/*
 *
 *    Copyright (c) 2021 Project CHIP Authors
 *    Copyright (c) 2013-2017 Nest Labs, Inc.
 *
 *    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
 *      This file contains an implementation of TLVBackingStore using PacketBuffers.
 */

#include <system/TLVPacketBufferBackingStore.h>

#include <lib/support/SafeInt.h>

namespace chip {
namespace System {

CHIP_ERROR TLVPacketBufferBackingStore::OnInit(chip::TLV::TLVReader & reader, const uint8_t *& bufStart, uint32_t & bufLen)
{
    bufStart = mHeadBuffer->Start();
    VerifyOrReturnError(CanCastTo<uint32_t>(mHeadBuffer->DataLength()), CHIP_ERROR_INVALID_ARGUMENT);
    bufLen = static_cast<uint32_t>(mHeadBuffer->DataLength());
    return CHIP_NO_ERROR;
}

CHIP_ERROR TLVPacketBufferBackingStore::GetNextBuffer(chip::TLV::TLVReader & reader, const uint8_t *& bufStart, uint32_t & bufLen)
{
    if (mUseChainedBuffers)
    {
        mCurrentBuffer.Advance();
    }
    else
    {
        mCurrentBuffer = nullptr;
    }

    if (mCurrentBuffer.IsNull())
    {
        bufStart = nullptr;
        bufLen   = 0;
    }
    else
    {
        bufStart = mCurrentBuffer->Start();
        VerifyOrReturnError(CanCastTo<uint32_t>(mCurrentBuffer->DataLength()), CHIP_ERROR_INVALID_ARGUMENT);
        bufLen = static_cast<uint32_t>(mCurrentBuffer->DataLength());
    }

    return CHIP_NO_ERROR;
}

CHIP_ERROR TLVPacketBufferBackingStore::OnInit(chip::TLV::TLVWriter & writer, uint8_t *& bufStart, uint32_t & bufLen)
{
    bufStart = mHeadBuffer->Start() + mHeadBuffer->DataLength();
    VerifyOrReturnError(CanCastTo<uint32_t>(mHeadBuffer->AvailableDataLength()), CHIP_ERROR_INVALID_ARGUMENT);
    bufLen = static_cast<uint32_t>(mHeadBuffer->AvailableDataLength());
    return CHIP_NO_ERROR;
}

CHIP_ERROR TLVPacketBufferBackingStore::FinalizeBuffer(chip::TLV::TLVWriter & writer, uint8_t * bufStart, uint32_t dataLen)
{
    uint8_t * endPtr = bufStart + dataLen;

    intptr_t length = endPtr - mCurrentBuffer->Start();
    if (!CanCastTo<uint32_t>(length))
    {
        return CHIP_ERROR_INVALID_ARGUMENT;
    }
    mCurrentBuffer->SetDataLength(static_cast<uint32_t>(length), mHeadBuffer);

    return CHIP_NO_ERROR;
}

CHIP_ERROR TLVPacketBufferBackingStore::GetNewBuffer(chip::TLV::TLVWriter & writer, uint8_t *& bufStart, uint32_t & bufLen)
{
    if (!mUseChainedBuffers)
    {
        return CHIP_ERROR_NO_MEMORY;
    }

    mCurrentBuffer.Advance();
    if (mCurrentBuffer.IsNull())
    {
        mCurrentBuffer = PacketBufferHandle::New(System::PacketBuffer::kMaxSizeWithoutReserve, 0);
        if (mCurrentBuffer.IsNull())
        {
            return CHIP_ERROR_NO_MEMORY;
        }
        mHeadBuffer->AddToEnd(mCurrentBuffer.Retain());
    }

    if (mCurrentBuffer.IsNull())
    {
        bufStart = nullptr;
        bufLen   = 0;
    }
    else
    {
        bufStart = mCurrentBuffer->Start();
        VerifyOrReturnError(CanCastTo<uint32_t>(mCurrentBuffer->MaxDataLength()), CHIP_ERROR_INVALID_ARGUMENT);
        bufLen = static_cast<uint32_t>(mCurrentBuffer->MaxDataLength());
    }

    return CHIP_NO_ERROR;
}

} // namespace System
} // namespace chip
