/*
 *  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 includes definitions for generating and processing Thread Network Data TLVs.
 */

#ifndef NETWORK_DATA_TLVS_HPP_
#define NETWORK_DATA_TLVS_HPP_

#include "openthread-core-config.h"

#include <openthread/netdata.h>

#include "common/const_cast.hpp"
#include "common/debug.hpp"
#include "common/encoding.hpp"
#include "common/equatable.hpp"
#include "net/ip6_address.hpp"
#include "thread/network_data_types.hpp"

namespace ot {
namespace NetworkData {

using ot::Encoding::BigEndian::HostSwap16;
using ot::Encoding::BigEndian::HostSwap32;

/**
 * @addtogroup core-netdata-tlvs
 *
 * @brief
 *   This module includes definitions for generating and processing Thread Network Data TLVs.
 *
 * @{
 *
 */

class NetworkDataTlv;

/**
 * Casts a `NetworkDataTlv` pointer to a given subclass `TlvType` pointer.
 *
 * @tparam TlvType  The TLV type to cast into. MUST be a subclass of `NetworkDataTlv`.
 *
 * @param[in] aTlv   A pointer to a `NetworkDataTlv` to convert/cast to a `TlvType`.
 *
 * @returns A `TlvType` pointer to `aTlv`.
 *
 */
template <class TlvType> TlvType *As(NetworkDataTlv *aTlv) { return static_cast<TlvType *>(aTlv); }

/**
 * Casts a `NetworkDataTlv` pointer to a given subclass `TlvType` pointer.
 *
 * @tparam TlvType  The TLV type to cast into. MUST be a subclass of `NetworkDataTlv`.
 *
 * @param[in] aTlv   A pointer to a `NetworkDataTlv` to convert/cast to a `TlvType`.
 *
 * @returns A `TlvType` pointer to `aTlv`.
 *
 */
template <class TlvType> const TlvType *As(const NetworkDataTlv *aTlv) { return static_cast<const TlvType *>(aTlv); }

/**
 * Casts a `NetworkDataTlv` reference to a given subclass `TlvType` reference.
 *
 * @tparam TlvType  The TLV type to cast into. MUST be a subclass of `NetworkDataTlv`.
 *
 * @param[in] aTlv   A reference to a `NetworkDataTlv` to convert/cast to a `TlvType`.
 *
 * @returns A `TlvType` reference to `aTlv`.
 *
 */
template <class TlvType> TlvType &As(NetworkDataTlv &aTlv) { return static_cast<TlvType &>(aTlv); }

/**
 * Casts a `NetworkDataTlv` reference to a given subclass `TlvType` reference.
 *
 * @tparam TlvType  The TLV type to cast into. MUST be a subclass of `NetworkDataTlv`.
 *
 * @param[in] aTlv   A reference to a `NetworkDataTlv` to convert/cast to a `TlvType`.
 *
 * @returns A `TlvType` reference to `aTlv`.
 *
 */
template <class TlvType> const TlvType &As(const NetworkDataTlv &aTlv) { return static_cast<const TlvType &>(aTlv); }

/**
 * Implements Thread Network Data TLV generation and parsing.
 *
 */
OT_TOOL_PACKED_BEGIN
class NetworkDataTlv
{
public:
    /**
     * Thread Network Data Type values.
     *
     */
    enum Type : uint8_t
    {
        kTypeHasRoute          = 0, ///< Has Route TLV
        kTypePrefix            = 1, ///< Prefix TLV
        kTypeBorderRouter      = 2, ///< Border Router TLV
        kTypeContext           = 3, ///< Context TLV
        kTypeCommissioningData = 4, ///< Commissioning Dataset TLV
        kTypeService           = 5, ///< Service TLV
        kTypeServer            = 6, ///< Server TLV
    };

    /**
     * Initializes the TLV.
     *
     */
    void Init(void)
    {
        mType   = 0;
        mLength = 0;
    }

    /**
     * Returns the Type value.
     *
     * @returns The Type value.
     *
     */
    Type GetType(void) const { return static_cast<Type>(mType >> kTypeOffset); }

    /**
     * Sets the Type value.
     *
     * @param[in]  aType  The Type value.
     *
     */
    void SetType(Type aType) { mType = (mType & ~kTypeMask) | ((aType << kTypeOffset) & kTypeMask); }

    /**
     * Returns the Length value.
     *
     * @returns The Length value.
     *
     */
    uint8_t GetLength(void) const { return mLength; }

    /**
     * Sets the Length value.
     *
     * @param[in]  aLength  The Length value.
     *
     */
    void SetLength(uint8_t aLength) { mLength = aLength; }

    /**
     * Increases the Length value by a given amount.
     *
     * @param[in]  aIncrement  The increment amount to increase the length.
     *
     */
    void IncreaseLength(uint8_t aIncrement) { mLength += aIncrement; }

    /**
     * Decreases the Length value by a given amount.
     *
     * @param[in]  aDecrement  The decrement amount to decrease the length.
     *
     */
    void DecreaseLength(uint8_t aDecrement) { mLength -= aDecrement; }

    /**
     * Returns the TLV's total size (number of bytes) including Type, Length, and Value fields.
     *
     * @returns The total size include Type, Length, and Value fields.
     *
     */
    uint8_t GetSize(void) const { return sizeof(NetworkDataTlv) + mLength; }

    /**
     * Returns a pointer to the Value.
     *
     * @returns A pointer to the value.
     *
     */
    uint8_t *GetValue(void) { return reinterpret_cast<uint8_t *>(this) + sizeof(NetworkDataTlv); }

    /**
     * Returns a pointer to the Value.
     *
     * @returns A pointer to the value.
     *
     */
    const uint8_t *GetValue(void) const { return reinterpret_cast<const uint8_t *>(this) + sizeof(NetworkDataTlv); }

    /**
     * Returns a pointer to the next Network Data TLV.
     *
     * @returns A pointer to the next Network Data TLV.
     *
     */
    NetworkDataTlv *GetNext(void)
    {
        return reinterpret_cast<NetworkDataTlv *>(reinterpret_cast<uint8_t *>(this) + sizeof(*this) + mLength);
    }

    /**
     * Returns a pointer to the next Network Data TLV.
     *
     * @returns A pointer to the next Network Data TLV.
     *
     */
    const NetworkDataTlv *GetNext(void) const
    {
        return reinterpret_cast<const NetworkDataTlv *>(reinterpret_cast<const uint8_t *>(this) + sizeof(*this) +
                                                        mLength);
    }

    /**
     * Clears the Stable bit.
     *
     */
    void ClearStable(void) { mType &= ~kStableMask; }

    /**
     * Indicates whether or not the Stable bit is set.
     *
     * @retval TRUE   If the Stable bit is set.
     * @retval FALSE  If the Stable bit is not set.
     *
     */
    bool IsStable(void) const { return (mType & kStableMask); }

