/*
 *
 *    Copyright (c) 2015-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 an updating encoder for the Weave TLV
 *      (Tag-Length-Value) encoding format.
 *
 */

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

namespace nl {
namespace Weave {
namespace TLV {

using namespace nl::Weave::Encoding;

/**
 * Initialize a TLVUpdater object to edit a single input buffer.
 *
 * On calling this method, the TLV data in the buffer is moved to the end of the
 * buffer and a private TLVReader object is initialized on this relocated
 * buffer. A private TLVWriter object is also initialized on the free space that
 * is now available at the beginning. Applications can use the TLVUpdater object
 * to parse the TLV data and modify/delete existing elements or add new elements
 * to the encoding.
 *
 * @param[in]   data    A pointer to a buffer containing the TLV data to be edited.
 * @param[in]   dataLen The length of the TLV data in the buffer.
 * @param[in]   maxLen  The total length of the buffer.
 *
 * @retval #WEAVE_NO_ERROR                  If the method succeeded.
 * @retval #WEAVE_ERROR_INVALID_ARGUMENT    If the buffer address is invalid.
 * @retval #WEAVE_ERROR_BUFFER_TOO_SMALL    If the buffer is too small.
 *
 */
WEAVE_ERROR TLVUpdater::Init(uint8_t *buf, uint32_t dataLen, uint32_t maxLen)
{
    WEAVE_ERROR err = WEAVE_NO_ERROR;
    uint32_t freeLen;

    VerifyOrExit(buf != NULL, err = WEAVE_ERROR_INVALID_ARGUMENT);

    VerifyOrExit(maxLen >= dataLen, err = WEAVE_ERROR_BUFFER_TOO_SMALL);

    // memmove the buffer data to end of the buffer
    freeLen = maxLen - dataLen;
    memmove(buf + freeLen, buf, dataLen);

    // Init reader
    mUpdaterReader.Init(buf + freeLen, dataLen);

    // Init writer
    mUpdaterWriter.Init(buf, freeLen);
    mUpdaterWriter.SetCloseContainerReserved(false);
    mElementStartAddr = buf + freeLen;

exit:
    return err;
}

/**
 * Initialize a TLVUpdater object using a TLVReader.
 *
 * On calling this method, TLV data in the buffer pointed to by the TLVReader
 * is moved from the current read point to the end of the buffer. A new
 * private TLVReader object is initialized to read from this new location, while
 * a new private TLVWriter object is initialized to write to the freed up buffer
 * space.
 *
 * Note that if the TLVReader is already positioned "on" an element, it is first
 * backed-off to the start of that element. Also note that this backing off
 * works well with container elements, i.e., if the TLVReader was already  used
 * to call EnterContainer(), then there is nothing to back-off. But if the
 * TLVReader was positioned on the container element and EnterContainer() was
 * not yet called, then the TLVReader object is backed-off to the start of the
 * container head.
 *
 * The input TLVReader object will be destroyed before returning and the
 * application must not make use of the same on return.
 *
 * @param[in,out]   aReader     Reference to a TLVReader object that will be
 *                              destroyed before returning.
 * @param[in]       freeLen     The length of free space (in bytes) available
 *                              in the pre-encoded data buffer.
 *
 * @retval #WEAVE_NO_ERROR                  If the method succeeded.
 * @retval #WEAVE_ERROR_INVALID_ARGUMENT    If the buffer address is invalid.
 * @retval #WEAVE_ERROR_NOT_IMPLEMENTED     If reader was initialized on a chain
 *                                          of buffers.
 */
WEAVE_ERROR TLVUpdater::Init(TLVReader& aReader, uint32_t freeLen)
{
    WEAVE_ERROR err = WEAVE_NO_ERROR;
    uint8_t *buf = const_cast<uint8_t *>(aReader.GetReadPoint());
    uint32_t remainingDataLen = aReader.GetRemainingLength();
    uint32_t readDataLen = aReader.GetLengthRead();

    // TLVUpdater does not support chain of buffers yet
    VerifyOrExit(aReader.mBufHandle == 0, err = WEAVE_ERROR_NOT_IMPLEMENTED);

    // TLVReader should point to a non-NULL buffer
    VerifyOrExit(buf != NULL, err = WEAVE_ERROR_INVALID_ARGUMENT);

    // If reader is already on an element, reset it to start of element
    if (aReader.ElementType() != kTLVElementType_NotSpecified)
    {
        uint8_t elemHeadLen;

        err = aReader.GetElementHeadLength(elemHeadLen);
        SuccessOrExit(err);

        buf -= elemHeadLen;
        remainingDataLen += elemHeadLen;
        readDataLen -= elemHeadLen;
    }

    // memmove the buffer data to end of the buffer
    memmove(buf + freeLen, buf, remainingDataLen);

    // Initialize the internal reader object
    mUpdaterReader.mBufHandle = 0;
    mUpdaterReader.mReadPoint = buf + freeLen;
    mUpdaterReader.mBufEnd = buf + freeLen + remainingDataLen;
    mUpdaterReader.mLenRead = readDataLen;
    mUpdaterReader.mMaxLen = aReader.mMaxLen;
    mUpdaterReader.mControlByte = kTLVControlByte_NotSpecified;
    mUpdaterReader.mElemTag = AnonymousTag;
    mUpdaterReader.mElemLenOrVal = 0;
    mUpdaterReader.mContainerType = aReader.mContainerType;
    mUpdaterReader.SetContainerOpen(false);

    mUpdaterReader.ImplicitProfileId = aReader.ImplicitProfileId;
    mUpdaterReader.AppData = aReader.AppData;
    mUpdaterReader.GetNextBuffer = NULL;

    // Initialize the internal writer object
    mUpdaterWriter.mBufHandle = 0;
    mUpdaterWriter.mBufStart = buf - readDataLen;
    mUpdaterWriter.mWritePoint = buf;
    mUpdaterWriter.mRemainingLen = freeLen;
    mUpdaterWriter.mLenWritten = readDataLen;
    mUpdaterWriter.mMaxLen = readDataLen + freeLen;
    mUpdaterWriter.mContainerType = aReader.mContainerType;
    mUpdaterWriter.SetContainerOpen(false);
    mUpdaterWriter.SetCloseContainerReserved(false);

    mUpdaterWriter.ImplicitProfileId = aReader.ImplicitProfileId;
    mUpdaterWriter.GetNewBuffer = NULL;
    mUpdaterWriter.FinalizeBuffer = NULL;

    // Cache element start address for internal use
    mElementStartAddr = buf + freeLen;

    // Clear the input reader object before returning. The user can no longer
    // use the original TLVReader object anymore.
    aReader.Init((const uint8_t *) NULL, 0);

exit:
    return err;
}

/**
 * Set the Implicit Profile ID for the TLVUpdater object.
 *
 * This method sets the implicit profile ID for the TLVUpdater object. When the
 * updater is asked to encode a new element, if the profile ID of the tag
 * associated with the new element matches the value of the @p profileId, the
 * updater will encode the tag in implicit form, thereby omitting the profile ID
 * in the process.
 *
 * @param[in]   profileId   The profile id of tags that should be encoded in
 *                          implicit form.
 */
void TLVUpdater::SetImplicitProfileId(uint32_t profileId)
{
    mUpdaterReader.ImplicitProfileId = profileId;
    mUpdaterWriter.ImplicitProfileId = profileId;
}

/**
 * Skip the current element and advance the TLVUpdater object to the next
 * element in the input TLV.
 *
 * The Next() method skips the current element in the input TLV and advances the
 * TLVUpdater's reader to the next element that resides in the same containment
 * context. In particular, if the reader is positioned at the outer most level
 * of a TLV encoding, calling Next() will advance it to the next, top most
 * element. If the reader is positioned within a TLV container element (a
 * structure, array or path), calling Next() will advance it to the next member
 * element of the container.
 *
 * Since Next() constrains reader motion to the current containment context,
 * calling Next() when the reader is positioned on a container element will
 * advance @em over the container, skipping its member elements (and the members
 * of any nested containers) until it reaches the first element after the
 * container.
 *
 * When there are no further elements within a particular containment context
 * the Next() method will return a #WEAVE_END_OF_TLV error and the position of
 * the reader will remain unchanged.
 *
 * @note The Next() method implicitly skips the current element. Hence, the
 * TLVUpdater's private writer state variables will be adjusted to account for
 * the new freed space (made available by skipping). This means that the
 * application is expected to call Next() on the TLVUpdater object after a Get()
 * whose value the application does @em not write back (which from the
 * TLVUpdater's view is equivalent to skipping that element).
 *
 * @note Applications are also expected to call Next() when they are at the end
 * of a container, and want to add new elements there. This is particularly
 * important in situations where there is a fixed schema. Applications that have
 * fixed schemas and know where the container end is cannot just add new
 * elements at the end, because the TLVUpdater writer's state will not reflect
 * the correct free space available for the Put() operation. Hence, applications
 * must call Next() (and possibly also test for WEAVE_END_OF_TLV) before adding
 * elements at the end of a container.
 *
 * @retval #WEAVE_NO_ERROR              If the TLVUpdater reader was
 *                                      successfully positioned on a new
 *                                      element.
 * @retval other                        Returns the Weave or platform error
 *                                      codes returned by the TLVReader::Skip()
 *                                      and TLVReader::Next() method.
 *
 */
WEAVE_ERROR TLVUpdater::Next()
{
    WEAVE_ERROR err = WEAVE_NO_ERROR;

    // Skip current element if the reader is already positioned on an element
    err = mUpdaterReader.Skip();
    SuccessOrExit(err);

    AdjustInternalWriterFreeSpace();

    // Move the reader to next element
    err = mUpdaterReader.Next();
    SuccessOrExit(err);

exit:
    return err;
}

/**
 * Copies the current element from input TLV to output TLV.
 *
 * The Move() method copies the current element on which the TLVUpdater's reader
 * is positioned on, to the TLVUpdater's writer. The application should call
 * Next() and position the TLVUpdater's reader on an element before calling this
 * method. Just like the TLVReader::Next() method, if the reader is positioned
 * on a container element at the time of the call, all the members of the
 * container will be copied. If the reader is not positioned on any element,
 * nothing changes on calling this method.
 *
 * @retval #WEAVE_NO_ERROR              If the TLVUpdater reader was
 *                                      successfully positioned on a new
 *                                      element.
 * @retval #WEAVE_END_OF_TLV            If the TLVUpdater's reader is pointing
 *                                      to end of container.
 * @retval #WEAVE_ERROR_INVALID_TLV_ELEMENT
 *                                      If the TLVIpdater's reader is not
 *                                      positioned on a valid TLV element.
 * @retval other                        Returns other error codes returned by
 *                                      TLVReader::Skip() method.
 *
 */
WEAVE_ERROR TLVUpdater::Move()
{
    WEAVE_ERROR err = WEAVE_NO_ERROR;
    const uint8_t *elementEnd;
    uint32_t copyLen;

    VerifyOrExit((mUpdaterReader.mControlByte & kTLVTypeMask) != kTLVElementType_EndOfContainer,
                 err = WEAVE_END_OF_TLV);

    VerifyOrExit(mUpdaterReader.GetType() != kTLVType_NotSpecified,
                 err = WEAVE_ERROR_INVALID_TLV_ELEMENT);

    // Skip to the end of the element
    err = mUpdaterReader.Skip();
    SuccessOrExit(err);

    elementEnd = mUpdaterReader.mReadPoint;

    copyLen = elementEnd - mElementStartAddr;

    // Move the element to output TLV
    memmove(mUpdaterWriter.mWritePoint, mElementStartAddr, copyLen);

    // Adjust the updater state
    mElementStartAddr += copyLen;
    mUpdaterWriter.mWritePoint += copyLen;
    mUpdaterWriter.mLenWritten += copyLen;
    mUpdaterWriter.mMaxLen += copyLen;

exit:
    return err;
}

/**
 * Move everything from the TLVUpdater's current read point till end of input
 * TLV buffer over to output.
 *
 * This method supports moving everything from the TLVUpdater's current read
 * point till the end of the reader buffer over to the TLVUpdater's writer.
 *
 * @note This method can be called with the TLVUpdater's reader positioned
 * anywhere within the input TLV. The reader can also be positioned under
 * multiple levels of nested containers and this method will still work.
 *
 * @note This method also changes the state of the TLVUpdater object to a state
 * it would be in if the application had painstakingly parsed each element from
 * the current read point till the end of the input encoding and copied them to
 * the output TLV.
 */
void TLVUpdater::MoveUntilEnd()
{
    const uint8_t *buffEnd = mUpdaterReader.GetReadPoint() +
                                mUpdaterReader.GetRemainingLength();

    uint32_t copyLen = buffEnd - mElementStartAddr;

    // Move all elements till end to output TLV
    memmove(mUpdaterWriter.mWritePoint, mElementStartAddr, copyLen);

    // Adjust the updater state
    mElementStartAddr += copyLen;
    mUpdaterWriter.mWritePoint += copyLen;
    mUpdaterWriter.mLenWritten += copyLen;
    mUpdaterWriter.mMaxLen += copyLen;
    mUpdaterWriter.mContainerType = kTLVType_NotSpecified;
    mUpdaterWriter.SetContainerOpen(false);
    mUpdaterWriter.SetCloseContainerReserved(false);
    mUpdaterReader.mReadPoint += copyLen;
    mUpdaterReader.mLenRead += copyLen;
    mUpdaterReader.mControlByte = kTLVControlByte_NotSpecified;
    mUpdaterReader.mElemTag = AnonymousTag;
    mUpdaterReader.mElemLenOrVal = 0;
    mUpdaterReader.mContainerType = kTLVType_NotSpecified;
    mUpdaterReader.SetContainerOpen(false);
}

/**
 * Prepares a TLVUpdater object for reading elements of a container. It also
 * encodes a start of container object in the output TLV.
 *
 * The EnterContainer() method prepares the current TLVUpdater object to begin
 * reading the member elements of a TLV container (a structure, array or path).
 * For every call to EnterContainer() applications must make a corresponding
 * call to ExitContainer().
 *
 * When EnterContainer() is called the TLVUpdater's reader must be positioned on
 * the container element. The method takes as an argument a reference to a
 * TLVType value which will be used to save the context of the updater while it
 * is reading the container.
 *
 * When the EnterContainer() method returns, the updater is positioned
 * immediately @em before the first member of the container. Repeatedly calling
 * Next() will advance the updater through the members of the collection until
 * the end is reached, at which point the updater will return WEAVE_END_OF_TLV.
 *
 * Once the application has finished reading a container it can continue reading
 * the elements after the container by calling the ExitContainer() method.
 *
 * @note This method implicitly encodes a start of container element in the
 * output TLV buffer.
 *
 * @param[out] outerContainerType       A reference to a TLVType value that will
 *                                      receive the context of the updater.
 *
 * @retval #WEAVE_NO_ERROR              If the method succeeded.
 * @retval #WEAVE_ERROR_INCORRECT_STATE If the TLVUpdater reader is not
 *                                      positioned on a container element.
 * @retval other                        Any other Weave or platform error code
 *                                      returned by TLVWriter::StartContainer()
 *                                      or TLVReader::EnterContainer().
 *
 */
WEAVE_ERROR TLVUpdater::EnterContainer(TLVType& outerContainerType)
{
    WEAVE_ERROR err = WEAVE_NO_ERROR;
    TLVType containerType;

    VerifyOrExit(TLVTypeIsContainer(mUpdaterReader.mControlByte & kTLVTypeMask),
                 err = WEAVE_ERROR_INCORRECT_STATE);

    // Change the updater state
    AdjustInternalWriterFreeSpace();

    err = mUpdaterWriter.StartContainer(mUpdaterReader.GetTag(),
                                      mUpdaterReader.GetType(),
                                      containerType);
    SuccessOrExit(err);

    err = mUpdaterReader.EnterContainer(containerType);
    SuccessOrExit(err);

    outerContainerType = containerType;

exit:
    return err;
}

/**
 * Completes the reading of a TLV container element and encodes an end of TLV
 * element in the output TLV.
 *
 * The ExitContainer() method restores the state of a TLVUpdater object after a
 * call to EnterContainer(). For every call to EnterContainer() applications
 * must make a corresponding call to ExitContainer(), passing the context value
 * returned by the EnterContainer() method.
 *
 * When ExitContainer() returns, the TLVUpdater reader is positioned immediately
 * before the first element that follows the container in the input TLV. From
 * this point applications can call Next() to advance through any remaining
 * elements.
 *
 * Once EnterContainer() has been called, applications can call ExitContainer()
 * on the updater at any point in time, regardless of whether all elements in
 * the underlying container have been read. Also, note that calling
 * ExitContainer() before reading all the elements in the container, will result
 * in the updated container getting truncated in the output TLV.
 *
 * @note Any changes made to the configuration of the updater between the calls
 * to EnterContainer() and ExitContainer() are NOT undone by the call to
 * ExitContainer(). For example, a change to the implicit profile id
 * (@p ImplicitProfileId) will not be reversed when a container is exited. Thus
 * it is the application's responsibility to adjust the configuration
 * accordingly at the appropriate times.
 *
 * @param[in] outerContainerType        The TLVType value that was returned by
 *                                      the EnterContainer() method.
 *
 * @retval #WEAVE_NO_ERROR              If the method succeeded.
 * @retval #WEAVE_ERROR_TLV_UNDERRUN    If the underlying TLV encoding ended
 *                                      prematurely.
 * @retval #WEAVE_ERROR_INVALID_TLV_ELEMENT
 *                                      If the updater encountered an invalid or
 *                                      unsupported TLV element type.
 * @retval #WEAVE_ERROR_INVALID_TLV_TAG If the updater encountered a TLV tag in
 *                                      an invalid context.
 * @retval other                        Any other Weave or platform error code
 *                                      returned by TLVWriter::EndContainer() or
 *                                      TLVReader::ExitContainer().
 *
 */
WEAVE_ERROR TLVUpdater::ExitContainer(TLVType outerContainerType)
{
    WEAVE_ERROR err = WEAVE_NO_ERROR;

    err = mUpdaterReader.ExitContainer(outerContainerType);
    SuccessOrExit(err);

    // Change the updater's state
    AdjustInternalWriterFreeSpace();

    err = mUpdaterWriter.EndContainer(outerContainerType);
    SuccessOrExit(err);

exit:
    return err;
}

/**
 * This is a private method that adjusts the TLVUpdater's free space count by
 * accounting for the freespace from mElementStartAddr to current read point.
 */
void TLVUpdater::AdjustInternalWriterFreeSpace()
{
    const uint8_t *nextElementStart = mUpdaterReader.mReadPoint;

    if (nextElementStart != mElementStartAddr)
    {
        // Increase the internal writer's free space state variables
        mUpdaterWriter.mRemainingLen += nextElementStart - mElementStartAddr;
        mUpdaterWriter.mMaxLen += nextElementStart - mElementStartAddr;

        // Cache the start address of the next element
        mElementStartAddr = nextElementStart;
    }
}

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