/*
 *
 *    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 <stdint.h>

#include <Weave/Core/WeaveCore.h>
#include <Weave/Core/WeaveEncoding.h>
#include <Weave/Core/WeaveTLV.h>
#include <Weave/Core/WeaveCircularTLVBuffer.h>
#include <Weave/Support/CodeUtils.h>

namespace nl {
namespace Weave {
namespace TLV {

using namespace nl::Weave::Encoding;

/**
 * @brief
 *   WeaveCircularTLVBuffer constructor
 *
 * @param inBuffer[in]       A pointer to the backing store for the queue
 *
 * @param inBufferLength[in] Length of the backing store
 */
WeaveCircularTLVBuffer::WeaveCircularTLVBuffer(uint8_t *inBuffer, size_t inBufferLength)
{
    mQueue = inBuffer;
    mQueueSize = inBufferLength;
    mQueueLength = 0;
    mQueueHead = mQueue;

    mProcessEvictedElement = NULL;
    mAppData = NULL;

    // 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 WeaveCircularTLVBuffer
 *
 * 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 #WEAVE_NO_ERROR, the element
 * is not removed.  Similarly, if any other error occurs -- no
 * elements within the buffer, etc -- the underlying
 * #WeaveCircularTLVBuffer remains unchanged.
 *
 *  @retval #WEAVE_NO_ERROR On success.
 *
 *  @retval other          On any other error returned either by the callback
 *                         or by the TLVReader.
 *
 */
WEAVE_ERROR WeaveCircularTLVBuffer::EvictHead(void)
{
    CircularTLVReader reader;
    uint8_t *newHead;
    size_t newLen;
    WEAVE_ERROR err;

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

    // position the reader on the first element
    err = reader.Next();
    SuccessOrExit(err);

    // skip to the next element
    err = reader.Skip();
    SuccessOrExit(err);

    // 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 != NULL)
    {
        // Reinitialize the reader
        reader.Init(this);
        reader.ImplicitProfileId = mImplicitProfileId;

        err = mProcessEvictedElement(*this, mAppData, reader);
        SuccessOrExit(err);
    }

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

exit:
    return err;
}

/**
 * @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 ioWriter[inout]  TLVWriter calling this function
 *
 * @param outBufStart[out] The pointer to the new buffer
 *
 * @param outBufLen[out]   The available length for writing
 *
 * @retval #WEAVE_NO_ERROR On success.
 *
 * @retval other           If the function was unable to elide a complete
 *                         top-level TLV element.
 */

WEAVE_ERROR WeaveCircularTLVBuffer::GetNewBuffer(TLVWriter& ioWriter, uint8_t *& outBufStart, uint32_t& outBufLen)
{
    WEAVE_ERROR err = WEAVE_NO_ERROR;
    uint8_t * tail = QueueTail();

    if (mQueueLength >= mQueueSize) {
        // Queue is out of space, need to evict an element
        err = EvictHead();
        SuccessOrExit(err);
    }

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

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

exit:
    return err;
}


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

WEAVE_ERROR WeaveCircularTLVBuffer::FinalizeBuffer(TLVWriter& ioWriter, uint8_t *inBufStart, uint32_t inBufLen)
{
    WEAVE_ERROR err = WEAVE_NO_ERROR;
    uint8_t * tail = inBufStart + inBufLen;
    if (inBufLen)
    {
        if (tail <= mQueueHead)
        {
            mQueueLength = mQueueSize + (tail - mQueueHead);
        }
        else
        {
            mQueueLength = tail - mQueueHead;
        }
    }
    return err;
}


/**
 * @brief
 *   Get additional space for the TLVReader.
 *
 *  The storage provided by the WeaveCircularTLVBuffer 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 ioReader[in]        TLVReader calling this function.
 *
 * @param outBufStart[inout]  The reference to the data buffer.  On
 *                            return, it is set to a value within this
 *                            buffer.
 *
 * @param outBufLen[out]      On return, set to the number of continuous
 *                            bytes that could be read out of the buffer.
 *
 * @retval #WEAVE_NO_ERROR    Succeeds unconditionally.
 */
WEAVE_ERROR WeaveCircularTLVBuffer::GetNextBuffer(TLVReader& ioReader, const uint8_t *& outBufStart, uint32_t & outBufLen)
{
    WEAVE_ERROR err = WEAVE_NO_ERROR;
    uint8_t * tail = QueueTail();
    const uint8_t *readerStart = outBufStart;

    if (readerStart == NULL)
    {
        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 = (mQueue + mQueueSize) - outBufStart;
        if ((tail == outBufStart) && (readerStart != NULL))
            outBufLen = 0;
    }
    else
    {
        // the buffer length is the distance between head and tail;
        // tail is either strictly larger or the buffer is empty
        outBufLen = tail - outBufStart;
    }
    return err;
}


/**
 * @brief
 *   A trampoline to fetch more space for the TLVWriter.
 *
 * @param ioWriter[inout] TLVWriter calling this function
 *
 * @param inBufHandle[inout] A handle to the `CircularTLVWriter` object
 *
 * @param outBufStart[out] The pointer to the new buffer
 *
 * @param outBufLen[out]   The available length for writing
 *
 * @retval #WEAVE_NO_ERROR On success.
 *
 * @retval other           If the function was unable to elide a complete
 *                         top-level TLV element.
 */
WEAVE_ERROR WeaveCircularTLVBuffer::GetNewBufferFunct(TLVWriter& ioWriter, uintptr_t& inBufHandle, uint8_t *&outBufStart, uint32_t& outBufLen)
{
    WEAVE_ERROR err = WEAVE_NO_ERROR;
    WeaveCircularTLVBuffer *buf;

    VerifyOrExit(inBufHandle != 0, err = WEAVE_ERROR_INVALID_ARGUMENT);

    buf = static_cast<WeaveCircularTLVBuffer *>((void *) inBufHandle);

    err = buf->GetNewBuffer(ioWriter, outBufStart, outBufLen);

exit:
    return err;
}


/**
 * @brief
 *   A trampoline to `WeaveCircularTLVBuffer::FinalizeBuffer`
 *
 * @param ioWriter[inout] TLVWriter calling this function
 *
 * @param inBufHandle[inout] A handle to the `CircularTLVWriter` object
 *
 * @param inbufStart[in] pointer to the start of data (from `TLVWriter`
 *                       perspective)
 *
 * @param inBufLen[in]   length of data in the buffer pointed to by
 *                       `inbufStart`
 *
 * @retval #WEAVE_NO_ERROR Unconditionally.
 */
WEAVE_ERROR WeaveCircularTLVBuffer::FinalizeBufferFunct(TLVWriter& ioWriter, uintptr_t inBufHandle, uint8_t *inBufStart, uint32_t inBufLen)
{
    WEAVE_ERROR err = WEAVE_NO_ERROR;
    WeaveCircularTLVBuffer *buf;

    VerifyOrExit(inBufHandle != 0, err = WEAVE_ERROR_INVALID_ARGUMENT);

    buf = static_cast<WeaveCircularTLVBuffer *>((void *) inBufHandle);

    err = buf->FinalizeBuffer(ioWriter, inBufStart, inBufLen);

exit:
    return err;
}


/**
 * @brief
 *   A trampoline to `WeaveCircularTLVBuffer::FinalizeBuffer`
 *
 * @param ioWriter[inout] TLVReader calling this function
 *
 * @param inBufHandle[inout] A handle to the `CircularTLVWriter` object
 *
 * @param outBufStart[inout]  The reference to the data buffer.  On
 *                            return, it is set to a value within this
 *                            buffer.
 *
 * @param outBufLen[out]      On return, set to the number of continuous
 *                            bytes that could be read out of the buffer.
 *
 * @retval #WEAVE_NO_ERROR    Succeeds unconditionally.
 */
WEAVE_ERROR WeaveCircularTLVBuffer::GetNextBufferFunct(TLVReader& ioReader, uintptr_t &inBufHandle, const uint8_t *&outBufStart, uint32_t &outBufLen)
{
    WEAVE_ERROR err = WEAVE_NO_ERROR;
    WeaveCircularTLVBuffer *buf;

    VerifyOrExit(inBufHandle != 0, err = WEAVE_ERROR_INVALID_ARGUMENT);

    buf = static_cast<WeaveCircularTLVBuffer *>((void *) inBufHandle);

    err = buf->GetNextBuffer(ioReader, outBufStart, outBufLen);

exit:
    return err;
}

/**
 * @brief
 *   Initializes a TLVWriter object to write from a single WeaveCircularTLVBuffer
 *
 * Writing begins at the last byte of the buffer.  The number of bytes
 * to be written is not constrained by the underlying circular buffer:
 * writing new elements to the buffer will kick out previous elements
 * as long as an individual top-level TLV structure fits within the
 * buffer.  For example, writing a 7-byte top-level boolean TLV into a
 * 7 byte buffer will work indefinitely, but writing an 8-byte TLV
 * structure will result in an error.
 *
 * @param[in]    buf   A pointer to a fully initialized WeaveCircularTLVBuffer
 *
 */
void CircularTLVWriter::Init(WeaveCircularTLVBuffer *buf)
{
    mBufHandle = (uintptr_t) buf;
    mLenWritten = 0;
    mMaxLen = UINT32_MAX;
    mContainerType = kTLVType_NotSpecified;
    SetContainerOpen(false);
    SetCloseContainerReserved(false);

    ImplicitProfileId = kProfileIdNotSpecified;
    GetNewBuffer = WeaveCircularTLVBuffer::GetNewBufferFunct;
    FinalizeBuffer = WeaveCircularTLVBuffer::FinalizeBufferFunct;

    GetNewBuffer(*this, mBufHandle, mBufStart, mRemainingLen);
    mWritePoint = mBufStart;
}

/**
 * @brief
 *   Initializes a TLVReader object to read from a single WeaveCircularTLVBuffer
 *
 * Parsing begins at the start of the buffer (obtained by the
 * buffer->Start() position) and continues until the end of the buffer
 * Parsing may wraparound within the buffer (on any element).  At most
 * buffer->GetQueueSize() bytes are read out.
 *
 * @param[in]    buf   A pointer to a fully initialized WeaveCircularTLVBuffer
 *
 */
void CircularTLVReader::Init(WeaveCircularTLVBuffer *buf)
{
    uint32_t bufLen = 0;

    mBufHandle = (uintptr_t) buf;
    GetNextBuffer = WeaveCircularTLVBuffer::GetNextBufferFunct;
    mLenRead = 0;
    mReadPoint = NULL;
    GetNextBuffer(*this, mBufHandle, mReadPoint, bufLen);
    mBufEnd = mReadPoint + bufLen;
    mMaxLen = buf->DataLength();
    mControlByte = kTLVControlByte_NotSpecified;
    mElemTag = AnonymousTag;
    mElemLenOrVal = 0;
    mContainerType = kTLVType_NotSpecified;
    SetContainerOpen(false);
    ImplicitProfileId = kProfileIdNotSpecified;
    AppData = NULL;
}

} // namespace TLV
} // namespace Weave
} // namespace nl