    /**
     * Sets the Stable bit.
     *
     */
    void SetStable(void) { mType |= kStableMask; }

    /**
     * Searches in a given sequence of TLVs to find the first TLV with a given type.
     *
     * @param[in]  aStart  A pointer to the start of the sequence of TLVs to search within.
     * @param[in]  aEnd    A pointer to the end of the sequence of TLVs.
     * @param[in]  aType   The TLV type to find.
     *
     * @returns A pointer to the TLV if found, or `nullptr` if not found.
     *
     */
    static NetworkDataTlv *Find(NetworkDataTlv *aStart, NetworkDataTlv *aEnd, Type aType)
    {
        return AsNonConst(Find(AsConst(aStart), AsConst(aEnd), aType));
    }

    /**
     * Searches in a given sequence of TLVs to find the first TLV with a given type.
     *
     * @param[in]  aStart  A pointer to the start of the sequence of TLVs to search within.
     * @param[in]  aEnd    A pointer to the end of the sequence of TLVs.
     * @param[in]  aType   The TLV type to find.
     *
     * @returns A pointer to the TLV if found, or `nullptr` if not found.
     *
     */
    static const NetworkDataTlv *Find(const NetworkDataTlv *aStart, const NetworkDataTlv *aEnd, Type aType);

    /**
     * This template static method searches in a given sequence of TLVs to find the first TLV with a given type.
     *
     * @tparam     TlvType The TLV type to search for (MUST be a sub-class of `NetworkDataTlv`).
     *
     * @param[in]  aStart  A pointer to the start of the sequence of TLVs to search within.
     * @param[in]  aEnd    A pointer to the end of the sequence of TLVs.
     *
     * @returns A pointer to the TLV if found, or `nullptr` if not found.
     *
     */
    template <typename TlvType> static TlvType *Find(NetworkDataTlv *aStart, NetworkDataTlv *aEnd)
    {
        return As<TlvType>(Find(aStart, aEnd, TlvType::kType));
    }

    /**
     * This template static method searches in a given sequence of TLVs to find the first TLV with a given type.
     *
     * @tparam     TlvType The TLV type to search for (MUST be a sub-class of `NetworkDataTlv`).
     *
     * @param[in]  aStart  A pointer to the start of the sequence of TLVs to search within.
     * @param[in]  aEnd    A pointer to the end of the sequence of TLVs.
     *
     * @returns A pointer to the TLV if found, or `nullptr` if not found.
     *
     */
    template <typename TlvType> static const TlvType *Find(const NetworkDataTlv *aStart, const NetworkDataTlv *aEnd)
    {
        return As<TlvType>(Find(aStart, aEnd, TlvType::kType));
    }

    /**
     * Searches in a given sequence of TLVs to find the first TLV with a given TLV type and stable
     * flag.
     *
     * @param[in]  aStart  A pointer to the start of the sequence of TLVs to search within.
     * @param[in]  aEnd    A pointer to the end of the sequence of TLVs.
     * @param[in]  aType   The TLV type to find.
     * @param[in]  aStable TRUE to find a stable TLV, FALSE to find a TLV not marked as stable.
     *
     * @returns A pointer to the TLV if found, or `nullptr` if not found.
     *
     */
    static NetworkDataTlv *Find(NetworkDataTlv *aStart, NetworkDataTlv *aEnd, Type aType, bool aStable)
    {
        return AsNonConst(Find(AsConst(aStart), AsConst(aEnd), aType, aStable));
    }

    /**
     * Searches in a given sequence of TLVs to find the first TLV with a given TLV type and stable
     * flag.
     *
     * @param[in]  aStart  A pointer to the start of the sequence of TLVs to search within.
     * @param[in]  aEnd    A pointer to the end of the sequence of TLVs.
     * @param[in]  aType   The TLV type to find.
     * @param[in]  aStable TRUE to find a stable TLV, FALSE to find a TLV not marked as stable.
     *
     * @returns A pointer to the TLV if found, or `nullptr` if not found.
     *
     */
    static const NetworkDataTlv *Find(const NetworkDataTlv *aStart,
                                      const NetworkDataTlv *aEnd,
                                      Type                  aType,
                                      bool                  aStable);

    /**
     * This template static method searches in a given sequence of TLVs to find the first TLV with a given TLV type and
     * stable flag.
     *
     * @tparam     TlvType The TLV type to search for (MUST be a sub-class of `NetworkDataTlv`).
     *
     * @param[in]  aStart  A pointer to the start of the sequence of TLVs to search within.
     * @param[in]  aEnd    A pointer to the end of the sequence of TLVs.
     * @param[in]  aStable TRUE to find a stable TLV, FALSE to find a TLV not marked as stable.
     *
     * @returns A pointer to the TLV if found, or `nullptr` if not found.
     *
     */
    template <typename TlvType> static TlvType *Find(NetworkDataTlv *aStart, NetworkDataTlv *aEnd, bool aStable)
    {
        return As<TlvType>(Find(aStart, aEnd, TlvType::kType, aStable));
    }

    /**
     * This template static method searches in a given sequence of TLVs to find the first TLV with a given TLV type and
     * stable flag.
     *
     * @tparam     TlvType The TLV type to search for (MUST be a sub-class of `NetworkDataTlv`).
     *
     * @param[in]  aStart  A pointer to the start of the sequence of TLVs to search within.
     * @param[in]  aEnd    A pointer to the end of the sequence of TLVs.
     * @param[in]  aStable TRUE to find a stable TLV, FALSE to find a TLV not marked as stable.
     *
     * @returns A pointer to the TLV if found, or `nullptr` if not found.
     *
     */
    template <typename TlvType>
    static const TlvType *Find(const NetworkDataTlv *aStart, const NetworkDataTlv *aEnd, bool aStable)
    {
        return As<TlvType>(Find(aStart, aEnd, TlvType::kType, aStable));
    }

private:
    static constexpr uint8_t kTypeOffset = 1;
    static constexpr uint8_t kTypeMask   = 0x7f << kTypeOffset;
    static constexpr uint8_t kStableMask = 1 << 0;

    uint8_t mType;
    uint8_t mLength;
} OT_TOOL_PACKED_END;

/**
 * Implements Has Route TLV entry generation and parsing.
 *
 */
OT_TOOL_PACKED_BEGIN
class HasRouteEntry : public Equatable<HasRouteEntry>
{
    friend class ExternalRouteConfig;

public:
    /**
     * Initializes the header.
     *
     */
    void Init(void)
    {
        SetRloc(Mac::kShortAddrInvalid);
        mFlags = 0;
    }

