/*
 *
 *    Copyright (c) 2020-2023 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.
 */
#include <lib/core/TLVReader.h>

#include <stdint.h>
#include <string.h>

#include <lib/core/CHIPConfig.h>
#include <lib/core/CHIPEncoding.h>
#include <lib/core/CHIPError.h>
#include <lib/core/CHIPSafeCasts.h>
#include <lib/core/DataModelTypes.h>
#include <lib/core/Optional.h>
#include <lib/core/TLVBackingStore.h>
#include <lib/core/TLVCommon.h>
#include <lib/core/TLVTags.h>
#include <lib/core/TLVTypes.h>
#include <lib/support/BufferWriter.h>
#include <lib/support/BytesToHex.h>
#include <lib/support/CHIPMem.h>
#include <lib/support/CodeUtils.h>
#include <lib/support/SafeInt.h>
#include <lib/support/Span.h>
#include <lib/support/logging/TextOnlyLogging.h>

#if CHIP_CONFIG_TLV_VALIDATE_CHAR_STRING_ON_READ
#include <lib/support/utf8.h>
#endif

namespace chip {
namespace TLV {

using namespace chip::Encoding;

static const uint8_t sTagSizes[] = { 0, 1, 2, 4, 2, 4, 6, 8 };

TLVReader::TLVReader() :
    ImplicitProfileId(kProfileIdNotSpecified), AppData(nullptr), mElemLenOrVal(0), mBackingStore(nullptr), mReadPoint(nullptr),
    mBufEnd(nullptr), mLenRead(0), mMaxLen(0), mContainerType(kTLVType_NotSpecified), mControlByte(kTLVControlByte_NotSpecified),
    mContainerOpen(false)
{}

void TLVReader::Init(const uint8_t * data, size_t dataLen)
{
    // TODO: Maybe we can just make mMaxLen and mLenRead size_t instead?
    uint32_t actualDataLen = dataLen > UINT32_MAX ? UINT32_MAX : static_cast<uint32_t>(dataLen);
    mBackingStore          = nullptr;
    mReadPoint             = data;
    mBufEnd                = data + actualDataLen;
    mLenRead               = 0;
    mMaxLen                = actualDataLen;
    ClearElementState();
    mContainerType = kTLVType_NotSpecified;
    SetContainerOpen(false);

    ImplicitProfileId = kProfileIdNotSpecified;
}

CHIP_ERROR TLVReader::Init(TLVBackingStore & backingStore, uint32_t maxLen)
{
    mBackingStore   = &backingStore;
    mReadPoint      = nullptr;
    uint32_t bufLen = 0;
    CHIP_ERROR err  = mBackingStore->OnInit(*this, mReadPoint, bufLen);
    if (err != CHIP_NO_ERROR)
        return err;

    mBufEnd  = mReadPoint + bufLen;
    mLenRead = 0;
    mMaxLen  = maxLen;
    ClearElementState();
    mContainerType = kTLVType_NotSpecified;
    SetContainerOpen(false);

    ImplicitProfileId = kProfileIdNotSpecified;
    AppData           = nullptr;
    return CHIP_NO_ERROR;
}

void TLVReader::Init(const TLVReader & aReader)
{
    // Initialize private data members

    mElemTag       = aReader.mElemTag;
    mElemLenOrVal  = aReader.mElemLenOrVal;
    mBackingStore  = aReader.mBackingStore;
    mReadPoint     = aReader.mReadPoint;
    mBufEnd        = aReader.mBufEnd;
    mLenRead       = aReader.mLenRead;
    mMaxLen        = aReader.mMaxLen;
    mControlByte   = aReader.mControlByte;
    mContainerType = aReader.mContainerType;
    SetContainerOpen(aReader.IsContainerOpen());

    // Initialize public data members

    ImplicitProfileId = aReader.ImplicitProfileId;
    AppData           = aReader.AppData;
}

TLVType TLVReader::GetType() const
{
    TLVElementType elemType = ElementType();
    if (elemType == TLVElementType::EndOfContainer)
        return kTLVType_NotSpecified;
    if (elemType == TLVElementType::FloatingPointNumber32 || elemType == TLVElementType::FloatingPointNumber64)
        return kTLVType_FloatingPointNumber;
    if (elemType == TLVElementType::NotSpecified || elemType >= TLVElementType::Null)
        return static_cast<TLVType>(elemType);
    return static_cast<TLVType>(static_cast<uint8_t>(elemType) & ~kTLVTypeSizeMask);
}

uint32_t TLVReader::GetLength() const
{
    if (TLVTypeHasLength(ElementType()))
        return static_cast<uint32_t>(mElemLenOrVal);
    return 0;
}

CHIP_ERROR TLVReader::Get(bool & v) const
{
    TLVElementType elemType = ElementType();
    if (elemType == TLVElementType::BooleanFalse)
        v = false;
    else if (elemType == TLVElementType::BooleanTrue)
        v = true;
    else
        return CHIP_ERROR_WRONG_TLV_TYPE;
    return CHIP_NO_ERROR;
}

CHIP_ERROR TLVReader::Get(int8_t & v) const
{
    int64_t v64    = 0;
    CHIP_ERROR err = Get(v64);
    if (!CanCastTo<int8_t>(v64))
    {
        return CHIP_ERROR_INVALID_INTEGER_VALUE;
    }
    v = static_cast<int8_t>(v64);
    return err;
}

CHIP_ERROR TLVReader::Get(int16_t & v) const
{
    int64_t v64    = 0;
    CHIP_ERROR err = Get(v64);
    if (!CanCastTo<int16_t>(v64))
    {
        return CHIP_ERROR_INVALID_INTEGER_VALUE;
    }
    v = static_cast<int16_t>(v64);
    return err;
}

CHIP_ERROR TLVReader::Get(int32_t & v) const
{
    int64_t v64    = 0;
    CHIP_ERROR err = Get(v64);
    if (!CanCastTo<int32_t>(v64))
    {
        return CHIP_ERROR_INVALID_INTEGER_VALUE;
    }
    v = static_cast<int32_t>(v64);
    return err;
}

CHIP_ERROR TLVReader::Get(int64_t & v) const
{
    // Internal callers of this method depend on it not modifying "v" on failure.
    switch (ElementType())
    {
    case TLVElementType::Int8:
        v = CastToSigned(static_cast<uint8_t>(mElemLenOrVal));
        break;
    case TLVElementType::Int16:
        v = CastToSigned(static_cast<uint16_t>(mElemLenOrVal));
        break;
    case TLVElementType::Int32:
        v = CastToSigned(static_cast<uint32_t>(mElemLenOrVal));
        break;
    case TLVElementType::Int64:
        v = CastToSigned(mElemLenOrVal);
        break;
    default:
        return CHIP_ERROR_WRONG_TLV_TYPE;
    }

    return CHIP_NO_ERROR;
}

CHIP_ERROR TLVReader::Get(uint8_t & v) const
{
    uint64_t v64   = 0;
    CHIP_ERROR err = Get(v64);
    if (!CanCastTo<uint8_t>(v64))
    {
        return CHIP_ERROR_INVALID_INTEGER_VALUE;
    }
    v = static_cast<uint8_t>(v64);
    return err;
}

CHIP_ERROR TLVReader::Get(uint16_t & v) const
{
    uint64_t v64   = 0;
    CHIP_ERROR err = Get(v64);
    if (!CanCastTo<uint16_t>(v64))
    {
        return CHIP_ERROR_INVALID_INTEGER_VALUE;
    }
    v = static_cast<uint16_t>(v64);
    return err;
}

CHIP_ERROR TLVReader::Get(uint32_t & v) const
{
    uint64_t v64   = 0;
    CHIP_ERROR err = Get(v64);
    if (!CanCastTo<uint32_t>(v64))
    {
        return CHIP_ERROR_INVALID_INTEGER_VALUE;
    }
    v = static_cast<uint32_t>(v64);
    return err;
}

CHIP_ERROR TLVReader::Get(uint64_t & v) const
{
    // Internal callers of this method depend on it not modifying "v" on failure.
    switch (ElementType())
    {
    case TLVElementType::UInt8:
    case TLVElementType::UInt16:
    case TLVElementType::UInt32:
    case TLVElementType::UInt64:
        v = mElemLenOrVal;
        break;
    default:
        return CHIP_ERROR_WRONG_TLV_TYPE;
    }
    return CHIP_NO_ERROR;
}

namespace {
float BitCastToFloat(const uint64_t elemLenOrVal)
{
    float f;
    auto unsigned32 = static_cast<uint32_t>(elemLenOrVal);
    memcpy(&f, &unsigned32, sizeof(f));
    return f;
}
} // namespace

// Note: Unlike the integer Get functions, this code avoids doing conversions
// between float and double wherever possible, because these conversions are
// relatively expensive on platforms that use soft-float instruction sets.

CHIP_ERROR TLVReader::Get(float & v) const
{
    switch (ElementType())
    {
    case TLVElementType::FloatingPointNumber32: {
        v = BitCastToFloat(mElemLenOrVal);
        break;
    }
    default:
        return CHIP_ERROR_WRONG_TLV_TYPE;
    }
    return CHIP_NO_ERROR;
}

CHIP_ERROR TLVReader::Get(double & v) const
{
    switch (ElementType())
    {
    case TLVElementType::FloatingPointNumber32: {
        v = BitCastToFloat(mElemLenOrVal);
        break;
    }
    case TLVElementType::FloatingPointNumber64: {
        double d;
        memcpy(&d, &mElemLenOrVal, sizeof(d));
        v = d;
        break;
    }
    default:
        return CHIP_ERROR_WRONG_TLV_TYPE;
    }
    return CHIP_NO_ERROR;
}

CHIP_ERROR TLVReader::Get(ByteSpan & v) const
{
    const uint8_t * val;
    ReturnErrorOnFailure(GetDataPtr(val));
    v = ByteSpan(val, GetLength());

    return CHIP_NO_ERROR;
}

namespace {
constexpr int kUnicodeInformationSeparator1       = 0x1F;
constexpr size_t kMaxLocalizedStringIdentifierLen = 2 * sizeof(LocalizedStringIdentifier);
} // namespace

CHIP_ERROR TLVReader::Get(CharSpan & v) const
{
    if (!TLVTypeIsUTF8String(ElementType()))
    {
        return CHIP_ERROR_WRONG_TLV_TYPE;
    }

    const uint8_t * bytes;
    ReturnErrorOnFailure(GetDataPtr(bytes)); // Does length sanity checks
    if (bytes == nullptr)
    {
        // Calling memchr further down with bytes == nullptr would have undefined behaviour, exiting early.
        return CHIP_NO_ERROR;
    }

    uint32_t len = GetLength();

    // If Unicode Information Separator 1 (0x1f) is present in the string then method returns
    // string ending at first appearance of the Information Separator 1.
    const uint8_t * infoSeparator = reinterpret_cast<const uint8_t *>(memchr(bytes, kUnicodeInformationSeparator1, len));
    if (infoSeparator != nullptr)
    {
        len = static_cast<uint32_t>(infoSeparator - bytes);
    }

    v = CharSpan(Uint8::to_const_char(bytes), len);
#if CHIP_CONFIG_TLV_VALIDATE_CHAR_STRING_ON_READ
    // Spec requirement: A.11.2. UTF-8 and Octet Strings
    //
    // For UTF-8 strings, the value octets SHALL encode a valid
    // UTF-8 character (code points) sequence.
    //
    // Senders SHALL NOT include a terminating null character to
    // mark the end of a string.

    if (!Utf8::IsValid(v))
    {
        return CHIP_ERROR_INVALID_UTF8;
    }

    if (!v.empty() && (v.back() == 0))
    {
        return CHIP_ERROR_INVALID_TLV_CHAR_STRING;
    }
#endif // CHIP_CONFIG_TLV_VALIDATE_CHAR_STRING_ON_READ
    return CHIP_NO_ERROR;
}

CHIP_ERROR TLVReader::Get(Optional<LocalizedStringIdentifier> & lsid)
{
    lsid.ClearValue();
    VerifyOrReturnError(TLVTypeIsUTF8String(ElementType()), CHIP_ERROR_WRONG_TLV_TYPE);

    const uint8_t * bytes;
    ReturnErrorOnFailure(GetDataPtr(bytes)); // Does length sanity checks
    if (bytes == nullptr)
    {
        // Calling memchr further down with bytes == nullptr would have undefined behaviour, exiting early.
        return CHIP_NO_ERROR;
    }

    uint32_t len = GetLength();

    const uint8_t * infoSeparator1 = static_cast<const uint8_t *>(memchr(bytes, kUnicodeInformationSeparator1, len));
    if (infoSeparator1 == nullptr)
    {
        return CHIP_NO_ERROR;
    }

    const uint8_t * lsidPtr = infoSeparator1 + 1;
    len -= static_cast<uint32_t>(lsidPtr - bytes);

    const uint8_t * infoSeparator2 = static_cast<const uint8_t *>(memchr(lsidPtr, kUnicodeInformationSeparator1, len));
    if (infoSeparator2 != nullptr)
    {
        len = static_cast<uint32_t>(infoSeparator2 - lsidPtr);
    }
    if (len == 0)
    {
        return CHIP_NO_ERROR;
    }
    VerifyOrReturnError(len <= kMaxLocalizedStringIdentifierLen, CHIP_ERROR_INVALID_TLV_ELEMENT);
    // Leading zeroes are not allowed.
    VerifyOrReturnError(static_cast<char>(lsidPtr[0]) != '0', CHIP_ERROR_INVALID_TLV_ELEMENT);

    char idStr[kMaxLocalizedStringIdentifierLen] = { '0', '0', '0', '0' };
    memcpy(&idStr[kMaxLocalizedStringIdentifierLen - len], lsidPtr, len);

    LocalizedStringIdentifier id;
    VerifyOrReturnError(Encoding::UppercaseHexToUint16(idStr, sizeof(idStr), id) == sizeof(LocalizedStringIdentifier),
                        CHIP_ERROR_INVALID_TLV_ELEMENT);

    lsid.SetValue(id);
    return CHIP_NO_ERROR;
}

CHIP_ERROR TLVReader::GetBytes(uint8_t * buf, size_t bufSize)
{
    if (!TLVTypeIsString(ElementType()))
        return CHIP_ERROR_WRONG_TLV_TYPE;

    if (mElemLenOrVal > bufSize)
        return CHIP_ERROR_BUFFER_TOO_SMALL;

    CHIP_ERROR err = ReadData(buf, static_cast<uint32_t>(mElemLenOrVal));
    if (err != CHIP_NO_ERROR)
        return err;

    mElemLenOrVal = 0;

    return CHIP_NO_ERROR;
}

CHIP_ERROR TLVReader::GetString(char * buf, size_t bufSize)
{
    if (!TLVTypeIsString(ElementType()))
        return CHIP_ERROR_WRONG_TLV_TYPE;

    if ((mElemLenOrVal + 1) > bufSize)
        return CHIP_ERROR_BUFFER_TOO_SMALL;

    buf[mElemLenOrVal] = 0;

    return GetBytes(reinterpret_cast<uint8_t *>(buf), bufSize - 1);
}

CHIP_ERROR TLVReader::DupBytes(uint8_t *& buf, uint32_t & dataLen)
{
    if (!TLVTypeIsString(ElementType()))
        return CHIP_ERROR_WRONG_TLV_TYPE;

    buf = static_cast<uint8_t *>(chip::Platform::MemoryAlloc(static_cast<uint32_t>(mElemLenOrVal)));
    if (buf == nullptr)
        return CHIP_ERROR_NO_MEMORY;

    CHIP_ERROR err = ReadData(buf, static_cast<uint32_t>(mElemLenOrVal));
    if (err != CHIP_NO_ERROR)
    {
        chip::Platform::MemoryFree(buf);
        buf = nullptr;
        return err;
    }

    dataLen       = static_cast<uint32_t>(mElemLenOrVal);
    mElemLenOrVal = 0;

    return CHIP_NO_ERROR;
}

CHIP_ERROR TLVReader::DupString(char *& buf)
{
    if (!TLVTypeIsString(ElementType()))
        return CHIP_ERROR_WRONG_TLV_TYPE;

    if (mElemLenOrVal > UINT32_MAX - 1)
        return CHIP_ERROR_NO_MEMORY;

    buf = static_cast<char *>(chip::Platform::MemoryAlloc(static_cast<uint32_t>(mElemLenOrVal + 1)));
    if (buf == nullptr)
        return CHIP_ERROR_NO_MEMORY;

    CHIP_ERROR err = ReadData(reinterpret_cast<uint8_t *>(buf), static_cast<uint32_t>(mElemLenOrVal));
    if (err != CHIP_NO_ERROR)
    {
        chip::Platform::MemoryFree(buf);
        buf = nullptr;
        return err;
    }

    buf[mElemLenOrVal] = 0;
    mElemLenOrVal      = 0;

    return err;
}

CHIP_ERROR TLVReader::GetDataPtr(const uint8_t *& data) const
{
    VerifyOrReturnError(TLVTypeIsString(ElementType()), CHIP_ERROR_WRONG_TLV_TYPE);

    if (GetLength() == 0)
    {
        data = nullptr;
        return CHIP_NO_ERROR;
    }

    uint32_t remainingLen = static_cast<decltype(mMaxLen)>(mBufEnd - mReadPoint);

    // Verify that the entirety of the data is available in the buffer.
    // Note that this may not be possible if the reader is reading from a chain of buffers.
    VerifyOrReturnError(remainingLen >= static_cast<uint32_t>(mElemLenOrVal), CHIP_ERROR_TLV_UNDERRUN);
    data = mReadPoint;
    return CHIP_NO_ERROR;
}

CHIP_ERROR TLVReader::OpenContainer(TLVReader & containerReader)
{
    TLVElementType elemType = ElementType();
    if (!TLVTypeIsContainer(elemType))
        return CHIP_ERROR_INCORRECT_STATE;

    containerReader.mBackingStore = mBackingStore;
    containerReader.mReadPoint    = mReadPoint;
    containerReader.mBufEnd       = mBufEnd;
    containerReader.mLenRead      = mLenRead;
    containerReader.mMaxLen       = mMaxLen;
    containerReader.ClearElementState();
    containerReader.mContainerType = static_cast<TLVType>(elemType);
    containerReader.SetContainerOpen(false);
    containerReader.ImplicitProfileId = ImplicitProfileId;
    containerReader.AppData           = AppData;

    SetContainerOpen(true);

    return CHIP_NO_ERROR;
}

CHIP_ERROR TLVReader::CloseContainer(TLVReader & containerReader)
{
    CHIP_ERROR err;

    if (!IsContainerOpen())
        return CHIP_ERROR_INCORRECT_STATE;

    if (static_cast<TLVElementType>(containerReader.mContainerType) != ElementType())
        return CHIP_ERROR_INCORRECT_STATE;

    err = containerReader.SkipToEndOfContainer();
    if (err != CHIP_NO_ERROR)
        return err;

    mBackingStore = containerReader.mBackingStore;
    mReadPoint    = containerReader.mReadPoint;
    mBufEnd       = containerReader.mBufEnd;
    mLenRead      = containerReader.mLenRead;
    mMaxLen       = containerReader.mMaxLen;
    ClearElementState();

    return CHIP_NO_ERROR;
}

CHIP_ERROR TLVReader::EnterContainer(TLVType & outerContainerType)
{
    TLVElementType elemType = ElementType();
    if (!TLVTypeIsContainer(elemType))
        return CHIP_ERROR_INCORRECT_STATE;

    outerContainerType = mContainerType;
    mContainerType     = static_cast<TLVType>(elemType);

    ClearElementState();
    SetContainerOpen(false);

    return CHIP_NO_ERROR;
}

CHIP_ERROR TLVReader::ExitContainer(TLVType outerContainerType)
{
    CHIP_ERROR err;

    err = SkipToEndOfContainer();
    if (err != CHIP_NO_ERROR)
        return err;

    mContainerType = outerContainerType;
    ClearElementState();

    return CHIP_NO_ERROR;
}

CHIP_ERROR TLVReader::VerifyEndOfContainer()
{
    CHIP_ERROR err = Next();
    if (err == CHIP_END_OF_TLV)
        return CHIP_NO_ERROR;
    if (err == CHIP_NO_ERROR)
        return CHIP_ERROR_UNEXPECTED_TLV_ELEMENT;
    return err;
}

CHIP_ERROR TLVReader::Next()
{
    ReturnErrorOnFailure(Skip());
    ReturnErrorOnFailure(ReadElement());

    TLVElementType elemType = ElementType();

    VerifyOrReturnError(elemType != TLVElementType::EndOfContainer, CHIP_END_OF_TLV);

    // Ensure that GetDataPtr calls can be called immediately after Next, so
    // that `Get(ByteSpan&)` does not need to advance buffers and just works
    if (TLVTypeIsString(elemType) && (GetLength() != 0))
    {
        ReturnErrorOnFailure(EnsureData(CHIP_ERROR_TLV_UNDERRUN));
    }

    return CHIP_NO_ERROR;
}

CHIP_ERROR TLVReader::Expect(Tag expectedTag)
{
    VerifyOrReturnError(GetType() != kTLVType_NotSpecified, CHIP_ERROR_WRONG_TLV_TYPE);
    VerifyOrReturnError(GetTag() == expectedTag, CHIP_ERROR_UNEXPECTED_TLV_ELEMENT);
    return CHIP_NO_ERROR;
}

CHIP_ERROR TLVReader::Next(Tag expectedTag)
{
    ReturnErrorOnFailure(Next());
    ReturnErrorOnFailure(Expect(expectedTag));
    return CHIP_NO_ERROR;
}

CHIP_ERROR TLVReader::Expect(TLVType expectedType, Tag expectedTag)
{
    VerifyOrReturnError(GetType() == expectedType, CHIP_ERROR_WRONG_TLV_TYPE);
    VerifyOrReturnError(GetTag() == expectedTag, CHIP_ERROR_UNEXPECTED_TLV_ELEMENT);
    return CHIP_NO_ERROR;
}

CHIP_ERROR TLVReader::Next(TLVType expectedType, Tag expectedTag)
{
    ReturnErrorOnFailure(Next());
    ReturnErrorOnFailure(Expect(expectedType, expectedTag));
    return CHIP_NO_ERROR;
}

CHIP_ERROR TLVReader::Skip()
{
    CHIP_ERROR err;
    TLVElementType elemType = ElementType();

    if (elemType == TLVElementType::EndOfContainer)
        return CHIP_END_OF_TLV;

    if (TLVTypeIsContainer(elemType))
    {
        TLVType outerContainerType;
        err = EnterContainer(outerContainerType);
        if (err != CHIP_NO_ERROR)
            return err;
        err = ExitContainer(outerContainerType);
        if (err != CHIP_NO_ERROR)
            return err;
    }

    else
    {
        err = SkipData();
        if (err != CHIP_NO_ERROR)
            return err;

        ClearElementState();
    }

    return CHIP_NO_ERROR;
}

/**
 * Clear the state of the TLVReader.
 * This method is used to position the reader before the first TLV,
 * between TLVs or after the last TLV.
 */
void TLVReader::ClearElementState()
{
    mElemTag      = AnonymousTag();
    mControlByte  = kTLVControlByte_NotSpecified;
    mElemLenOrVal = 0;
}

/**
 * Skip any data contained in the current TLV by reading over it without
 * a destination buffer.
 *
 * @retval #CHIP_NO_ERROR              If the reader was successfully positioned at the end of the
 *                                      data.
 * @retval other                        Other CHIP or platform error codes returned by the configured
 *                                      TLVBackingStore.
 */
CHIP_ERROR TLVReader::SkipData()
{
    CHIP_ERROR err          = CHIP_NO_ERROR;
    TLVElementType elemType = ElementType();

    if (TLVTypeHasLength(elemType))
    {
        err = ReadData(nullptr, static_cast<uint32_t>(mElemLenOrVal));
        if (err != CHIP_NO_ERROR)
            return err;
    }

    return err;
}

CHIP_ERROR TLVReader::SkipToEndOfContainer()
{
    CHIP_ERROR err;
    TLVType outerContainerType = mContainerType;
    uint32_t nestLevel         = 0;

    // If the user calls Next() after having called OpenContainer() but before calling
    // CloseContainer() they're effectively doing a close container by skipping over
    // the container element.  So reset the 'container open' flag here to prevent them
    // from calling CloseContainer() with the now orphaned container reader.
    SetContainerOpen(false);

    while (true)
    {
        TLVElementType elemType = ElementType();

        if (elemType == TLVElementType::EndOfContainer)
        {
            if (nestLevel == 0)
                return CHIP_NO_ERROR;

            nestLevel--;
            mContainerType = (nestLevel == 0) ? outerContainerType : kTLVType_UnknownContainer;
        }

        else if (TLVTypeIsContainer(elemType))
        {
            nestLevel++;
            mContainerType = static_cast<TLVType>(elemType);
        }

        err = SkipData();
        if (err != CHIP_NO_ERROR)
            return err;

        err = ReadElement();
        if (err != CHIP_NO_ERROR)
            return err;
    }
}

CHIP_ERROR TLVReader::ReadElement()
{
    CHIP_ERROR err;
    uint8_t stagingBuf[17]; // 17 = 1 control byte + 8 tag bytes + 8 length/value bytes
    const uint8_t * p;
    TLVElementType elemType;

    // Make sure we have input data. Return CHIP_END_OF_TLV if no more data is available.
    err = EnsureData(CHIP_END_OF_TLV);
    if (err != CHIP_NO_ERROR)
        return err;

    if (mReadPoint == nullptr)
    {
        return CHIP_ERROR_INVALID_TLV_ELEMENT;
    }
    // Get the element's control byte.
    mControlByte = *mReadPoint;

    // Extract the element type from the control byte. Fail if it's invalid.
    elemType = ElementType();
    if (!IsValidTLVType(elemType))
        return CHIP_ERROR_INVALID_TLV_ELEMENT;

    // Extract the tag control from the control byte.
    TLVTagControl tagControl = static_cast<TLVTagControl>(mControlByte & kTLVTagControlMask);

    // Determine the number of bytes in the element's tag, if any.
    uint8_t tagBytes = sTagSizes[tagControl >> kTLVTagControlShift];

    // Extract the size of length/value field from the control byte.
    TLVFieldSize lenOrValFieldSize = GetTLVFieldSize(elemType);

    // Determine the number of bytes in the length/value field.
    uint8_t valOrLenBytes = TLVFieldSizeToBytes(lenOrValFieldSize);

    // Determine the number of bytes in the element's 'head'. This includes: the control byte, the tag bytes (if present), the
    // length bytes (if present), and for elements that don't have a length (e.g. integers), the value bytes.
    uint8_t elemHeadBytes = static_cast<uint8_t>(1 + tagBytes + valOrLenBytes);

    // If the head of the element overlaps the end of the input buffer, read the bytes into the staging buffer
    // and arrange to parse them from there. Otherwise read them directly from the input buffer.
    if (elemHeadBytes > (mBufEnd - mReadPoint))
    {
        err = ReadData(stagingBuf, elemHeadBytes);
        if (err != CHIP_NO_ERROR)
            return err;
        p = stagingBuf;
    }
    else
    {
        p = mReadPoint;
        mReadPoint += elemHeadBytes;
        mLenRead += elemHeadBytes;
    }

    // Skip over the control byte.
    p++;

    // Read the tag field, if present.
    mElemTag = ReadTag(tagControl, p);

    // Read the length/value field, if present.
    switch (lenOrValFieldSize)
    {
    case kTLVFieldSize_0Byte:
        mElemLenOrVal = 0;
        break;
    case kTLVFieldSize_1Byte:
        mElemLenOrVal = Read8(p);
        break;
    case kTLVFieldSize_2Byte:
        mElemLenOrVal = LittleEndian::Read16(p);
        break;
    case kTLVFieldSize_4Byte:
        mElemLenOrVal = LittleEndian::Read32(p);
        break;
    case kTLVFieldSize_8Byte:
        mElemLenOrVal = LittleEndian::Read64(p);
        VerifyOrReturnError(!TLVTypeHasLength(elemType) || (mElemLenOrVal <= UINT32_MAX), CHIP_ERROR_NOT_IMPLEMENTED);
        break;
    }

    return VerifyElement();
}

CHIP_ERROR TLVReader::VerifyElement()
{
    if (ElementType() == TLVElementType::EndOfContainer)
    {
        if (mContainerType == kTLVType_NotSpecified)
            return CHIP_ERROR_INVALID_TLV_ELEMENT;
        if (mElemTag != AnonymousTag())
            return CHIP_ERROR_INVALID_TLV_TAG;
    }
    else
    {
        if (mElemTag == UnknownImplicitTag())
            return CHIP_ERROR_UNKNOWN_IMPLICIT_TLV_TAG;
        switch (mContainerType)
        {
        case kTLVType_NotSpecified:
            if (IsContextTag(mElemTag))
                return CHIP_ERROR_INVALID_TLV_TAG;
            break;
        case kTLVType_Structure:
            if (mElemTag == AnonymousTag())
                return CHIP_ERROR_INVALID_TLV_TAG;
            break;
        case kTLVType_Array:
            if (mElemTag != AnonymousTag())
                return CHIP_ERROR_INVALID_TLV_TAG;
            break;
        case kTLVType_UnknownContainer:
        case kTLVType_List:
            break;
        default:
            return CHIP_ERROR_INCORRECT_STATE;
        }
    }

    // If the current element encodes a specific length (e.g. a UTF8 string or a byte string), verify
    // that the purported length fits within the remaining bytes of the encoding (as delineated by mMaxLen).
    //
    // Note that this check is not strictly necessary to prevent runtime errors, as any attempt to access
    // the data of an element with an invalid length will result in an error.  However checking the length
    // here catches the error earlier, and ensures that the application will never see the erroneous length
    // value.
    //
    if (TLVTypeHasLength(ElementType()))
    {
        uint32_t overallLenRemaining = mMaxLen - mLenRead;
        if (overallLenRemaining < static_cast<uint32_t>(mElemLenOrVal))
            return CHIP_ERROR_TLV_UNDERRUN;
    }

    return CHIP_NO_ERROR;
}

Tag TLVReader::ReadTag(TLVTagControl tagControl, const uint8_t *& p) const
{
    uint16_t vendorId;
    uint16_t profileNum;

    switch (tagControl)
    {
    case TLVTagControl::ContextSpecific:
        return ContextTag(Read8(p));
    case TLVTagControl::CommonProfile_2Bytes:
        return CommonTag(LittleEndian::Read16(p));
    case TLVTagControl::CommonProfile_4Bytes:
        return CommonTag(LittleEndian::Read32(p));
    case TLVTagControl::ImplicitProfile_2Bytes:
        if (ImplicitProfileId == kProfileIdNotSpecified)
            return UnknownImplicitTag();
        return ProfileTag(ImplicitProfileId, LittleEndian::Read16(p));
    case TLVTagControl::ImplicitProfile_4Bytes:
        if (ImplicitProfileId == kProfileIdNotSpecified)
            return UnknownImplicitTag();
        return ProfileTag(ImplicitProfileId, LittleEndian::Read32(p));
    case TLVTagControl::FullyQualified_6Bytes:
        vendorId   = LittleEndian::Read16(p);
        profileNum = LittleEndian::Read16(p);
        return ProfileTag(vendorId, profileNum, LittleEndian::Read16(p));
    case TLVTagControl::FullyQualified_8Bytes:
        vendorId   = LittleEndian::Read16(p);
        profileNum = LittleEndian::Read16(p);
        return ProfileTag(vendorId, profileNum, LittleEndian::Read32(p));
    case TLVTagControl::Anonymous:
    default:
        return AnonymousTag();
    }
}

CHIP_ERROR TLVReader::ReadData(uint8_t * buf, uint32_t len)
{
    CHIP_ERROR err;

    while (len > 0)
    {
        err = EnsureData(CHIP_ERROR_TLV_UNDERRUN);
        if (err != CHIP_NO_ERROR)
            return err;

        uint32_t remainingLen = static_cast<decltype(mMaxLen)>(mBufEnd - mReadPoint);

        uint32_t readLen = len;
        if (readLen > remainingLen)
            readLen = remainingLen;

        if (buf != nullptr)
        {
            memcpy(buf, mReadPoint, readLen);
            buf += readLen;
        }
        mReadPoint += readLen;
        mLenRead += readLen;
        len -= readLen;
    }

    return CHIP_NO_ERROR;
}

CHIP_ERROR TLVReader::EnsureData(CHIP_ERROR noDataErr)
{
    CHIP_ERROR err;

    if (mReadPoint == mBufEnd)
    {
        if (mLenRead == mMaxLen)
            return noDataErr;

        if (mBackingStore == nullptr)
            return noDataErr;

        uint32_t bufLen;
        err = mBackingStore->GetNextBuffer(*this, mReadPoint, bufLen);
        if (err != CHIP_NO_ERROR)
            return err;
        if (bufLen == 0)
            return noDataErr;

        // Cap mBufEnd so that we don't read beyond the user's specified maximum length, even
        // if the underlying buffer is larger.
        uint32_t overallLenRemaining = mMaxLen - mLenRead;
        if (overallLenRemaining < bufLen)
            bufLen = overallLenRemaining;

        mBufEnd = mReadPoint + bufLen;
    }

    return CHIP_NO_ERROR;
}

/**
 * This is a private method used to compute the length of a TLV element head.
 */
CHIP_ERROR TLVReader::GetElementHeadLength(uint8_t & elemHeadBytes) const
{
    uint8_t tagBytes;
    uint8_t valOrLenBytes;
    TLVTagControl tagControl;
    TLVFieldSize lenOrValFieldSize;
    TLVElementType elemType = ElementType();

    // Verify element is of valid TLVType.
    VerifyOrReturnError(IsValidTLVType(elemType), CHIP_ERROR_INVALID_TLV_ELEMENT);

    // Extract the tag control from the control byte.
    tagControl = static_cast<TLVTagControl>(mControlByte & kTLVTagControlMask);

    // Determine the number of bytes in the element's tag, if any.
    tagBytes = sTagSizes[tagControl >> kTLVTagControlShift];

    // Extract the size of length/value field from the control byte.
    lenOrValFieldSize = GetTLVFieldSize(elemType);

    // Determine the number of bytes in the length/value field.
    valOrLenBytes = TLVFieldSizeToBytes(lenOrValFieldSize);

    // Determine the number of bytes in the element's 'head'. This includes: the
    // control byte, the tag bytes (if present), the length bytes (if present),
    // and for elements that don't have a length (e.g. integers), the value
    // bytes.
    VerifyOrReturnError(CanCastTo<uint8_t>(1 + tagBytes + valOrLenBytes), CHIP_ERROR_INTERNAL);
    elemHeadBytes = static_cast<uint8_t>(1 + tagBytes + valOrLenBytes);

    return CHIP_NO_ERROR;
}

/**
 * This is a private method that returns the TLVElementType from mControlByte
 */
TLVElementType TLVReader::ElementType() const
{
    if (mControlByte == static_cast<uint16_t>(kTLVControlByte_NotSpecified))
        return TLVElementType::NotSpecified;
    return static_cast<TLVElementType>(mControlByte & kTLVTypeMask);
}

CHIP_ERROR TLVReader::FindElementWithTag(Tag tag, TLVReader & destReader) const
{
    CHIP_ERROR err = CHIP_NO_ERROR;

    chip::TLV::TLVReader reader;
    reader.Init(*this);

    while (CHIP_NO_ERROR == (err = reader.Next()))
    {
        VerifyOrExit(chip::TLV::kTLVType_NotSpecified != reader.GetType(), err = CHIP_ERROR_INVALID_TLV_ELEMENT);

        if (tag == reader.GetTag())
        {
            destReader.Init(reader);
            break;
        }
    }

exit:
    ChipLogIfFalse((CHIP_NO_ERROR == err) || (CHIP_END_OF_TLV == err));

    return err;
}

CHIP_ERROR TLVReader::CountRemainingInContainer(size_t * size) const
{
    if (mContainerType == kTLVType_NotSpecified)
    {
        return CHIP_ERROR_INCORRECT_STATE;
    }

    TLVReader tempReader(*this);
    size_t count = 0;
    CHIP_ERROR err;
    while ((err = tempReader.Next()) == CHIP_NO_ERROR)
    {
        ++count;
    };
    if (err == CHIP_END_OF_TLV)
    {
        *size = count;
        return CHIP_NO_ERROR;
    }
    return err;
}

CHIP_ERROR ContiguousBufferTLVReader::OpenContainer(ContiguousBufferTLVReader & containerReader)
{
    // We are going to initialize containerReader by calling our superclass
    // OpenContainer method.  The superclass only knows how to initialize
    // members the superclass knows about, so we assert that we don't have any
    // extra members that need initializing.  If such members ever get added,
    // they would need to be initialized in this method.
    static_assert(sizeof(ContiguousBufferTLVReader) == sizeof(TLVReader), "We have state the superclass is not initializing?");
    return TLVReader::OpenContainer(containerReader);
}

CHIP_ERROR ContiguousBufferTLVReader::GetStringView(Span<const char> & data)
{
    return Get(data);
}

CHIP_ERROR ContiguousBufferTLVReader::GetByteView(ByteSpan & data)
{
    if (!TLVTypeIsByteString(ElementType()))
    {
        return CHIP_ERROR_WRONG_TLV_TYPE;
    }

    return Get(data);
}

} // namespace TLV
} // namespace chip
