/*
 *  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;

/**
 * This template method 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);
}

/**
 * This template method 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);
}

/**
 * This template method 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);
}

/**
 * This template method 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);
}

/**
 * This class 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
    };

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

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

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

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

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

    /**
     * This methods 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; }

    /**
     * This methods 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; }

    /**
     * This method 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; }

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

    /**
     * This method 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); }

    /**
     * This method 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);
    }

    /**
     * This method 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);
    }

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

    /**
     * This method 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); }

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

    /**
     * This static method 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));
    }

    /**
     * This static method 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));
    }

    /**
     * This static method 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));
    }

    /**
     * This static method 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;

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

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

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

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

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

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

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

    /**
     * This method 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; }

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

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

    /**
     * This static method 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); }

    /**
     * This static method 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;

    uint16_t mRloc;
    uint8_t  mFlags;
} OT_TOOL_PACKED_END;

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

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

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

    /**
     * This method 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)));
    }

    /**
     * This method 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)));
    }

    /**
     * This method 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()); }

    /**
     * This method 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()); }

    /**
     * This method 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));
    }

    /**
     * This method 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;

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

    /**
     * This method 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);
    }

    /**
     * This method 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());
    }

    /**
     * This method 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)));
    }

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

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

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

    /**
     * This method 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); }

    /**
     * This method 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()); }

    /**
     * This method 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()); }

    /**
     * This method 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);
    }

    /**
     * This method 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));
    }

    /**
     * This method 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));
    }

    /**
     * This method 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));
    }

    /**
     * This method 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);
    }

    /**
     * This template method 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));
    }

    /**
     * This template method 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));
    }

    /**
     * This template method 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));
    }

    /**
     * This template method 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));
    }

    /**
     * This method 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)); }

    /**
     * This method 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;

    /**
     * This method 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));
    }

    /**
     * This method 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;

    /**
     * This static method 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;

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

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

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

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

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

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

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

    /**
     * This method 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; }

    /**
     * This method 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; }

    /**
     * This method 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; }

    /**
     * This method 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; }

    /**
     * This method 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; }

    /**
     * This method 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; }

    /**
     * This method 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; }

    /**
     * This method 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; }

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

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

    /**
     * This static method 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); }

    /**
     * This static method 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;

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

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

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

    /**
     * This method 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)));
    }

    /**
     * This method 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)));
    }

    /**
     * This method 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()); }

    /**
     * This method 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());
    }

    /**
     * This method 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));
    }

    /**
     * This method 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;

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

    /**
     * This method 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;
    }

    /**
     * This method 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; }

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

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

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

    /**
     * This method 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;

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

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

/**
 * This class 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.

    /**
     * This method 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);

    /**
     * This method 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()));
    }

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

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

    /**
     * This method 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());
    }

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

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

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

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

    /**
     * This method 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());
    }

    /**
     * This static method 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;

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

    /**
     * This method 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());
    }

    /**
     * This method 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)); }

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

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

    /**
     * This method 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()); }

    /**
     * This method 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)); }

    /**
     * This method 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);
    }

    /**
     * This static method 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;

/**
 * This class represents a Network Data TLV iterator.
 *
 */
class TlvIterator
{
public:
    /**
     * This constructor 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)
    {
    }

    /**
     * This constructor 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))
    {
    }

    /**
     * This constructor 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())
    {
    }

    /**
     * This constructor 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())
    {
    }

    /**
     * This template method 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)); }

    /**
     * This template method 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_