    /**
     * Returns the RLOC16 value.
     *
     * @returns The RLOC16 value.
     */
    uint16_t GetRloc(void) const { return HostSwap16(mRloc); }

    /**
     * Sets the RLOC16 value.
     *
     * @param[in]  aRloc16  The RLOC16 value.
     *
     */
    void SetRloc(uint16_t aRloc16) { mRloc = HostSwap16(aRloc16); }

    /**
     * Returns the Preference value.
     *
     * @returns The preference value.
     *
     */
    int8_t GetPreference(void) const { return PreferenceFromFlags(GetFlags()); }

    /**
     * Gets the Flags value.
     *
     * @returns The Flags value.
     *
     */
    uint8_t GetFlags(void) const { return mFlags; }

    /**
     * Sets the Flags value.
     *
     * @param[in]  aFlags  The Flags value.
     *
     */
    void SetFlags(uint8_t aFlags) { mFlags = aFlags; }

    /**
     * Indicates whether or not the NAT64 flag is set.
     *
     * @retval TRUE   If the NAT64 flag is set.
     * @retval FALSE  If the NAT64 flag is not set.
     *
     */
    bool IsNat64(void) const { return (mFlags & kNat64Flag) != 0; }

    /**
     * Indicates whether or not the Advertising PIO (AP) flag is set.
     *
     * @retval TRUE   If the AP flag is set.
     * @retval FALSE  If the AP flag is not set.
     *
     */
    bool IsAdvPio(void) const { return (mFlags & kAdvPioFlag) != 0; }

    /**
     * Returns a pointer to the next HasRouteEntry.
     *
     * @returns A pointer to the next HasRouteEntry.
     *
     */
    HasRouteEntry *GetNext(void) { return (this + 1); }

    /**
     * Returns a pointer to the next HasRouteEntry.
     *
     * @returns A pointer to the next HasRouteEntry.
     *
     */
    const HasRouteEntry *GetNext(void) const { return (this + 1); }

    /**
     * Returns an updated flags bitmask by removing the preference bits (sets them to zero) from a
     * given flags bitmask.
     *
     * @param[in] aFlags  The flags bitmask.
     *
     * @returns An updated version @p aFlags with preference bits cleared.
     *
     */
    static uint8_t FlagsWithoutPreference(uint8_t aFlags) { return (aFlags & ~kPreferenceMask); }

    /**
     * Gets the preference field from a flags bitmask.
     *
     * @param[in] aFlags  The flags.
     *
     * @returns The preference field from the @p aFlags.
     *
     */
    static int8_t PreferenceFromFlags(uint8_t aFlags) { return RoutePreferenceFromValue(aFlags >> kPreferenceOffset); }

private:
    static constexpr uint8_t kPreferenceOffset = 6;
    static constexpr uint8_t kPreferenceMask   = 3 << kPreferenceOffset;
    static constexpr uint8_t kNat64Flag        = 1 << 5;
    static constexpr uint8_t kAdvPioFlag       = 1 << 4;

    uint16_t mRloc;
    uint8_t  mFlags;
} OT_TOOL_PACKED_END;

/**
 * Implements Has Route TLV generation and parsing.
 *
 */
OT_TOOL_PACKED_BEGIN
class HasRouteTlv : public NetworkDataTlv
{
public:
    static constexpr Type kType = kTypeHasRoute; ///< The TLV Type.

    /**
     * Initializes the TLV.
     *
     */
    void Init(void)
    {
        NetworkDataTlv::Init();
        SetType(kTypeHasRoute);
        SetLength(0);
    }

    /**
     * Returns the number of HasRoute entries.
     *
     * @returns The number of HasRoute entries.
     *
     */
    uint8_t GetNumEntries(void) const { return GetLength() / sizeof(HasRouteEntry); }

    /**
     * Returns a pointer to the HasRoute entry at a given index.
     *
     * @param[in]  aIndex  An index.
     *
     * @returns A pointer to the HasRoute entry at @p aIndex.
     *
     */
    HasRouteEntry *GetEntry(uint8_t aIndex)
    {
        return reinterpret_cast<HasRouteEntry *>(GetValue() + (aIndex * sizeof(HasRouteEntry)));
    }

    /**
     * Returns a pointer to the HasRoute entry at a given index.
     *
     * @param[in]  aIndex  An index.
     *
     * @returns A pointer to the HasRoute entry at @p aIndex.
     *
     */
    const HasRouteEntry *GetEntry(uint8_t aIndex) const
    {
        return reinterpret_cast<const HasRouteEntry *>(GetValue() + (aIndex * sizeof(HasRouteEntry)));
    }

    /**
     * Returns a pointer to the first HasRouteEntry (at index 0'th).
     *
     * @returns A pointer to the first HasRouteEntry.
     *
     */
    HasRouteEntry *GetFirstEntry(void) { return reinterpret_cast<HasRouteEntry *>(GetValue()); }

    /**
     * Returns a pointer to the first HasRouteEntry (at index 0'th).
     *
     * @returns A pointer to the first HasRouteEntry.
     *
     */
    const HasRouteEntry *GetFirstEntry(void) const { return reinterpret_cast<const HasRouteEntry *>(GetValue()); }

    /**
     * Returns a pointer to the last HasRouteEntry.
     *
     * If there are no entries the pointer will be invalid but guaranteed to be before the `GetFirstEntry()` pointer.
     *
     * @returns A pointer to the last HasRouteEntry.
     *
     */
    HasRouteEntry *GetLastEntry(void)
    {
        return reinterpret_cast<HasRouteEntry *>(GetValue() + GetLength() - sizeof(HasRouteEntry));
    }

    /**
     * Returns a pointer to the last HasRouteEntry.
     *
     * If there are no entries the pointer will be invalid but guaranteed to be before the `GetFirstEntry()` pointer.
     *
     * @returns A pointer to the last HasRouteEntry.
     *
     */
    const HasRouteEntry *GetLastEntry(void) const
    {
        return reinterpret_cast<const HasRouteEntry *>(GetValue() + GetLength() - sizeof(HasRouteEntry));
    }

} OT_TOOL_PACKED_END;

/**
 * Implements Prefix TLV generation and parsing.
 *
 */
OT_TOOL_PACKED_BEGIN
class PrefixTlv : public NetworkDataTlv
{
public:
    static constexpr Type kType = kTypePrefix; ///< The TLV Type.

    /**
     * Initializes the TLV.
     *
     * @param[in]  aDomainId      The Domain ID.
     * @param[in]  aPrefixLength  The Prefix Length in bits.
     * @param[in]  aPrefix        A pointer to the prefix.
     *
     */
    void Init(uint8_t aDomainId, uint8_t aPrefixLength, const uint8_t *aPrefix)
    {
        NetworkDataTlv::Init();
        SetType(kTypePrefix);
        mDomainId     = aDomainId;
        mPrefixLength = aPrefixLength;
        memcpy(GetPrefix(), aPrefix, Ip6::Prefix::SizeForLength(aPrefixLength));
        SetSubTlvsLength(0);
    }

