/**
 *
 *    Copyright (c) 2020 Project CHIP Authors
 *
 *    Licensed under the Apache License, Version 2.0 (the "License");
 *    you may not use this file except in compliance with the License.
 *    You may obtain a copy of the License at
 *
 *        http://www.apache.org/licenses/LICENSE-2.0
 *
 *    Unless required by applicable law or agreed to in writing, software
 *    distributed under the License is distributed on an "AS IS" BASIS,
 *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *    See the License for the specific language governing permissions and
 *    limitations under the License.
 */

/**
 * @file Basic implementation of a binding table.
 */

#include <app/util/binding-table.h>

namespace chip {

BindingTable BindingTable::sInstance;

BindingTable::BindingTable()
{
    memset(mNextIndex, kNextNullIndex, sizeof(mNextIndex));
}

CHIP_ERROR BindingTable::Add(const EmberBindingTableEntry & entry)
{
    if (entry.type == EMBER_UNUSED_BINDING)
    {
        return CHIP_ERROR_INVALID_ARGUMENT;
    }
    uint8_t newIndex = GetNextAvaiableIndex();
    if (newIndex >= EMBER_BINDING_TABLE_SIZE)
    {
        return CHIP_ERROR_NO_MEMORY;
    }
    mBindingTable[newIndex] = entry;
    CHIP_ERROR error        = SaveEntryToStorage(newIndex, kNextNullIndex);
    if (error == CHIP_NO_ERROR)
    {
        if (mTail == kNextNullIndex)
        {
            error = SaveListInfo(newIndex);
        }
        else
        {
            error = SaveEntryToStorage(mTail, newIndex);
        }
        if (error != CHIP_NO_ERROR)
        {
            mStorage->SyncDeleteKeyValue(DefaultStorageKeyAllocator::BindingTableEntry(newIndex).KeyName());
        }
    }
    if (error != CHIP_NO_ERROR)
    {
        // Roll back
        mBindingTable[newIndex].type = EMBER_UNUSED_BINDING;
        return error;
    }

    if (mTail == kNextNullIndex)
    {
        mTail = newIndex;
        mHead = newIndex;
    }
    else
    {
        mNextIndex[mTail]    = newIndex;
        mNextIndex[newIndex] = kNextNullIndex;
        mTail                = newIndex;
    }

    mSize++;
    return CHIP_NO_ERROR;
}

const EmberBindingTableEntry & BindingTable::GetAt(uint8_t index)
{
    return mBindingTable[index];
}

CHIP_ERROR BindingTable::SaveEntryToStorage(uint8_t index, uint8_t nextIndex)
{
    EmberBindingTableEntry & entry    = mBindingTable[index];
    uint8_t buffer[kEntryStorageSize] = { 0 };
    TLV::TLVWriter writer;
    writer.Init(buffer);
    TLV::TLVType container;
    ReturnErrorOnFailure(writer.StartContainer(TLV::AnonymousTag(), TLV::TLVType::kTLVType_Structure, container));
    ReturnErrorOnFailure(writer.Put(TLV::ContextTag(kTagFabricIndex), entry.fabricIndex));
    ReturnErrorOnFailure(writer.Put(TLV::ContextTag(kTagLocalEndpoint), entry.local));
    if (entry.clusterId.HasValue())
    {
        ReturnErrorOnFailure(writer.Put(TLV::ContextTag(kTagCluster), entry.clusterId.Value()));
    }
    if (entry.type == EMBER_UNICAST_BINDING)
    {
        ReturnErrorOnFailure(writer.Put(TLV::ContextTag(kTagRemoteEndpoint), entry.remote));
        ReturnErrorOnFailure(writer.Put(TLV::ContextTag(kTagNodeId), entry.nodeId));
    }
    else
    {
        ReturnErrorOnFailure(writer.Put(TLV::ContextTag(kTagGroupId), entry.groupId));
    }
    ReturnErrorOnFailure(writer.Put(TLV::ContextTag(kTagNextEntry), nextIndex));
    ReturnErrorOnFailure(writer.EndContainer(container));
    ReturnErrorOnFailure(writer.Finalize());
    return mStorage->SyncSetKeyValue(DefaultStorageKeyAllocator::BindingTableEntry(index).KeyName(), buffer,
                                     static_cast<uint16_t>(writer.GetLengthWritten()));
}

CHIP_ERROR BindingTable::SaveListInfo(uint8_t head)
{
    uint8_t buffer[kListInfoStorageSize] = { 0 };
    TLV::TLVWriter writer;
    writer.Init(buffer);
    TLV::TLVType container;
    ReturnErrorOnFailure(writer.StartContainer(TLV::AnonymousTag(), TLV::TLVType::kTLVType_Structure, container));
    ReturnErrorOnFailure(writer.Put(TLV::ContextTag(kTagStorageVersion), kStorageVersion));
    ReturnErrorOnFailure(writer.Put(TLV::ContextTag(kTagHead), head));
    ReturnErrorOnFailure(writer.EndContainer(container));
    ReturnErrorOnFailure(writer.Finalize());
    return mStorage->SyncSetKeyValue(DefaultStorageKeyAllocator::BindingTable().KeyName(), buffer,
                                     static_cast<uint16_t>(writer.GetLengthWritten()));
}

CHIP_ERROR BindingTable::LoadFromStorage()
{
    VerifyOrReturnError(mStorage != nullptr, CHIP_ERROR_INCORRECT_STATE);
    uint8_t buffer[kListInfoStorageSize] = { 0 };
    uint16_t size                        = sizeof(buffer);
    CHIP_ERROR error;

    ReturnErrorOnFailure(mStorage->SyncGetKeyValue(DefaultStorageKeyAllocator::BindingTable().KeyName(), buffer, size));
    TLV::TLVReader reader;
    reader.Init(buffer, size);

    ReturnErrorOnFailure(reader.Next(TLV::kTLVType_Structure, TLV::AnonymousTag()));

    TLV::TLVType container;
    ReturnErrorOnFailure(reader.EnterContainer(container));

    ReturnErrorOnFailure(reader.Next(TLV::ContextTag(kTagStorageVersion)));
    uint32_t version;
    ReturnErrorOnFailure(reader.Get(version));
    VerifyOrReturnError(version == kStorageVersion, CHIP_ERROR_VERSION_MISMATCH);
    ReturnErrorOnFailure(reader.Next(TLV::ContextTag(kTagHead)));
    uint8_t index;
    ReturnErrorOnFailure(reader.Get(index));
    mHead = index;
    while (index != kNextNullIndex)
    {
        uint8_t nextIndex;
        error = LoadEntryFromStorage(index, nextIndex);
        if (error != CHIP_NO_ERROR)
        {
            mHead = kNextNullIndex;
            mTail = kNextNullIndex;
            return error;
        }
        mTail = index;
        index = nextIndex;
        mSize++;
    }
    error = reader.ExitContainer(container);
    if (error != CHIP_NO_ERROR)
    {
        mHead = kNextNullIndex;
        mTail = kNextNullIndex;
    }
    return error;
}

CHIP_ERROR BindingTable::LoadEntryFromStorage(uint8_t index, uint8_t & nextIndex)
{
    uint8_t buffer[kEntryStorageSize] = { 0 };
    uint16_t size                     = sizeof(buffer);
    EmberBindingTableEntry entry;

    ReturnErrorOnFailure(mStorage->SyncGetKeyValue(DefaultStorageKeyAllocator::BindingTableEntry(index).KeyName(), buffer, size));
    TLV::TLVReader reader;
    reader.Init(buffer, size);

    ReturnErrorOnFailure(reader.Next(TLV::kTLVType_Structure, TLV::AnonymousTag()));

    TLV::TLVType container;
    ReturnErrorOnFailure(reader.EnterContainer(container));
    ReturnErrorOnFailure(reader.Next(TLV::ContextTag(kTagFabricIndex)));
    ReturnErrorOnFailure(reader.Get(entry.fabricIndex));
    ReturnErrorOnFailure(reader.Next(TLV::ContextTag(kTagLocalEndpoint)));
    ReturnErrorOnFailure(reader.Get(entry.local));
    ReturnErrorOnFailure(reader.Next());
    if (reader.GetTag() == TLV::ContextTag(kTagCluster))
    {
        ClusterId clusterId;
        ReturnErrorOnFailure(reader.Get(clusterId));
        entry.clusterId.SetValue(clusterId);
        ReturnErrorOnFailure(reader.Next());
    }
    else
    {
        entry.clusterId = NullOptional;
    }
    if (reader.GetTag() == TLV::ContextTag(kTagRemoteEndpoint))
    {
        entry.type = EMBER_UNICAST_BINDING;
        ReturnErrorOnFailure(reader.Get(entry.remote));
        ReturnErrorOnFailure(reader.Next(TLV::ContextTag(kTagNodeId)));
        ReturnErrorOnFailure(reader.Get(entry.nodeId));
    }
    else
    {
        entry.type = EMBER_MULTICAST_BINDING;
        ReturnErrorCodeIf(reader.GetTag() != TLV::ContextTag(kTagGroupId), CHIP_ERROR_INVALID_TLV_TAG);
        ReturnErrorOnFailure(reader.Get(entry.groupId));
    }
    ReturnErrorOnFailure(reader.Next(TLV::ContextTag(kTagNextEntry)));
    ReturnErrorOnFailure(reader.Get(nextIndex));
    ReturnErrorOnFailure(reader.ExitContainer(container));
    mBindingTable[index] = entry;
    mNextIndex[index]    = nextIndex;
    return CHIP_NO_ERROR;
}

CHIP_ERROR BindingTable::RemoveAt(Iterator & iter)
{
    CHIP_ERROR error;
    if (iter.mTable != this || iter.mIndex == kNextNullIndex)
    {
        return CHIP_ERROR_INVALID_ARGUMENT;
    }
    if (iter.mIndex == mTail)
    {
        mTail = iter.mPrevIndex;
    }
    uint8_t next = mNextIndex[iter.mIndex];
    if (iter.mIndex != mHead)
    {
        error = SaveEntryToStorage(iter.mPrevIndex, next);
        if (error == CHIP_NO_ERROR)
        {
            mNextIndex[iter.mPrevIndex] = next;
        }
    }
    else
    {
        error = SaveListInfo(next);
        if (error == CHIP_NO_ERROR)
        {
            mHead = next;
        }
    }
    if (error == CHIP_NO_ERROR)
    {
        // The remove is considered "submitted" once the change on prev node takes effect
        if (mStorage->SyncDeleteKeyValue(DefaultStorageKeyAllocator::BindingTableEntry(iter.mIndex).KeyName()) != CHIP_NO_ERROR)
        {
            ChipLogError(AppServer, "Failed to remove binding table entry %u from storage", iter.mIndex);
        }
        mBindingTable[iter.mIndex].type = EMBER_UNUSED_BINDING;
        mNextIndex[iter.mIndex]         = kNextNullIndex;
        mSize--;
    }
    iter.mIndex = next;
    return error;
}

BindingTable::Iterator BindingTable::begin()
{
    Iterator iter;
    iter.mTable     = this;
    iter.mPrevIndex = kNextNullIndex;
    iter.mIndex     = mHead;
    return iter;
}

BindingTable::Iterator BindingTable::end()
{
    Iterator iter;
    iter.mTable = this;
    iter.mIndex = kNextNullIndex;
    return iter;
}

uint8_t BindingTable::GetNextAvaiableIndex()
{
    for (uint8_t i = 0; i < EMBER_BINDING_TABLE_SIZE; i++)
    {
        if (mBindingTable[i].type == EMBER_UNUSED_BINDING)
        {
            return i;
        }
    }
    return EMBER_BINDING_TABLE_SIZE;
}

BindingTable::Iterator BindingTable::Iterator::operator++()
{
    if (mIndex != kNextNullIndex)
    {
        mPrevIndex = mIndex;
        mIndex     = mTable->mNextIndex[mIndex];
    }
    return *this;
}

} // namespace chip
