/*
 *
 *    Copyright (c) 2020-2021 Project CHIP Authors
 *    Copyright (c) 2016-2017 Nest Labs, Inc.
 *    All rights reserved.
 *
 *    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 implements the circular buffer for TLV
 *      elements. When used as the backing store for the TLVReader and
 *      TLVWriter, those classes will work with the wraparound of data
 *      within the buffer.  Additionally, the TLVWriter will be able
 *      to continually add top-level TLV elements by evicting
 *      pre-existing elements.
 */

#ifndef __STDC_LIMIT_MACROS
#define __STDC_LIMIT_MACROS
#endif
#include <lib/core/TLVCircularBuffer.h>

#include <lib/core/CHIPCore.h>
#include <lib/core/CHIPEncoding.h>
#include <lib/core/TLV.h>

#include <lib/support/CodeUtils.h>

#include <stdint.h>

namespace chip {
namespace TLV {

using namespace chip::Encoding;

/**
 * @brief
 *   TLVCircularBuffer constructor
 *
 * @param[in] inBuffer       A pointer to the backing store for the queue
 *
 * @param[in] inBufferLength Length, in bytes, of the backing store
 *
 * @param[in] inHead         Initial point for the head.  The @a inHead pointer is must fall within the backing store for the
 * circular buffer, i.e. within @a inBuffer and &(@a inBuffer[@a inBufferLength])
 */
TLVCircularBuffer::TLVCircularBuffer(uint8_t * inBuffer, uint32_t inBufferLength, uint8_t * inHead)
{
    mQueue       = inBuffer;
    mQueueSize   = inBufferLength;
    mQueueLength = 0;
    mQueueHead   = inHead;

    mProcessEvictedElement = nullptr;
    mAppData               = nullptr;

    // use common as opposed to unspecified, s.t. the reader that
    // skips over the elements does not complain about implicit
    // profile tags.
    mImplicitProfileId = kCommonProfileId;
}

/**
 * @brief
 *   TLVCircularBuffer constructor
 *
 * @param[in] inBuffer       A pointer to the backing store for the queue
 *
 * @param[in] inBufferLength Length, in bytes, of the backing store
 */
TLVCircularBuffer::TLVCircularBuffer(uint8_t * inBuffer, uint32_t inBufferLength)
{
    Init(inBuffer, inBufferLength);
}

/**
 * @brief
 *   TLVCircularBuffer Init function
 *
 * @param[in] inBuffer       A pointer to the backing store for the queue
 *
 * @param[in] inBufferLength Length, in bytes, of the backing store
 */
void TLVCircularBuffer::Init(uint8_t * inBuffer, uint32_t inBufferLength)
{
    mQueue       = inBuffer;
    mQueueSize   = inBufferLength;
    mQueueLength = 0;
    mQueueHead   = mQueue;

    mProcessEvictedElement = nullptr;
    mAppData               = nullptr;

    // use common as opposed to unspecified, s.t. the reader that
    // skips over the elements does not complain about implicit
    // profile tags.
    mImplicitProfileId = kCommonProfileId;
}

/**
 * @brief
 *   Evicts the oldest top-level TLV element in the TLVCircularBuffer
 *
 * This function removes the oldest top level TLV element in the
 * buffer.  The function will call the callback registered at
 * #mProcessEvictedElement to process the element prior to removal.
 * If the callback returns anything but #CHIP_NO_ERROR, the element
 * is not removed.  Similarly, if any other error occurs -- no
 * elements within the buffer, etc -- the underlying
 * #TLVCircularBuffer remains unchanged.
 *
 *  @retval #CHIP_NO_ERROR On success.
 *
 *  @retval other          On any other error returned either by the callback
 *                         or by the TLVReader.
 *
 */
CHIP_ERROR TLVCircularBuffer::EvictHead()
{
    CircularTLVReader reader;
    uint8_t * newHead;
    uint32_t newLen;

    // find the boundaries of an event to throw away
    reader.Init(*this);
    reader.ImplicitProfileId = mImplicitProfileId;

    // position the reader on the first element
    ReturnErrorOnFailure(reader.Next());

    // skip to the next element
    ReturnErrorOnFailure(reader.Skip());

    // record the state of the queue post-call
    newLen  = mQueueLength - (reader.GetLengthRead());
    newHead = const_cast<uint8_t *>(reader.GetReadPoint());

    // if a custom handler is installed, give it a chance to
    // process the element before we evict it from the buffer.
    if (mProcessEvictedElement != nullptr)
    {
        // Reinitialize the reader
        reader.Init(*this);
        reader.ImplicitProfileId = mImplicitProfileId;

        ReturnErrorOnFailure(mProcessEvictedElement(*this, mAppData, reader));
    }

    // update queue state
    mQueueLength = newLen;
    mQueueHead   = newHead;

    return CHIP_NO_ERROR;
}

/**
 * @brief
 *  Implements TLVBackingStore::OnInit(TLVWriter) for circular buffers.
 */
CHIP_ERROR TLVCircularBuffer::OnInit(TLVWriter & writer, uint8_t *& bufStart, uint32_t & bufLen)
{
    return GetNewBuffer(writer, bufStart, bufLen);
}

/**
 * @brief
 *   Get additional space for the TLVWriter.  In actuality, the
 *   function evicts an element from the circular buffer, and adjusts
 *   the head of this buffer queue
 *
 * @param[in,out] ioWriter  TLVWriter calling this function
 *
 * @param[out] outBufStart The pointer to the new buffer
 *
 * @param[out] outBufLen   The available length for writing
 *
 * @retval #CHIP_NO_ERROR On success.
 *
 * @retval other           If the function was unable to elide a complete
 *                         top-level TLV element.
 */

CHIP_ERROR TLVCircularBuffer::GetNewBuffer(TLVWriter & ioWriter, uint8_t *& outBufStart, uint32_t & outBufLen)
{
    if (mQueueLength >= mQueueSize)
    {
        // Queue is out of space, need to evict an element
        ReturnErrorOnFailure(EvictHead());
    }

    GetCurrentWritableBuffer(outBufStart, outBufLen);
    return CHIP_NO_ERROR;
}

void TLVCircularBuffer::GetCurrentWritableBuffer(uint8_t *& outBufStart, uint32_t & outBufLen) const
{
    uint8_t * tail = QueueTail();

    // set the output values, returned buffer must be contiguous
    outBufStart = tail;

    if (tail >= mQueueHead)
    {
        outBufLen = mQueueSize - static_cast<uint32_t>(tail - mQueue);
    }
    else
    {
        outBufLen = static_cast<uint32_t>(mQueueHead - tail);
    }
}

/**
 * @brief
 *   FinalizeBuffer adjust the `TLVCircularBuffer` state on
 *   completion of output from the TLVWriter.  This function affects
 *   the position of the queue tail.
 *
 * @param[in,out] ioWriter TLVWriter calling this function
 *
 * @param[in] inBufStart pointer to the start of data (from `TLVWriter`
 *                       perspective)
 *
 * @param[in] inBufLen   length of data in the buffer pointed to by
 *                       `inbufStart`
 *
 * @retval #CHIP_NO_ERROR Unconditionally.
 */

CHIP_ERROR TLVCircularBuffer::FinalizeBuffer(TLVWriter & ioWriter, uint8_t * inBufStart, uint32_t inBufLen)
{
    CHIP_ERROR err = CHIP_NO_ERROR;
    uint8_t * tail = inBufStart + inBufLen;
    if (inBufLen)
    {
        if (tail <= mQueueHead)
        {
            mQueueLength = mQueueSize - static_cast<uint32_t>(mQueueHead - tail);
        }
        else
        {
            mQueueLength = static_cast<uint32_t>(tail - mQueueHead);
        }
    }
    return err;
}

/**
 * @brief
 *  Implements TLVBackingStore::OnInit(TVLReader) for circular buffers.
 */
CHIP_ERROR TLVCircularBuffer::OnInit(TLVReader & reader, const uint8_t *& bufStart, uint32_t & bufLen)
{
    return GetNextBuffer(reader, bufStart, bufLen);
}

/**
 * @brief
 *   Get additional space for the TLVReader.
 *
 *  The storage provided by the TLVCircularBuffer may be
 *  wraparound within the buffer.  This function provides us with an
 *  ability to match the buffering of the circular buffer to the
 *  TLVReader constraints.  The reader will read at most `mQueueSize`
 *  bytes from the buffer.
 *
 * @param[in] ioReader         TLVReader calling this function.
 *
 * @param[in,out] outBufStart  The reference to the data buffer.  On
 *                             return, it is set to a value within this
 *                             buffer.
 *
 * @param[out] outBufLen       On return, set to the number of continuous
 *                             bytes that could be read out of the buffer.
 *
 * @retval #CHIP_NO_ERROR      Succeeds unconditionally.
 */
CHIP_ERROR TLVCircularBuffer::GetNextBuffer(TLVReader & ioReader, const uint8_t *& outBufStart, uint32_t & outBufLen)
{
    CHIP_ERROR err              = CHIP_NO_ERROR;
    uint8_t * tail              = QueueTail();
    const uint8_t * readerStart = outBufStart;

    if (readerStart == nullptr)
    {
        outBufStart = mQueueHead;

        if (outBufStart == mQueue + mQueueSize)
        {
            outBufStart = mQueue;
        }
    }
    else if (readerStart >= (mQueue + mQueueSize))
    {
        outBufStart = mQueue;
    }
    else
    {
        outBufLen = 0;
        return err;
    }

    if ((mQueueLength != 0) && (tail <= outBufStart))
    {
        // the buffer is non-empty and data wraps around the end
        // point.  The returned buffer conceptually spans from
        // outBufStart until the end of the underlying storage buffer
        // (i.e. mQueue+mQueueSize).  This case tail == outBufStart
        // indicates that the buffer is completely full
        outBufLen = mQueueSize - static_cast<uint32_t>(outBufStart - mQueue);
        if ((tail == outBufStart) && (readerStart != nullptr))
            outBufLen = 0;
    }
    else
    {
        // the buffer length is the distance between head and tail;
        // tail is either strictly larger or the buffer is empty
        outBufLen = static_cast<uint32_t>(tail - outBufStart);
    }
    return err;
}

} // namespace TLV
} // namespace chip