    /**
     * Initializes the TLV.
     *
     * @param[in]  aDomainId      The Domain ID.
     * @param[in]  aPrefix        The Prefix.
     *
     */
    void Init(uint8_t aDomainId, const Ip6::Prefix aPrefix)
    {
        Init(aDomainId, aPrefix.GetLength(), aPrefix.GetBytes());
    }

    /**
     * Indicates whether or not the TLV appears to be well-formed.
     *
     * @retval TRUE   If the TLV appears to be well-formed.
     * @retval FALSE  If the TLV does not appear to be well-formed.
     *
     */
    bool IsValid(void) const
    {
        return ((GetLength() >= sizeof(*this) - sizeof(NetworkDataTlv)) &&
                (GetLength() >= Ip6::Prefix::SizeForLength(mPrefixLength) + sizeof(*this) - sizeof(NetworkDataTlv)) &&
                (Ip6::Prefix::SizeForLength(mPrefixLength) <= sizeof(Ip6::Address)));
    }

    /**
     * Returns the Domain ID value.
     *
     * @returns The Domain ID value.
     *
     */
    uint8_t GetDomainId(void) const { return mDomainId; }

    /**
     * Returns the Prefix Length value.
     *
     * @returns The Prefix Length value (in bits).
     *
     */
    uint8_t GetPrefixLength(void) const { return mPrefixLength; }

    /**
     * Returns a pointer to the Prefix.
     *
     * @returns A pointer to the Prefix.
     *
     */
    uint8_t *GetPrefix(void) { return reinterpret_cast<uint8_t *>(this) + sizeof(*this); }

    /**
     * Returns a pointer to the Prefix.
     *
     * @returns A pointer to the Prefix.
     *
     */
    const uint8_t *GetPrefix(void) const { return reinterpret_cast<const uint8_t *>(this) + sizeof(*this); }

    /**
     * Copies the Prefix from TLV into a given `Ip6::Prefix`.
     *
     * @param[out] aPrefix  An `Ip6::Prefix` to copy the Prefix from TLV into.
     *
     */
    void CopyPrefixTo(Ip6::Prefix &aPrefix) const { aPrefix.Set(GetPrefix(), GetPrefixLength()); }

    /**
     * Indicates whether the Prefix from TLV is equal to a given `Ip6::Prefix`.
     *
     * @param[in] aPrefix  A Prefix to compare with.
     *
     * @retval TRUE   The TLV's Prefix is equal to @p aPrefix.
     * @retval FALSE  The TLV's Prefix is not equal to @p aPrefix.
     *
     */
    bool IsEqual(Ip6::Prefix &aPrefix) const { return aPrefix.IsEqual(GetPrefix(), GetPrefixLength()); }

    /**
     * Indicates whether the Prefix from TLV is equal to a given Prefix.
     *
     * @param[in]  aPrefix        A pointer to an IPv6 prefix to compare with.
     * @param[in]  aPrefixLength  The prefix length pointed to by @p aPrefix (in bits).
     *
     * @retval TRUE   The TLV's Prefix is equal to @p aPrefix.
     * @retval FALSE  The TLV's Prefix is not equal @p aPrefix.
     *
     */
    bool IsEqual(const uint8_t *aPrefix, uint8_t aPrefixLength) const
    {
        return (aPrefixLength == mPrefixLength) &&
               (Ip6::Prefix::MatchLength(GetPrefix(), aPrefix, Ip6::Prefix::SizeForLength(aPrefixLength)) >=
                mPrefixLength);
    }

    /**
     * Returns a pointer to the Sub-TLVs.
     *
     * @returns A pointer to the Sub-TLVs.
     *
     */
    NetworkDataTlv *GetSubTlvs(void)
    {
        return reinterpret_cast<NetworkDataTlv *>(GetPrefix() + Ip6::Prefix::SizeForLength(mPrefixLength));
    }

    /**
     * Returns a pointer to the Sub-TLVs.
     *
     * @returns A pointer to the Sub-TLVs.
     *
     */
    const NetworkDataTlv *GetSubTlvs(void) const
    {
        return reinterpret_cast<const NetworkDataTlv *>(GetPrefix() + Ip6::Prefix::SizeForLength(mPrefixLength));
    }

    /**
     * Returns the Sub-TLVs length in bytes.
     *
     * @returns The Sub-TLVs length in bytes.
     *
     */
    uint8_t GetSubTlvsLength(void) const
    {
        return GetLength() - (sizeof(*this) - sizeof(NetworkDataTlv) + Ip6::Prefix::SizeForLength(mPrefixLength));
    }

    /**
     * Sets the Sub-TLVs length in bytes.
     *
     * @param[in]  aLength  The Sub-TLVs length in bytes.
     *
     */
    void SetSubTlvsLength(uint8_t aLength)
    {
        SetLength(sizeof(*this) - sizeof(NetworkDataTlv) + Ip6::Prefix::SizeForLength(mPrefixLength) + aLength);
    }

    /**
     * Searches in the sub-TLVs to find the first one matching a given TLV type.
     *
     * @tparam     SubTlvType    The sub-TLV type to search for (MUST be a sub-class of `NetworkDataTlv`).
     *
     * @returns A pointer to the TLV if found, or `nullptr` if not found.
     *
     */
    template <typename SubTlvType> SubTlvType *FindSubTlv(void)
    {
        return As<SubTlvType>(FindSubTlv(SubTlvType::kType));
    }

    /**
     * Searches in the sub-TLVs to find the first one matching a given TLV Type.
     *
     * @tparam     SubTlvType   The sub-TLV type to search for (MUST be a sub-class of `NetworkDataTlv`).
     *
     * @returns A pointer to the TLV if found, or `nullptr` if not found.
     *
     */
    template <typename SubTlvType> const SubTlvType *FindSubTlv(void) const
    {
        return As<SubTlvType>(FindSubTlv(SubTlvType::kType));
    }

    /**
     * Searches in the sub-TLVs to find the first one matching a given TLV type and stable flag.
     *
     * @tparam     SubTlvType    The sub-TLV type to search for (MUST be a sub-class of `NetworkDataTlv`).
     *
     * @param[in]  aStable       TRUE to find a stable TLV, FALSE to find a TLV not marked as stable.
     *
     * @returns A pointer to the TLV if found, or `nullptr` if not found.
     *
     */
    template <typename SubTlvType> SubTlvType *FindSubTlv(bool aStable)
    {
        return As<SubTlvType>(FindSubTlv(static_cast<Type>(SubTlvType::kType), aStable));
    }

