/*
 *  Copyright (c) 2016, The OpenThread Authors.
 *  All rights reserved.
 *
 *  Redistribution and use in source and binary forms, with or without
 *  modification, are permitted provided that the following conditions are met:
 *  1. Redistributions of source code must retain the above copyright
 *     notice, this list of conditions and the following disclaimer.
 *  2. Redistributions in binary form must reproduce the above copyright
 *     notice, this list of conditions and the following disclaimer in the
 *     documentation and/or other materials provided with the distribution.
 *  3. Neither the name of the copyright holder nor the
 *     names of its contributors may be used to endorse or promote products
 *     derived from this software without specific prior written permission.
 *
 *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 *  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 *  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 *  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
 *  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 *  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 *  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 *  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 *  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 *  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 *  POSSIBILITY OF SUCH DAMAGE.
 */

/**
 * @file
 *   This file implements common methods for manipulating MLE TLVs.
 */

#include "tlvs.hpp"

#include "common/code_utils.hpp"
#include "common/debug.hpp"
#include "common/message.hpp"

namespace ot {

uint32_t Tlv::GetSize(void) const
{
    return IsExtended() ? sizeof(ExtendedTlv) + As<ExtendedTlv>(this)->GetLength() : sizeof(Tlv) + GetLength();
}

uint8_t *Tlv::GetValue(void)
{
    return reinterpret_cast<uint8_t *>(this) + (IsExtended() ? sizeof(ExtendedTlv) : sizeof(Tlv));
}

const uint8_t *Tlv::GetValue(void) const
{
    return reinterpret_cast<const uint8_t *>(this) + (IsExtended() ? sizeof(ExtendedTlv) : sizeof(Tlv));
}

Error Tlv::AppendTo(Message &aMessage) const { return aMessage.AppendBytes(this, static_cast<uint16_t>(GetSize())); }

Error Tlv::FindTlv(const Message &aMessage, uint8_t aType, uint16_t aMaxSize, Tlv &aTlv)
{
    uint16_t offset;

    return FindTlv(aMessage, aType, aMaxSize, aTlv, offset);
}

Error Tlv::FindTlv(const Message &aMessage, uint8_t aType, uint16_t aMaxSize, Tlv &aTlv, uint16_t &aOffset)
{
    Error      error;
    ParsedInfo info;

    SuccessOrExit(error = info.FindIn(aMessage, aType));

    if (aMaxSize > info.mSize)
    {
        aMaxSize = info.mSize;
    }

    aMessage.ReadBytes(info.mOffset, &aTlv, aMaxSize);
    aOffset = info.mOffset;

exit:
    return error;
}
Error Tlv::FindTlvValueOffset(const Message &aMessage, uint8_t aType, uint16_t &aValueOffset, uint16_t &aLength)
{
    Error      error;
    ParsedInfo info;

    SuccessOrExit(error = info.FindIn(aMessage, aType));

    aValueOffset = info.mValueOffset;
    aLength      = info.mLength;

exit:
    return error;
}

Error Tlv::FindTlvValueStartEndOffsets(const Message &aMessage,
                                       uint8_t        aType,
                                       uint16_t      &aValueStartOffset,
                                       uint16_t      &aValueEndOffset)
{
    Error      error;
    ParsedInfo info;

    SuccessOrExit(error = info.FindIn(aMessage, aType));

    aValueStartOffset = info.mValueOffset;
    aValueEndOffset   = info.mValueOffset + info.mLength;

exit:
    return error;
}

Error Tlv::ParsedInfo::ParseFrom(const Message &aMessage, uint16_t aOffset)
{
    // This method reads and parses the TLV info from `aMessage` at
    // `aOffset`. This can be used independent of whether the TLV is
    // extended or not. It validates that the entire TLV can be read
    // from `aMessage`.  Returns `kErrorNone` when successfully parsed,
    // otherwise `kErrorParse`.

    Error       error;
    Tlv         tlv;
    ExtendedTlv extTlv;
    uint16_t    headerSize;

    SuccessOrExit(error = aMessage.Read(aOffset, tlv));

    if (!tlv.IsExtended())
    {
        mType      = tlv.GetType();
        mLength    = tlv.GetLength();
        headerSize = sizeof(Tlv);
    }
    else
    {
        SuccessOrExit(error = aMessage.Read(aOffset, extTlv));

        mType      = extTlv.GetType();
        mLength    = extTlv.GetLength();
        headerSize = sizeof(ExtendedTlv);
    }

    // We know that we could successfully read `tlv` or `extTlv`
    // (`headerSize` bytes) from the message, so the calculation of the
    // remaining length as `aMessage.GetLength() - aOffset - headerSize`
    // cannot underflow.

    VerifyOrExit(mLength <= aMessage.GetLength() - aOffset - headerSize, error = kErrorParse);

    // Now that we know the entire TLV is contained within the
    // `aMessage`, we can safely calculate `mValueOffset` and `mSize`
    // as `uint16_t` and know that there will be no overflow.

    mType        = tlv.GetType();
    mOffset      = aOffset;
    mValueOffset = aOffset + headerSize;
    mSize        = mLength + headerSize;

exit:
    return error;
}

Error Tlv::ParsedInfo::FindIn(const Message &aMessage, uint8_t aType)
{
    // This  method searches within `aMessage` starting from
    // `aMessage.GetOffset()` for a TLV type `aType` and parsed its
    // info and validates that the entire TLV can be read from
    // `aMessage`. Returns `kErrorNone` when found, otherwise
    // `kErrorNotFound`.

    Error    error  = kErrorNotFound;
    uint16_t offset = aMessage.GetOffset();

    while (true)
    {
        SuccessOrExit(ParseFrom(aMessage, offset));

        if (mType == aType)
        {
            error = kErrorNone;
            ExitNow();
        }

        // `ParseFrom()` already validated that `offset + mSize` is
        // less than `aMessage.GetLength()` and therefore we can not
        // have an overflow here.

        offset += mSize;
    }

exit:
    return error;
}

Error Tlv::ReadStringTlv(const Message &aMessage, uint16_t aOffset, uint8_t aMaxStringLength, char *aValue)
{
    Error      error = kErrorNone;
    ParsedInfo info;
    uint16_t   length;

    SuccessOrExit(error = info.ParseFrom(aMessage, aOffset));

    length = Min(info.mLength, static_cast<uint16_t>(aMaxStringLength));

    aMessage.ReadBytes(info.mValueOffset, aValue, length);
    aValue[length] = '\0';

exit:
    return error;
}

template <typename UintType> Error Tlv::ReadUintTlv(const Message &aMessage, uint16_t aOffset, UintType &aValue)
{
    Error error;

    SuccessOrExit(error = ReadTlvValue(aMessage, aOffset, &aValue, sizeof(aValue)));
    aValue = Encoding::BigEndian::HostSwap<UintType>(aValue);

exit:
    return error;
}

// Explicit instantiations of `ReadUintTlv<>()`
template Error Tlv::ReadUintTlv<uint8_t>(const Message &aMessage, uint16_t aOffset, uint8_t &aValue);
template Error Tlv::ReadUintTlv<uint16_t>(const Message &aMessage, uint16_t aOffset, uint16_t &aValue);
template Error Tlv::ReadUintTlv<uint32_t>(const Message &aMessage, uint16_t aOffset, uint32_t &aValue);

Error Tlv::ReadTlvValue(const Message &aMessage, uint16_t aOffset, void *aValue, uint8_t aMinLength)
{
    Error      error;
    ParsedInfo info;

    SuccessOrExit(error = info.ParseFrom(aMessage, aOffset));

    VerifyOrExit(info.mLength >= aMinLength, error = kErrorParse);

    aMessage.ReadBytes(info.mValueOffset, aValue, aMinLength);

exit:
    return error;
}

Error Tlv::FindStringTlv(const Message &aMessage, uint8_t aType, uint8_t aMaxStringLength, char *aValue)
{
    Error      error;
    ParsedInfo info;

    SuccessOrExit(error = info.FindIn(aMessage, aType));
    error = ReadStringTlv(aMessage, info.mOffset, aMaxStringLength, aValue);

exit:
    return error;
}

template <typename UintType> Error Tlv::FindUintTlv(const Message &aMessage, uint8_t aType, UintType &aValue)
{
    Error      error;
    ParsedInfo info;

    SuccessOrExit(error = info.FindIn(aMessage, aType));
    error = ReadUintTlv<UintType>(aMessage, info.mOffset, aValue);

exit:
    return error;
}

// Explicit instantiations of `FindUintTlv<>()`
template Error Tlv::FindUintTlv<uint8_t>(const Message &aMessage, uint8_t aType, uint8_t &aValue);
template Error Tlv::FindUintTlv<uint16_t>(const Message &aMessage, uint8_t aType, uint16_t &aValue);
template Error Tlv::FindUintTlv<uint32_t>(const Message &aMessage, uint8_t aType, uint32_t &aValue);

Error Tlv::FindTlv(const Message &aMessage, uint8_t aType, void *aValue, uint8_t aLength)
{
    Error    error;
    uint16_t offset;
    uint16_t length;

    SuccessOrExit(error = FindTlvValueOffset(aMessage, aType, offset, length));
    VerifyOrExit(length >= aLength, error = kErrorParse);
    aMessage.ReadBytes(offset, aValue, aLength);

exit:
    return error;
}

Error Tlv::AppendStringTlv(Message &aMessage, uint8_t aType, uint8_t aMaxStringLength, const char *aValue)
{
    uint16_t length = (aValue == nullptr) ? 0 : StringLength(aValue, aMaxStringLength);

    return AppendTlv(aMessage, aType, aValue, static_cast<uint8_t>(length));
}

template <typename UintType> Error Tlv::AppendUintTlv(Message &aMessage, uint8_t aType, UintType aValue)
{
    UintType value = Encoding::BigEndian::HostSwap<UintType>(aValue);

    return AppendTlv(aMessage, aType, &value, sizeof(UintType));
}

// Explicit instantiations of `AppendUintTlv<>()`
template Error Tlv::AppendUintTlv<uint8_t>(Message &aMessage, uint8_t aType, uint8_t aValue);
template Error Tlv::AppendUintTlv<uint16_t>(Message &aMessage, uint8_t aType, uint16_t aValue);
template Error Tlv::AppendUintTlv<uint32_t>(Message &aMessage, uint8_t aType, uint32_t aValue);

Error Tlv::AppendTlv(Message &aMessage, uint8_t aType, const void *aValue, uint8_t aLength)
{
    Error error = kErrorNone;
    Tlv   tlv;

    OT_ASSERT(aLength <= Tlv::kBaseTlvMaxLength);

    tlv.SetType(aType);
    tlv.SetLength(aLength);
    SuccessOrExit(error = aMessage.Append(tlv));

    VerifyOrExit(aLength > 0);
    error = aMessage.AppendBytes(aValue, aLength);

exit:
    return error;
}

} // namespace ot
