/*
 *
 *    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 defines 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.
 */

#pragma once

#include <lib/core/CHIPError.h>
#include <lib/core/CHIPTLV.h>
#include <lib/core/CHIPTLVTags.h>
#include <lib/core/CHIPTLVTypes.h>

#include <lib/support/DLLUtil.h>

#include <stdlib.h>

namespace chip {
namespace TLV {

/**
 * @class CHIPCircularTLVBuffer
 *
 * @brief
 *    CHIPCircularTLVBuffer provides circular storage for the
 *    chip::TLV::TLVWriter and chip::TLVTLVReader.  chip::TLV::TLVWriter is able to write an
 *    unbounded number of TLV entries to the CHIPCircularTLVBuffer
 *    as long as each individual TLV entry fits entirely within the
 *    provided storage.  The chip::TLV::TLVReader will read at most the size of
 *    the buffer, but will accommodate the wraparound within the
 *    buffer.
 *
 */
class DLL_EXPORT CHIPCircularTLVBuffer : public chip::TLV::TLVBackingStore
{
public:
    CHIPCircularTLVBuffer(uint8_t * inBuffer, uint32_t inBufferLength);
    CHIPCircularTLVBuffer(uint8_t * inBuffer, uint32_t inBufferLength, uint8_t * inHead);

    void Init(uint8_t * inBuffer, uint32_t inBufferLength);
    inline uint8_t * QueueHead() const { return mQueueHead; }
    inline uint8_t * QueueTail() const { return mQueue + ((static_cast<size_t>(mQueueHead - mQueue) + mQueueLength) % mQueueSize); }
    inline uint32_t DataLength() const { return mQueueLength; }
    inline uint32_t AvailableDataLength() const { return mQueueSize - mQueueLength; }
    inline uint32_t GetTotalDataLength() const { return mQueueSize; }
    inline uint8_t * GetQueue() const { return mQueue; }

    CHIP_ERROR EvictHead();

    // chip::TLV::TLVBackingStore overrides:
    CHIP_ERROR OnInit(TLVReader & reader, const uint8_t *& bufStart, uint32_t & bufLen) override;
    CHIP_ERROR GetNextBuffer(TLVReader & ioReader, const uint8_t *& outBufStart, uint32_t & outBufLen) override;
    CHIP_ERROR OnInit(TLVWriter & writer, uint8_t *& bufStart, uint32_t & bufLen) override;
    CHIP_ERROR GetNewBuffer(TLVWriter & ioWriter, uint8_t *& outBufStart, uint32_t & outBufLen) override;
    CHIP_ERROR FinalizeBuffer(TLVWriter & ioWriter, uint8_t * inBufStart, uint32_t inBufLen) override;

    /**
     *  @typedef CHIP_ERROR (*ProcessEvictedElementFunct)(CHIPCircularTLVBuffer &inBuffer, void * inAppData, TLVReader &inReader)
     *
     *  A function that is called to process a TLV element prior to it
     *  being evicted from the chip::TLV::CHIPCircularTLVBuffer
     *
     *  Functions of this type are used to process a TLV element about
     *  to be evicted from the buffer.  The function will be given a
     *  chip::TLV::TLVReader positioned on the element about to be deleted, as
     *  well as void * context where the user may have provided
     *  additional environment for the callback.  If the function
     *  processed the element successfully, it must return
     *  #CHIP_NO_ERROR ; this signifies to the CHIPCircularTLVBuffer
     *  that the element may be safely evicted.  Any other return
     *  value is treated as an error and will prevent the
     *  #CHIPCircularTLVBuffer from evicting the element under
     *  consideration.
     *
     *  Note: This callback may be used to force
     *  CHIPCircularTLVBuffer to not evict the element.  This may be
     *  useful in a number of circumstances, when it is desired to
     *  have an underlying circular buffer, but not to override any
     *  elements within it.
     *
     *  @param[in] inBuffer  A reference to the buffer from which the
     *                       eviction takes place
     *
     *  @param[in] inAppData A pointer to the user-provided structure
     *                       containing additional context for this
     *                       callback
     *
     *  @param[in] inReader  A TLVReader positioned at the element to
     *                       be evicted.
     *
     *  @retval #CHIP_NO_ERROR On success. Element will be evicted.
     *
     *  @retval other        An error has occurred during the event
     *                       processing.  The element stays in the
     *                       buffer.  The write function that
     *                       triggered this element eviction will
     *                       fail.
     */
    typedef CHIP_ERROR (*ProcessEvictedElementFunct)(CHIPCircularTLVBuffer & inBuffer, void * inAppData, TLVReader & inReader);

    uint32_t mImplicitProfileId;
    void * mAppData; /**< An optional, user supplied context to be used with the callback processing the evicted element. */
    ProcessEvictedElementFunct
        mProcessEvictedElement; /**< An optional, user-supplied callback that processes the element prior to evicting it from the
                                   circular buffer.  See the ProcessEvictedElementFunct type definition on additional information on
                                   implementing the mProcessEvictedElement function. */

private:
    uint8_t * mQueue;
    uint32_t mQueueSize;
    uint8_t * mQueueHead;
    uint32_t mQueueLength;
};

class DLL_EXPORT CircularTLVReader : public TLVReader
{
public:
    /**
     * @brief
     *   Initializes a TLVReader object to read from a single CHIPCircularTLVBuffer
     *
     * 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 CHIPCircularTLVBuffer
     *
     */
    void Init(CHIPCircularTLVBuffer & buf) { TLVReader::Init(buf, buf.DataLength()); }
};

class DLL_EXPORT CircularTLVWriter : public TLVWriter
{
public:
    /**
     * @brief
     *   Initializes a TLVWriter object to write from a single CHIPCircularTLVBuffer
     *
     * 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 CHIPCircularTLVBuffer
     *
     */
    void Init(CHIPCircularTLVBuffer & buf) { TLVWriter::Init(buf, UINT32_MAX); }
};

} // namespace TLV
} // namespace chip