    /**
     * Searches in the sub-TLVs to find the first one matching a given TLV type and stable flag.
     *
     * @tparam     SubTlvType   The sub-TLV type to search for (MUST be a sub-class of `NetworkDataTlv`).
     *
     * @param[in]  aStable      TRUE to find a stable TLV, FALSE to find a TLV not marked as stable.
     *
     * @returns A pointer to the TLV if found, or `nullptr` if not found.
     *
     */
    template <typename SubTlvType> const SubTlvType *FindSubTlv(bool aStable) const
    {
        return As<SubTlvType>(FindSubTlv(static_cast<Type>(SubTlvType::kType), aStable));
    }

    /**
     * Searches in the sub-TLVs to find the first one matching a given TLV type.
     *
     * @param[in]  aType        The sub-TLV type to search for.
     *
     * @returns A pointer to the TLV if found, or `nullptr` if not found.
     *
     */
    NetworkDataTlv *FindSubTlv(Type aType) { return AsNonConst(AsConst(this)->FindSubTlv(aType)); }

    /**
     * Searches in the sub-TLVs to find the first one matching a given TLV type.
     *
     * @param[in]  aType        The sub-TLV type to search for.
     *
     * @returns A pointer to the TLV if found, or `nullptr` if not found.
     *
     */
    const NetworkDataTlv *FindSubTlv(Type aType) const;

    /**
     * Searches in the sub-TLVs to find the first one matching a given TLV type and stable flag.
     *
     * @param[in]  aType        The sub-TLV type to search for.
     * @param[in]  aStable      TRUE to find a stable TLV, FALSE to find a TLV not marked as stable.
     *
     * @returns A pointer to the TLV if found, or `nullptr` if not found.
     *
     */
    NetworkDataTlv *FindSubTlv(Type aType, bool aStable)
    {
        return AsNonConst(AsConst(this)->FindSubTlv(aType, aStable));
    }

    /**
     * Searches in the sub-TLVs to find the first one matching a given TLV type and stable flag.
     *
     * @param[in]  aType        The sub-TLV type to search for.
     * @param[in]  aStable      TRUE to find a stable TLV, FALSE to find a TLV not marked as stable.
     *
     * @returns A pointer to the TLV if found, or `nullptr` if not found.
     *
     */
    const NetworkDataTlv *FindSubTlv(Type aType, bool aStable) const;

    /**
     * Calculates the total size (number of bytes) of a Prefix TLV with a given Prefix Length value.
     *
     * Note that the returned size does include the Type and Length fields in the TLV, but does not account for any
     * sub TLVs of the Prefix TLV.
     *
     * @param[in]  aPrefixLength     A Prefix Length in bits.

     * @returns    The size (number of bytes) of the Prefix TLV.
     *
     */
    static uint16_t CalculateSize(uint8_t aPrefixLength)
    {
        return sizeof(PrefixTlv) + Ip6::Prefix::SizeForLength(aPrefixLength);
    }

private:
    uint8_t mDomainId;
    uint8_t mPrefixLength;
} OT_TOOL_PACKED_END;

/**
 * Implements Border Router Entry generation and parsing.
 *
 */
OT_TOOL_PACKED_BEGIN
class BorderRouterEntry : public Equatable<BorderRouterEntry>
{
    friend class OnMeshPrefixConfig;

public:
    /**
     * Initializes the TLV.
     *
     */
    void Init(void)
    {
        SetRloc(Mac::kShortAddrInvalid);
        mFlags = 0;
    }

    /**
     * Returns the RLOC16 value.
     *
     * @returns The RLOC16 value.
     */
    uint16_t GetRloc(void) const { return HostSwap16(mRloc); }

    /**
     * Sets the RLOC16 value.
     *
     * @param[in]  aRloc16  The RLOC16 value.
     *
     */
    void SetRloc(uint16_t aRloc16) { mRloc = HostSwap16(aRloc16); }

    /**
     * Returns the Flags value.
     *
     * @returns The Flags value.
     *
     */
    uint16_t GetFlags(void) const { return HostSwap16(mFlags); }

    /**
     * Sets the Flags value.
     *
     * @param[in]  aFlags  The Flags value.
     *
     */
    void SetFlags(uint16_t aFlags) { mFlags = HostSwap16(aFlags); }

    /**
     * Returns the Preference value.
     *
     * @returns the Preference value.
     *
     */
    int8_t GetPreference(void) const { return PreferenceFromFlags(GetFlags()); }

    /**
     * Indicates whether or not the Preferred flag is set.
     *
     * @retval TRUE   If the Preferred flag is set.
     * @retval FALSE  If the Preferred flag is not set.
     *
     */
    bool IsPreferred(void) const { return (HostSwap16(mFlags) & kPreferredFlag) != 0; }

    /**
     * Indicates whether or not the SLAAC flag is set.
     *
     * @retval TRUE   If the SLAAC flag is set.
     * @retval FALSE  If the SLAAC flag is not set.
     *
     */
    bool IsSlaac(void) const { return (HostSwap16(mFlags) & kSlaacFlag) != 0; }

    /**
     * Indicates whether or not the DHCP flag is set.
     *
     * @retval TRUE   If the DHCP flag is set.
     * @retval FALSE  If the DHCP flag is not set.
     *
     */
    bool IsDhcp(void) const { return (HostSwap16(mFlags) & kDhcpFlag) != 0; }

    /**
     * Indicates whether or not the Configure flag is set.
     *
     * @retval TRUE   If the Configure flag is set.
     * @retval FALSE  If the Configure flag is not set.
     *
     */
    bool IsConfigure(void) const { return (HostSwap16(mFlags) & kConfigureFlag) != 0; }

    /**
     * Indicates whether or not the Default Route flag is set.
     *
     * @retval TRUE   If the Default Route flag is set.
     * @retval FALSE  If the Default Route flag is not set.
     *
     */
    bool IsDefaultRoute(void) const { return (HostSwap16(mFlags) & kDefaultRouteFlag) != 0; }

    /**
     * Indicates whether or not the On-Mesh flag is set.
     *
     * @retval TRUE   If the On-Mesh flag is set.
     * @retval FALSE  If the On-Mesh flag is not set.
     *
     */
    bool IsOnMesh(void) const { return (HostSwap16(mFlags) & kOnMeshFlag) != 0; }

    /**
     * Indicates whether or not the Nd-Dns flag is set.
     *
     * @retval TRUE   If the Nd-Dns flag is set.
     * @retval FALSE  If the Nd-Dns flag is not set.
     *
     */
    bool IsNdDns(void) const { return (HostSwap16(mFlags) & kNdDnsFlag) != 0; }

    /**
     * Indicates whether or not the Domain Prefix flag is set.
     *
     * @retval TRUE   If the Domain Prefix flag is set.
     * @retval FALSE  If the Domain Prefix flag is not set.
     *
     */
    bool IsDp(void) const { return (HostSwap16(mFlags) & kDpFlag) != 0; }

    /**
     * Returns a pointer to the next BorderRouterEntry
     *
     * @returns A pointer to the next BorderRouterEntry.
     *
     */
    BorderRouterEntry *GetNext(void) { return (this + 1); }

    /**
     * Returns a pointer to the next BorderRouterEntry
     *
     * @returns A pointer to the next BorderRouterEntry.
     *
     */
    const BorderRouterEntry *GetNext(void) const { return (this + 1); }

    /**
     * Returns an updated flags bitmask by removing the preference bits (sets them to zero) from a
     * given flags bitmask.
     *
     * @param[in] aFlags  The flags bitmask.
     *
     * @returns An updated version @p aFlags with preference bits cleared.
     *
     */
    static uint16_t FlagsWithoutPreference(uint16_t aFlags) { return (aFlags & ~kPreferenceMask); }

    /**
     * Gets the preference field from a flags bitmask.
     *
     * @param[in] aFlags  The flags.
     *
     * @returns The preference field from the @p aFlags.
     *
     */
    static int8_t PreferenceFromFlags(uint16_t aFlags)
    {
        return RoutePreferenceFromValue(static_cast<uint8_t>(aFlags >> kPreferenceOffset));
    }

private:
    static constexpr uint8_t  kPreferenceOffset = 14;
    static constexpr uint16_t kPreferenceMask   = 3 << kPreferenceOffset;
    static constexpr uint16_t kPreferredFlag    = 1 << 13;
    static constexpr uint16_t kSlaacFlag        = 1 << 12;
    static constexpr uint16_t kDhcpFlag         = 1 << 11;
    static constexpr uint16_t kConfigureFlag    = 1 << 10;
    static constexpr uint16_t kDefaultRouteFlag = 1 << 9;
    static constexpr uint16_t kOnMeshFlag       = 1 << 8;
    static constexpr uint16_t kNdDnsFlag        = 1 << 7;
    static constexpr uint16_t kDpFlag           = 1 << 6;

    uint16_t mRloc;
    uint16_t mFlags;
} OT_TOOL_PACKED_END;

/**
 * Implements Border Router TLV generation and parsing.
 *
 */
OT_TOOL_PACKED_BEGIN
class BorderRouterTlv : public NetworkDataTlv
{
public:
    static constexpr Type kType = kTypeBorderRouter; ///< The TLV Type.

    /**
     * Initializes the TLV.
     *
     */
    void Init(void)
    {
        NetworkDataTlv::Init();
        SetType(kTypeBorderRouter);
        SetLength(0);
    }

    /**
     * Returns the number of Border Router entries.
     *
     * @returns The number of Border Router entries.
     *
     */
    uint8_t GetNumEntries(void) const { return GetLength() / sizeof(BorderRouterEntry); }

    /**
     * Returns a pointer to the Border Router entry at a given index
     *
     * @param[in]  aIndex  The index.
     *
     * @returns A pointer to the Border Router entry at @p aIndex.
     *
     */
    BorderRouterEntry *GetEntry(uint8_t aIndex)
    {
        return reinterpret_cast<BorderRouterEntry *>(GetValue() + (aIndex * sizeof(BorderRouterEntry)));
    }

    /**
     * Returns a pointer to the Border Router entry at a given index.
     *
     * @param[in]  aIndex  The index.
     *
     * @returns A pointer to the Border Router entry at @p aIndex
     *
     */
    const BorderRouterEntry *GetEntry(uint8_t aIndex) const
    {
        return reinterpret_cast<const BorderRouterEntry *>(GetValue() + (aIndex * sizeof(BorderRouterEntry)));
    }

    /**
     * Returns a pointer to the first BorderRouterEntry (at index 0'th).
     *
     * @returns A pointer to the first BorderRouterEntry.
     *
     */
    BorderRouterEntry *GetFirstEntry(void) { return reinterpret_cast<BorderRouterEntry *>(GetValue()); }

    /**
     * Returns a pointer to the first BorderRouterEntry (at index 0'th).
     *
     * @returns A pointer to the first BorderRouterEntry.
     *
     */
    const BorderRouterEntry *GetFirstEntry(void) const
    {
        return reinterpret_cast<const BorderRouterEntry *>(GetValue());
    }

    /**
     * Returns a pointer to the last BorderRouterEntry.
     *
     * If there are no entries the pointer will be invalid but guaranteed to be before the `GetFirstEntry()` pointer.
     *
     * @returns A pointer to the last BorderRouterEntry.
     *
     */
    BorderRouterEntry *GetLastEntry(void)
    {
        return reinterpret_cast<BorderRouterEntry *>(GetValue() + GetLength() - sizeof(BorderRouterEntry));
    }

    /**
     * Returns a pointer to the last BorderRouterEntry.
     *
     * If there are no entries the pointer will be invalid but guaranteed to be before the `GetFirstEntry()` pointer.
     *
     * @returns A pointer to the last BorderRouterEntry.
     *
     */
    const BorderRouterEntry *GetLastEntry(void) const
    {
        return reinterpret_cast<const BorderRouterEntry *>(GetValue() + GetLength() - sizeof(BorderRouterEntry));
    }

} OT_TOOL_PACKED_END;

/**
 * Implements Context TLV generation and processing.
 *
 */
OT_TOOL_PACKED_BEGIN
class ContextTlv : public NetworkDataTlv
{
public:
    static constexpr Type kType = kTypeContext; ///< The TLV Type.

    /**
     * Initializes the Context TLV.
     *
     * @param[in]  aContextId      The Context ID value.
     * @param[in]  aContextLength  The Context Length value.
     *
     */
    void Init(uint8_t aContextId, uint8_t aContextLength)
    {
        NetworkDataTlv::Init();
        SetType(kTypeContext);
        SetLength(sizeof(ContextTlv) - sizeof(NetworkDataTlv));
        mFlags         = ((aContextId << kContextIdOffset) & kContextIdMask);
        mContextLength = aContextLength;
    }

    /**
     * Indicates whether or not the Compress flag is set.
     *
     * @retval TRUE   The Compress flag is set.
     * @retval FALSE  The Compress flags is not set.
     *
     */
    bool IsCompress(void) const { return (mFlags & kCompressFlag) != 0; }

    /**
     * Clears the Compress flag.
     *
     */
    void ClearCompress(void) { mFlags &= ~kCompressFlag; }

    /**
     * Sets the Compress flag.
     *
     */
    void SetCompress(void) { mFlags |= kCompressFlag; }

    /**
     * Returns the Context ID value.
     *
     * @returns The Context ID value.
     *
     */
    uint8_t GetContextId(void) const { return mFlags & kContextIdMask; }

    /**
     * Returns the Context Length value.
     *
     * @returns The Context Length value.
     *
     */
    uint8_t GetContextLength(void) const { return mContextLength; }

private:
    static constexpr uint8_t kCompressFlag    = 1 << 4;
    static constexpr uint8_t kContextIdOffset = 0;
    static constexpr uint8_t kContextIdMask   = 0xf << kContextIdOffset;

    uint8_t mFlags;
    uint8_t mContextLength;
} OT_TOOL_PACKED_END;

/**
 * Implements Commissioning Data TLV generation and parsing.
 *
 */
OT_TOOL_PACKED_BEGIN
class CommissioningDataTlv : public NetworkDataTlv
{
public:
    static constexpr Type kType = kTypeCommissioningData; ///< The TLV Type.

    /**
     * Initializes the TLV.
     *
     */
    void Init(void)
    {
        NetworkDataTlv::Init();
        SetType(kTypeCommissioningData);
        SetLength(0);
    }
} OT_TOOL_PACKED_END;

/**
 * Implements Service Data TLV generation and parsing.
 *
 */
OT_TOOL_PACKED_BEGIN
class ServiceTlv : public NetworkDataTlv
{
public:
    static constexpr Type kType = kTypeService; ///< The TLV Type.

    static constexpr uint32_t kThreadEnterpriseNumber = 44970; ///< Thread enterprise number.

    /**
     * Initializes the TLV.
     *
     * @param[in]  aServiceId          The Service Id value.
     * @param[in]  aEnterpriseNumber   The Enterprise Number.
     * @param[in]  aServiceData        The Service Data.
     *
     */
    void Init(uint8_t aServiceId, uint32_t aEnterpriseNumber, const ServiceData &aServiceData);

    /**
     * Indicates whether or not the TLV appears to be well-formed.
     *
     * @retval TRUE   If the TLV appears to be well-formed.
     * @retval FALSE  If the TLV does not appear to be well-formed.
     *
     */
    bool IsValid(void) const
    {
        uint8_t length = GetLength();

        return (length >= sizeof(mFlagsServiceId)) &&
               (length >= kMinLength + (IsThreadEnterprise() ? 0 : sizeof(uint32_t))) &&
               (static_cast<uint16_t>(length) + sizeof(NetworkDataTlv) >=
                CalculateSize(GetEnterpriseNumber(), GetServiceDataLength()));
    }

    /**
     * Returns the Service ID. It is in range 0x00-0x0f.
     *
     * @returns the Service ID.
     *
     */
    uint8_t GetServiceId(void) const { return (mFlagsServiceId & kServiceIdMask); }

    /**
     * Returns Enterprise Number field.
     *
     * @returns The Enterprise Number.
     *
     */
    uint32_t GetEnterpriseNumber(void) const
    {
        return IsThreadEnterprise() ? static_cast<uint32_t>(kThreadEnterpriseNumber)
                                    : HostSwap32(mShared.mEnterpriseNumber);
    }

    /**
     * Gets the Service Data.
     *
     * @param[out] aServiceData   A reference to a`ServiceData` to return the data.
     *
     */
    void GetServiceData(ServiceData &aServiceData) const
    {
        aServiceData.Init(GetServiceData(), GetServiceDataLength());
    }

    /**
     * Gets Service Data length.
     *
     * @returns length of the Service Data field in bytes.
     *
     */
    uint8_t GetServiceDataLength(void) const
    {
        return IsThreadEnterprise() ? mShared.mServiceDataLengthThreadEnterprise : mServiceDataLength;
    }

    /**
     * Returns the Sub-TLVs length in bytes.
     *
     * @returns The Sub-TLVs length in bytes.
     *
     */
    uint8_t GetSubTlvsLength(void) { return GetLength() - GetFieldsLength(); }

    /**
     * Sets the Sub-TLVs length in bytes.
     *
     * @param[in]  aLength  The Sub-TLVs length in bytes.
     *
     */
    void SetSubTlvsLength(uint8_t aLength) { SetLength(GetFieldsLength() + aLength); }

    /**
     * Returns a pointer to the Sub-TLVs.
     *
     * @returns A pointer to the Sub-TLVs.
     *
     */
    NetworkDataTlv *GetSubTlvs(void) { return reinterpret_cast<NetworkDataTlv *>(GetValue() + GetFieldsLength()); }

    /**
     * Returns a pointer to the Sub-TLVs.
     *
     * @returns A pointer to the Sub-TLVs.
     *
     */
    const NetworkDataTlv *GetSubTlvs(void) const
    {
        return reinterpret_cast<const NetworkDataTlv *>(GetValue() + GetFieldsLength());
    }

    /**
     * Calculates the total size (number of bytes) of a Service TLV with a given Enterprise Number
     * and Service Data length.
     *
     * Note that the returned size does include the Type and Length fields in the TLV, but does not account for any
     * sub-TLVs of the Service TLV.
     *
     * @param[in]  aEnterpriseNumber   A Enterprise Number.
     * @param[in]  aServiceDataLength  A Service Data length.
     *
     * @returns    The size (number of bytes) of the Service TLV.
     *
     */
    static uint16_t CalculateSize(uint32_t aEnterpriseNumber, uint8_t aServiceDataLength)
    {
        return sizeof(NetworkDataTlv) + kMinLength + aServiceDataLength +
               ((aEnterpriseNumber == kThreadEnterpriseNumber) ? 0 : sizeof(uint32_t) /* mEnterpriseNumber  */);
    }

private:
    bool IsThreadEnterprise(void) const { return (mFlagsServiceId & kThreadEnterpriseFlag) != 0; }

    const uint8_t *GetServiceData(void) const
    {
        return (IsThreadEnterprise() ? &mShared.mServiceDataLengthThreadEnterprise : &mServiceDataLength) +
               sizeof(uint8_t);
    }

    uint8_t GetFieldsLength(void) const
    {
        // Returns the length of TLV value's common fields (flags, enterprise
        // number and service data) excluding any sub-TLVs.

        return kMinLength + (IsThreadEnterprise() ? 0 : sizeof(uint32_t)) + GetServiceDataLength();
    }

    static constexpr uint8_t kThreadEnterpriseFlag = (1 << 7);
    static constexpr uint8_t kServiceIdMask        = 0xf;
    static constexpr uint8_t kMinLength            = sizeof(uint8_t) + sizeof(uint8_t); // Flags & Service Data length.

    // When `kThreadEnterpriseFlag is set in the `mFlagsServiceId`, the
    // `mEnterpriseNumber` field is elided and `mFlagsServiceId` is
    // immediately followed by the Service Data length field (which is
    // represented by `mServiceDataLengthThreadEnterprise`)

    uint8_t mFlagsServiceId;
    union OT_TOOL_PACKED_FIELD
    {
        uint32_t mEnterpriseNumber;
        uint8_t  mServiceDataLengthThreadEnterprise;
    } mShared;
    uint8_t mServiceDataLength;

} OT_TOOL_PACKED_END;

/**
 * Implements Server Data TLV generation and parsing.
 *
 */
OT_TOOL_PACKED_BEGIN
class ServerTlv : public NetworkDataTlv
{
public:
    static constexpr Type kType = kTypeServer; ///< The TLV Type.

    /**
     * Initializes the Server TLV.
     *
     * @param[in] aServer16          The Server16 value.
     * @param[in] aServerData        The Server Data.
     *
     */
    void Init(uint16_t aServer16, const ServerData &aServerData)
    {
        NetworkDataTlv::Init();
        SetType(kTypeServer);
        SetServer16(aServer16);
        aServerData.CopyBytesTo(GetServerData());
        SetLength(sizeof(*this) - sizeof(NetworkDataTlv) + aServerData.GetLength());
    }

    /**
     * Indicates whether or not the TLV appears to be well-formed.
     *
     * @retval TRUE   If the TLV appears to be well-formed.
     * @retval FALSE  If the TLV does not appear to be well-formed.
     *
     */
    bool IsValid(void) const { return GetLength() >= (sizeof(*this) - sizeof(NetworkDataTlv)); }

    /**
     * Returns the Server16 value.
     *
     * @returns The Server16 value.
     *
     */
    uint16_t GetServer16(void) const { return HostSwap16(mServer16); }

    /*
     * Sets the Server16 value.
     *
     * @param[in]  aServer16  The Server16 value.
     *
     */
    void SetServer16(uint16_t aServer16) { mServer16 = HostSwap16(aServer16); }

    /**
     * Gets the Server Data.
     *
     * @param[out] aServerData   A reference to a`ServerData` to return the data.
     *
     */
    void GetServerData(ServerData &aServerData) const { aServerData.Init(GetServerData(), GetServerDataLength()); }

    /**
     * Returns the Server Data length in bytes.
     *
     * @returns The Server Data length in bytes.
     *
     */
    uint8_t GetServerDataLength(void) const { return GetLength() - (sizeof(*this) - sizeof(NetworkDataTlv)); }

    /**
     * Indicates whether two Server TLVs fully match.
     *
     * @param[in]  aOther  Another Server TLV to compare with it.
     *
     * @retval TRUE  The two TLVs are equal.
     * @retval FALSE The two TLVs are not equal.
     *
     */
    bool operator==(const ServerTlv &aOther) const
    {
        return (GetLength() == aOther.GetLength()) && (memcmp(GetValue(), aOther.GetValue(), GetLength()) == 0);
    }

    /**
     * Calculates the total size (number of bytes) of a Service TLV with a given Server Data length.
     *
     * Note that the returned size does include the Type and Length fields in the TLV.
     *
     * @param[in]  aServerDataLength    Server Data length in bytes.
     *
     * @returns    The size (number of bytes) of the Server TLV.
     *
     */
    static uint16_t CalculateSize(uint8_t aServerDataLength) { return sizeof(ServerTlv) + aServerDataLength; }

private:
    const uint8_t *GetServerData(void) const { return reinterpret_cast<const uint8_t *>(this) + sizeof(*this); }
    uint8_t       *GetServerData(void) { return AsNonConst(AsConst(this)->GetServerData()); }

    uint16_t mServer16;
} OT_TOOL_PACKED_END;

/**
 * Represents a Network Data TLV iterator.
 *
 */
class TlvIterator
{
public:
    /**
     * Initializes the `TlvIterator` to iterate over a given sequence of TLVs.
     *
     * @param[in] aStart  A pointer to the start of the TLV sequence.
     * @param[in] aEnd    A pointer to the end of the TLV sequence.
     *
     */
    TlvIterator(const NetworkDataTlv *aStart, const NetworkDataTlv *aEnd)
        : mStart(aStart)
        , mEnd(aEnd)
    {
    }

    /**
     * Initializes the `TlvIterator` to iterate over TLVs from a given buffer.
     *
     * @param[in] aBuffer   A pointer to a buffer containing the TLVs.
     * @param[in] aLength   The length (number of bytes) of @p aBuffer.
     *
     */
    TlvIterator(const uint8_t *aBuffer, uint8_t aLength)
        : TlvIterator(reinterpret_cast<const NetworkDataTlv *>(aBuffer),
                      reinterpret_cast<const NetworkDataTlv *>(aBuffer + aLength))
    {
    }

    /**
     * Initializes the `TlvIterator` to iterate over sub-TLVs of a given Prefix TLV.
     *
     * @param[in] aPrefixTlv   A Prefix TLV to iterate over its sub-TLVs.
     *
     */
    explicit TlvIterator(const PrefixTlv &aPrefixTlv)
        : TlvIterator(aPrefixTlv.GetSubTlvs(), aPrefixTlv.GetNext())
    {
    }

    /**
     * Initializes the `TlvIterator` to iterate over sub-TLVs of a given Service TLV.
     *
     * @param[in] aServiceTlv   A Service TLV to iterate over its sub-TLVs.
     *
     */
    explicit TlvIterator(const ServiceTlv &aServiceTlv)
        : TlvIterator(aServiceTlv.GetSubTlvs(), aServiceTlv.GetNext())
    {
    }

    /**
     * Iterates to the next TLV with a given type.
     *
     * @tparam  TlvType The TLV Type to search for (MUST be a sub-class of `NetworkDataTlv`).
     *
     * @returns A pointer to the next TLV, or `nullptr` if it can not be found.
     *
     */
    template <typename TlvType> const TlvType *Iterate(void) { return As<TlvType>(Iterate(TlvType::kType)); }

    /**
     * Iterates to the next TLV with a given type and stable flag.
     *
     * @tparam  TlvType The TLV Type to search for (MUST be a sub-class of `NetworkDataTlv`).
     *
     * @param[in]  aStable      TRUE to find a stable TLV, FALSE to find a TLV not marked as stable.
     *
     * @returns A pointer to the next TLV, or `nullptr` if it can not be found.
     *
     */
    template <typename TlvType> const TlvType *Iterate(bool aStable)
    {
        return As<TlvType>(Iterate(TlvType::kType, aStable));
    }

private:
    const NetworkDataTlv *Iterate(NetworkDataTlv::Type aType);
    const NetworkDataTlv *Iterate(NetworkDataTlv::Type aType, bool aStable);

    const NetworkDataTlv *mStart;
    const NetworkDataTlv *mEnd;
};

/**
 * @}
 *
 */

} // namespace NetworkData
} // namespace ot

#endif // NETWORK_DATA_TLVS_HPP_
