/*
 *  Copyright (c) 2017, 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 DNS headers.
 */

#ifndef DNS_HEADER_HPP_
#define DNS_HEADER_HPP_

#include "openthread-core-config.h"

#include <openthread/dns.h>
#include <openthread/dns_client.h>

#include "common/appender.hpp"
#include "common/as_core_type.hpp"
#include "common/clearable.hpp"
#include "common/encoding.hpp"
#include "common/equatable.hpp"
#include "common/message.hpp"
#include "crypto/ecdsa.hpp"
#include "net/ip4_address.hpp"
#include "net/ip6_address.hpp"

namespace ot {

/**
 * @namespace ot::Dns
 * @brief
 *   This namespace includes definitions for DNS.
 *
 */
namespace Dns {

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

/**
 * @addtogroup core-dns
 *
 * @brief
 *   This module includes definitions for DNS.
 *
 * @{
 *
 */

/**
 * This class implements DNS header generation and parsing.
 *
 */
OT_TOOL_PACKED_BEGIN
class Header : public Clearable<Header>
{
public:
    /**
     * Default constructor for DNS Header.
     *
     */
    Header(void) { Clear(); }

    /**
     * This method returns the Message ID.
     *
     * @returns The Message ID value.
     *
     */
    uint16_t GetMessageId(void) const { return HostSwap16(mMessageId); }

    /**
     * This method sets the Message ID.
     *
     * @param[in]  aMessageId The Message ID value.
     *
     */
    void SetMessageId(uint16_t aMessageId) { mMessageId = HostSwap16(aMessageId); }

    /**
     * This method sets the Message ID to a crypto-secure randomly generated number.
     *
     * @retval  kErrorNone     Successfully generated random Message ID.
     * @retval  kErrorFailed   Could not generate random Message ID.
     *
     */
    Error SetRandomMessageId(void);

    /**
     * Defines types of DNS message.
     *
     */
    enum Type : uint8_t
    {
        kTypeQuery    = 0,
        kTypeResponse = 1,
    };

    /**
     * This method returns the type of the message.
     *
     * @returns The type of the message.
     *
     */
    Type GetType(void) const { return static_cast<Type>((mFlags[0] & kQrFlagMask) >> kQrFlagOffset); }

    /**
     * This method sets the type of the message.
     *
     * @param[in]  aType The type of the message.
     *
     */
    void SetType(Type aType)
    {
        mFlags[0] &= ~kQrFlagMask;
        mFlags[0] |= static_cast<uint8_t>(aType) << kQrFlagOffset;
    }

    /**
     * Defines types of query.
     *
     */
    enum QueryType : uint8_t
    {
        kQueryTypeStandard = 0,
        kQueryTypeInverse  = 1,
        kQueryTypeStatus   = 2,
        kQueryTypeNotify   = 4,
        kQueryTypeUpdate   = 5,
        kQueryTypeDso      = 6,
    };

    /**
     * This method returns the type of the query.
     *
     * @returns The type of the query.
     *
     */
    QueryType GetQueryType(void) const { return static_cast<QueryType>((mFlags[0] & kOpCodeMask) >> kOpCodeOffset); }

    /**
     * This method sets the type of the query.
     *
     * @param[in]  aType The type of the query.
     *
     */
    void SetQueryType(QueryType aType)
    {
        mFlags[0] &= ~kOpCodeMask;
        mFlags[0] |= static_cast<uint8_t>(aType) << kOpCodeOffset;
    }

    /**
     * This method specifies in response message if the responding name server is an
     * authority for the domain name in question section.
     *
     * @returns True if Authoritative Answer flag (AA) is set in the header, false otherwise.
     *
     */
    bool IsAuthoritativeAnswerFlagSet(void) const { return (mFlags[0] & kAaFlagMask) == kAaFlagMask; }

    /**
     * This method clears the Authoritative Answer flag (AA) in the header.
     *
     */
    void ClearAuthoritativeAnswerFlag(void) { mFlags[0] &= ~kAaFlagMask; }

    /**
     * This method sets the Authoritative Answer flag (AA) in the header.
     *
     */
    void SetAuthoritativeAnswerFlag(void) { mFlags[0] |= kAaFlagMask; }

    /**
     * This method specifies if message is truncated.
     *
     * @returns True if Truncation flag (TC) is set in the header, false otherwise.
     *
     */
    bool IsTruncationFlagSet(void) const { return (mFlags[0] & kTcFlagMask) == kTcFlagMask; }

    /**
     * This method clears the Truncation flag (TC) in the header.
     *
     */
    void ClearTruncationFlag(void) { mFlags[0] &= ~kTcFlagMask; }

    /**
     * This method sets the Truncation flag (TC) in the header.
     *
     */
    void SetTruncationFlag(void) { mFlags[0] |= kTcFlagMask; }

    /**
     * This method specifies if resolver wants to direct the name server to pursue
     * the query recursively.
     *
     * @returns True if Recursion Desired flag (RD) is set in the header, false otherwise.
     *
     */
    bool IsRecursionDesiredFlagSet(void) const { return (mFlags[0] & kRdFlagMask) == kRdFlagMask; }

    /**
     * This method clears the Recursion Desired flag (RD) in the header.
     *
     */
    void ClearRecursionDesiredFlag(void) { mFlags[0] &= ~kRdFlagMask; }

    /**
     * This method sets the Recursion Desired flag (RD) in the header.
     *
     */
    void SetRecursionDesiredFlag(void) { mFlags[0] |= kRdFlagMask; }

    /**
     * This method denotes whether recursive query support is available in the name server.
     *
     * @returns True if Recursion Available flag (RA) is set in the header, false otherwise.
     *
     */
    bool IsRecursionAvailableFlagSet(void) const { return (mFlags[1] & kRaFlagMask) == kRaFlagMask; }

    /**
     * This method clears the Recursion Available flag (RA) in the header.
     *
     */
    void ClearRecursionAvailableFlag(void) { mFlags[1] &= ~kRaFlagMask; }

    /**
     * This method sets the Recursion Available flag (RA) in the header.
     *
     */
    void SetRecursionAvailableFlag(void) { mFlags[1] |= kRaFlagMask; }

    /**
     * Defines response codes.
     *
     */
    enum Response : uint8_t
    {
        kResponseSuccess         = 0,  ///< Success (no error condition).
        kResponseFormatError     = 1,  ///< Server unable to interpret request due to format error.
        kResponseServerFailure   = 2,  ///< Server encountered an internal failure.
        kResponseNameError       = 3,  ///< Name that ought to exist, does not exists.
        kResponseNotImplemented  = 4,  ///< Server does not support the query type (OpCode).
        kResponseRefused         = 5,  ///< Server refused to perform operation for policy or security reasons.
        kResponseNameExists      = 6,  ///< Some name that ought not to exist, does exist.
        kResponseRecordExists    = 7,  ///< Some RRset that ought not to exist, does exist.
        kResponseRecordNotExists = 8,  ///< Some RRset that ought to exist, does not exist.
        kResponseNotAuth         = 9,  ///< Service is not authoritative for zone.
        kResponseNotZone         = 10, ///< A name is not in the zone.
        kDsoTypeNotImplemented   = 11, ///< DSO TLV TYPE is not implemented.
        kResponseBadName         = 20, ///< Bad name.
        kResponseBadAlg          = 21, ///< Bad algorithm.
        kResponseBadTruncation   = 22, ///< Bad truncation.
    };

    /**
     * This method returns the response code.
     *
     * @returns The response code from the header.
     *
     */
    Response GetResponseCode(void) const { return static_cast<Response>((mFlags[1] & kRCodeMask) >> kRCodeOffset); }

    /**
     * This method sets the response code.
     *
     * @param[in]  aResponse The type of the response.
     *
     */
    void SetResponseCode(Response aResponse)
    {
        mFlags[1] &= ~kRCodeMask;
        mFlags[1] |= static_cast<uint8_t>(aResponse) << kRCodeOffset;
    }

    /**
     * This method converts a Response Code into a related `Error`.
     *
     * - kResponseSuccess (0)         : Success (no error condition)                    -> kErrorNone
     * - kResponseFormatError (1)     : Server unable to interpret due to format error  -> kErrorParse
     * - kResponseServerFailure (2)   : Server encountered an internal failure          -> kErrorFailed
     * - kResponseNameError (3)       : Name that ought to exist, does not exists       -> kErrorNotFound
     * - kResponseNotImplemented (4)  : Server does not support the query type (OpCode) -> kErrorNotImplemented
     * - kResponseRefused (5)         : Server refused for policy/security reasons      -> kErrorSecurity
     * - kResponseNameExists (6)      : Some name that ought not to exist, does exist   -> kErrorDuplicated
     * - kResponseRecordExists (7)    : Some RRset that ought not to exist, does exist  -> kErrorDuplicated
     * - kResponseRecordNotExists (8) : Some RRset that ought to exist, does not exist  -> kErrorNotFound
     * - kResponseNotAuth (9)         : Service is not authoritative for zone           -> kErrorSecurity
     * - kResponseNotZone (10)        : A name is not in the zone                       -> kErrorParse
     * - kDsoTypeNotImplemented (11)  : DSO TLV Type is not implemented                 -> kErrorNotImplemented
     * - kResponseBadName (20)        : Bad name                                        -> kErrorParse
     * - kResponseBadAlg (21)         : Bad algorithm                                   -> kErrorSecurity
     * - kResponseBadTruncation (22)  : Bad truncation                                  -> kErrorParse
     * - Other error                                                                    -> kErrorFailed
     *
     * @param[in] aResponse  The response code to convert.
     *
     */
    static Error ResponseCodeToError(Response aResponse);

    /**
     * This method returns the number of entries in question section.
     *
     * @returns The number of entries in question section.
     *
     */
    uint16_t GetQuestionCount(void) const { return HostSwap16(mQdCount); }

    /**
     * This method sets the number of entries in question section.
     *
     * @param[in]  aCount The number of entries in question section.
     *
     */
    void SetQuestionCount(uint16_t aCount) { mQdCount = HostSwap16(aCount); }

    /**
     * This method returns the number of entries in answer section.
     *
     * @returns The number of entries in answer section.
     *
     */
    uint16_t GetAnswerCount(void) const { return HostSwap16(mAnCount); }

    /**
     * This method sets the number of entries in answer section.
     *
     * @param[in]  aCount The number of entries in answer section.
     *
     */
    void SetAnswerCount(uint16_t aCount) { mAnCount = HostSwap16(aCount); }

    /**
     * This method returns the number of entries in authority records section.
     *
     * @returns The number of entries in authority records section.
     *
     */
    uint16_t GetAuthorityRecordCount(void) const { return HostSwap16(mNsCount); }

    /**
     * This method sets the number of entries in authority records section.
     *
     * @param[in]  aCount The number of entries in authority records section.
     *
     */
    void SetAuthorityRecordCount(uint16_t aCount) { mNsCount = HostSwap16(aCount); }

    /**
     * This method returns the number of entries in additional records section.
     *
     * @returns The number of entries in additional records section.
     *
     */
    uint16_t GetAdditionalRecordCount(void) const { return HostSwap16(mArCount); }

    /**
     * This method sets the number of entries in additional records section.
     *
     * @param[in]  aCount The number of entries in additional records section.
     *
     */
    void SetAdditionalRecordCount(uint16_t aCount) { mArCount = HostSwap16(aCount); }

private:
    // Protocol Constants (RFC 1035).
    static constexpr uint8_t kQrFlagOffset = 7;                     // QR Flag offset.
    static constexpr uint8_t kQrFlagMask   = 0x01 << kQrFlagOffset; // QR Flag mask.
    static constexpr uint8_t kOpCodeOffset = 3;                     // OpCode field offset.
    static constexpr uint8_t kOpCodeMask   = 0x0f << kOpCodeOffset; // OpCode field mask.
    static constexpr uint8_t kAaFlagOffset = 2;                     // AA Flag offset.
    static constexpr uint8_t kAaFlagMask   = 0x01 << kAaFlagOffset; // AA Flag mask.
    static constexpr uint8_t kTcFlagOffset = 1;                     // TC Flag offset.
    static constexpr uint8_t kTcFlagMask   = 0x01 << kTcFlagOffset; // TC Flag mask.
    static constexpr uint8_t kRdFlagOffset = 0;                     // RD Flag offset.
    static constexpr uint8_t kRdFlagMask   = 0x01 << kRdFlagOffset; // RD Flag mask.
    static constexpr uint8_t kRaFlagOffset = 7;                     // RA Flag offset.
    static constexpr uint8_t kRaFlagMask   = 0x01 << kRaFlagOffset; // RA Flag mask.
    static constexpr uint8_t kRCodeOffset  = 0;                     // RCODE field offset.
    static constexpr uint8_t kRCodeMask    = 0x0f << kRCodeOffset;  // RCODE field mask.

    uint16_t mMessageId; // Message identifier for requester to match up replies to outstanding queries.
    uint8_t  mFlags[2];  // DNS header flags.
    uint16_t mQdCount;   // Number of entries in the question section.
    uint16_t mAnCount;   // Number of entries in the answer section.
    uint16_t mNsCount;   // Number of entries in the authority records section.
    uint16_t mArCount;   // Number of entries in the additional records section.

} OT_TOOL_PACKED_END;

/**
 * This class implements DNS Update message header generation and parsing.
 *
 * The DNS header specifies record counts for its four sections: Question, Answer, Authority, and Additional. A DNS
 * Update header uses the same fields, and the same section formats, but the naming and use of these sections differs:
 * DNS Update header uses Zone, Prerequisite, Update, Additional Data sections.
 *
 */
OT_TOOL_PACKED_BEGIN
class UpdateHeader : public Header
{
public:
    /**
     * Default constructor for DNS Update message header.
     *
     */
    UpdateHeader(void) { SetQueryType(kQueryTypeUpdate); }

    /**
     * This method returns the number of records in Zone section.
     *
     * @returns The number of records in Zone section.
     *
     */
    uint16_t GetZoneRecordCount(void) const { return GetQuestionCount(); }

    /**
     * This method sets the number of records in Zone section.
     *
     * @param[in]  aCount The number of records in Zone section.
     *
     */
    void SetZoneRecordCount(uint16_t aCount) { SetQuestionCount(aCount); }

    /**
     * This method returns the number of records in Prerequisite section.
     *
     * @returns The number of records in Prerequisite section.
     *
     */
    uint16_t GetPrerequisiteRecordCount(void) const { return GetAnswerCount(); }

    /**
     * This method sets the number of records in Prerequisite section.
     *
     * @param[in]  aCount The number of records in Prerequisite section.
     *
     */
    void SetPrerequisiteRecordCount(uint16_t aCount) { SetAnswerCount(aCount); }

    /**
     * This method returns the number of records in Update section.
     *
     * @returns The number of records in Update section.
     *
     */
    uint16_t GetUpdateRecordCount(void) const { return GetAuthorityRecordCount(); }

    /**
     * This method sets the number of records in Update section.
     *
     * @param[in]  aCount The number of records in Update section.
     *
     */
    void SetUpdateRecordCount(uint16_t aCount) { SetAuthorityRecordCount(aCount); }

} OT_TOOL_PACKED_END;

/**
 * This class represents a DNS name and implements helper methods for encoding/decoding of DNS Names.
 *
 */
class Name : public Clearable<Name>
{
public:
    /**
     * Max size (number of chars) in a name string array (includes null char at the end of string).
     *
     */
    static constexpr uint8_t kMaxNameSize = OT_DNS_MAX_NAME_SIZE;

    /**
     * Maximum length in a name string (does not include null char at the end of string).
     *
     */
    static constexpr uint8_t kMaxNameLength = kMaxNameSize - 1;

    /**
     * Max size (number of chars) in a label string array (includes null char at the end of the string).
     *
     */
    static constexpr uint8_t kMaxLabelSize = OT_DNS_MAX_LABEL_SIZE;

    /**
     * Maximum length in a label string (does not include null char at the end of string).
     *
     */
    static constexpr uint8_t kMaxLabelLength = kMaxLabelSize - 1;

    static constexpr char kLabelSeperatorChar = '.';

    /**
     * This enumeration represents the name type.
     *
     */
    enum Type : uint8_t
    {
        kTypeEmpty,   ///< The name is empty (not specified).
        kTypeCString, ///< The name is given as a C string (dot '.' separated sequence of labels).
        kTypeMessage, ///< The name is specified from a message at a given offset (encoded in the message).
    };

    /**
     * This constructor initializes the `Name` object as empty (not specified).
     *
     */
    Name(void)
        : Name(nullptr, nullptr, 0)
    {
    }

    /**
     * This constructor initializes the `Name` object with a given string.
     *
     * @param[in] aString   A C string specifying the name (dot '.' separated sequence of labels').
     *
     */
    explicit Name(const char *aString)
        : Name(aString, nullptr, 0)
    {
    }

    /**
     * This constructor initializes the `Name` object from a message at a given offset.
     *
     * @param[in] aMessage   The message containing the encoded name. `aMessage.GetOffset()` MUST point to the start of
     *                       the DNS header in the message (used to parse compressed name).
     * @param[in] aOffset    The offset in @p aMessage pointing to the start of the name.
     *
     */
    Name(const Message &aMessage, uint16_t aOffset)
        : Name(nullptr, &aMessage, aOffset)
    {
    }

    /**
     * This method indicates whether the name is empty (not specified).
     *
     * @returns TRUE if the name is empty, FALSE otherwise.
     *
     */
    bool IsEmpty(void) const { return (mString == nullptr) && (mMessage == nullptr); }

    /**
     * This method indicates whether the name is specified from a C string.
     *
     * @returns TRUE if the name is specified from a string, FALSE otherwise.
     *
     */
    bool IsFromCString(void) const { return mString != nullptr; }

    /**
     * This method indicates whether the name is specified from a message.
     *
     * @returns TRUE if the name is specified from a message, FALSE otherwise.
     *
     */
    bool IsFromMessage(void) const { return mMessage != nullptr; }

    /**
     * This method gets the type of `Name` object indicating whether it is empty, specified by a C string or from a
     * message
     *
     * @returns The name type.
     *
     */
    Type GetFromType(void) const
    {
        return IsFromCString() ? kTypeCString : (IsFromMessage() ? kTypeMessage : kTypeEmpty);
    }

    /**
     * This method sets the name from a given C string.
     *
     * @param[in] aString   A C string specifying the name (dot '.' separated sequence of labels).
     *
     */
    void Set(const char *aString)
    {
        mString  = aString;
        mMessage = nullptr;
    }

    /**
     * This method sets the name from a message at a given offset.
     *
     * @param[in] aMessage   The message containing the encoded name. `aMessage.GetOffset()` MUST point to the start of
     *                       the DNS header in the message (used to parse compressed name).
     * @param[in] aOffset    The offset in @p aMessage pointing to the start of the name.
     *
     */
    void SetFromMessage(const Message &aMessage, uint16_t aOffset)
    {
        mString  = nullptr;
        mMessage = &aMessage;
        mOffset  = aOffset;
    }

    /**
     * This method gets the name as a C string.
     *
     * This method MUST be used only when the type is `kTypeString`. Otherwise its behavior is undefined.
     *
     * @returns A pointer to the C string.
     *
     */
    const char *GetAsCString(void) const { return mString; }

    /**
     * This method gets the name message and offset.
     *
     * This method MUST be used only when the type is `kTypeMessage`. Otherwise its behavior is undefined.
     *
     * @param[out]  aOffset    A reference to a variable to output the offset of the start of the name in the message.
     *
     * @returns A reference to the message containing the name.
     *
     */
    const Message &GetAsMessage(uint16_t &aOffset) const
    {
        aOffset = mOffset;
        return *mMessage;
    }

    /**
     * This method encodes and appends the name to a message.
     *
     * If the name is empty (not specified), then root "." is appended to @p aMessage. If the name is from a C string
     * then the string is checked and appended (similar to static `AppendName(const char *aName, Message &)` method).
     * If the the name is from a message, then it is read from the message and appended to @p aMessage. Note that in
     * this case independent of whether the name is compressed or not in its original message, the name is appended
     * as full (uncompressed) in @p aMessage.
     *
     * @param[in] aMessage        The message to append to.
     *
     * @retval kErrorNone         Successfully encoded and appended the name to @p aMessage.
     * @retval kErrorInvalidArgs  Name is not valid.
     * @retval kErrorNoBufs       Insufficient available buffers to grow the message.
     *
     */
    Error AppendTo(Message &aMessage) const;

    /**
     * This static method encodes and appends a single name label to a message.
     *
     * The @p aLabel is assumed to contain a single name label as a C string (null-terminated). Unlike
     * `AppendMultipleLabels()` which parses the label string and treats it as sequence of multiple (dot-separated)
     * labels, this method always appends @p aLabel as a single whole label. This allows the label string to even
     * contain dot '.' character, which, for example, is useful for "Service Instance Names" where <Instance> portion
     * is a user-friendly name and can contain dot characters.
     *
     * @param[in] aLabel              The label string to append. MUST NOT be `nullptr`.
     * @param[in] aMessage            The message to append to.
     *
     * @retval kErrorNone         Successfully encoded and appended the name label to @p aMessage.
     * @retval kErrorInvalidArgs  @p aLabel is not valid (e.g., label length is not within valid range).
     * @retval kErrorNoBufs       Insufficient available buffers to grow the message.
     *
     */
    static Error AppendLabel(const char *aLabel, Message &aMessage);

    /**
     * This static method encodes and appends a single name label of specified length to a message.
     *
     * The @p aLabel is assumed to contain a single name label of given @p aLength.  @p aLabel must not contain
     * '\0' characters within the length @p aLength. Unlike `AppendMultipleLabels()` which parses the label string
     * and treats it as sequence of multiple (dot-separated) labels, this method always appends @p aLabel as a single
     * whole label. This allows the label string to even contain dot '.' character, which, for example, is useful for
     * "Service Instance Names" where <Instance> portion is a user-friendly name and can contain dot characters.
     *
     * @param[in] aLabel         The label string to append. MUST NOT be `nullptr`.
     * @param[in] aLength        The length of the label to append.
     * @param[in] aMessage       The message to append to.
     *
     * @retval kErrorNone         Successfully encoded and appended the name label to @p aMessage.
     * @retval kErrorInvalidArgs  @p aLabel is not valid (e.g., label length is not within valid range).
     * @retval kErrorNoBufs       Insufficient available buffers to grow the message.
     *
     */
    static Error AppendLabel(const char *aLabel, uint8_t aLength, Message &aMessage);

    /**
     * This static method encodes and appends a sequence of name labels to a given message.
     *
     * The @p aLabels must follow  "<label1>.<label2>.<label3>", i.e., a sequence of labels separated by dot '.' char.
     * E.g., "_http._tcp", "_http._tcp." (same as previous one), "host-1.test".
     *
     * This method validates that the @p aLabels is a valid name format, i.e., no empty label, and labels are
     * `kMaxLabelLength` (63) characters or less.
     *
     * @note This method NEVER adds a label terminator (empty label) to the message, even in the case where @p aLabels
     * ends with a dot character, e.g., "host-1.test." is treated same as "host-1.test".
     *
     * @param[in]  aLabels            A name label string. Can be `nullptr` (then treated as "").
     * @param[in]  aMessage           The message to which to append the encoded name.
     *
     * @retval kErrorNone         Successfully encoded and appended the name label(s) to @p aMessage.
     * @retval kErrorInvalidArgs  Name label @p aLabels is not valid.
     * @retval kErrorNoBufs       Insufficient available buffers to grow the message.
     *
     */
    static Error AppendMultipleLabels(const char *aLabels, Message &aMessage);

    /**
     * This static method encodes and appends a sequence of name labels within the specified length to a given message.
     * This method stops appending labels if @p aLength characters are read or '\0' is found before @p aLength
     * characters.
     *
     * This method is useful for appending a number of labels of the name instead of appending all labels.
     *
     * The @p aLabels must follow  "<label1>.<label2>.<label3>", i.e., a sequence of labels separated by dot '.' char.
     * E.g., "_http._tcp", "_http._tcp." (same as previous one), "host-1.test".
     *
     * This method validates that the @p aLabels is a valid name format, i.e., no empty label, and labels are
     * `kMaxLabelLength` (63) characters or less.
     *
     * @note This method NEVER adds a label terminator (empty label) to the message, even in the case where @p aLabels
     * ends with a dot character, e.g., "host-1.test." is treated same as "host-1.test".
     *
     * @param[in]  aLabels            A name label string. Can be `nullptr` (then treated as "").
     * @param[in]  aLength            The max length of the name labels to encode.
     * @param[in]  aMessage           The message to which to append the encoded name.
     *
     * @retval kErrorNone         Successfully encoded and appended the name label(s) to @p aMessage.
     * @retval kErrorInvalidArgs  Name label @p aLabels is not valid.
     * @retval kErrorNoBufs       Insufficient available buffers to grow the message.
     *
     */
    static Error AppendMultipleLabels(const char *aLabels, uint8_t aLength, Message &aMessage);

    /**
     * This static method appends a name label terminator to a message.
     *
     * An encoded name is terminated by an empty label (a zero byte).
     *
     * @param[in] aMessage            The message to append to.
     *
     * @retval kErrorNone         Successfully encoded and appended the terminator label to @p aMessage.
     * @retval kErrorNoBufs       Insufficient available buffers to grow the message.
     *
     */
    static Error AppendTerminator(Message &aMessage);

    /**
     * This static method appends a pointer type name label to a message.
     *
     * Pointer label is used for name compression. It allows an entire name or a list of labels at the end of an
     * encoded name to be replaced with a pointer to a prior occurrence of the same name within the message.
     *
     * @param[in] aOffset             The offset from the start of DNS header to use for pointer value.
     * @param[in] aMessage            The message to append to.
     *
     * @retval kErrorNone         Successfully encoded and appended the pointer label to @p aMessage.
     * @retval kErrorNoBufs       Insufficient available buffers to grow the message.
     *
     */
    static Error AppendPointerLabel(uint16_t aOffset, Message &aMessage);

    /**
     * This static method encodes and appends a full name to a message.
     *
     * The @p aName must follow  "<label1>.<label2>.<label3>", i.e., a sequence of labels separated by dot '.' char.
     * E.g., "example.com", "example.com." (same as previous one), "local.", "default.service.arpa", "." or "" (root).
     *
     * This method validates that the @p aName is a valid name format, i.e. no empty labels, and labels are
     * `kMaxLabelLength` (63) characters or less, and the name is `kMaxLength` (255) characters or less.
     *
     * @param[in]  aName              A name string. Can be `nullptr` (then treated as "." or root).
     * @param[in]  aMessage           The message to append to.
     *
     * @retval kErrorNone         Successfully encoded and appended the name to @p aMessage.
     * @retval kErrorInvalidArgs  Name @p aName is not valid.
     * @retval kErrorNoBufs       Insufficient available buffers to grow the message.
     *
     */
    static Error AppendName(const char *aName, Message &aMessage);

    /**
     * This static method parses and skips over a full name in a message.
     *
     * @param[in]     aMessage        The message to parse the name from. `aMessage.GetOffset()` MUST point to
     *                                the start of DNS header (this is used to handle compressed names).
     * @param[in,out] aOffset         On input the offset in @p aMessage pointing to the start of the name field.
     *                                On exit (when parsed successfully), @p aOffset is updated to point to the byte
     *                                after the end of name field.
     *
     * @retval kErrorNone          Successfully parsed and skipped over name, @p Offset is updated.
     * @retval kErrorParse         Name could not be parsed (invalid format).
     *
     */
    static Error ParseName(const Message &aMessage, uint16_t &aOffset);

    /**
     * This static method reads a name label from a message.
     *
     * This method can be used to read labels one by one in a name. After a successful label read, @p aOffset is
     * updated to point to the start of the next label. When we reach the end of the name, kErrorNotFound is
     * returned. This method handles compressed names which use pointer labels. So as the labels in a name are read,
     * the @p aOffset may jump back in the message and at the end the @p aOffset does not necessarily point to the end
     * of the original name field.
     *
     * Unlike `ReadName()` which requires and verifies that the read label to contain no dot '.' character, this method
     * allows the read label to include any character.
     *
     * @param[in]      aMessage       The message to read the label from. `aMessage.GetOffset()` MUST point to
     *                                the start of DNS header (this is used to handle compressed names).
     * @param[in,out]  aOffset        On input, the offset in @p aMessage pointing to the start of the label to read.
     *                                On exit, when successfully read, @p aOffset is updated to point to the start of
     *                                the next label.
     * @param[out]     aLabelBuffer   A pointer to a char array to output the read label as a null-terminated C string.
     * @param[in,out]  aLabelLength   On input, the maximum number chars in @p aLabelBuffer array.
     *                                On output, when label is successfully read, @p aLabelLength is updated to return
     *                                the label's length (number of chars in the label string, excluding the null char).
     *
     * @retval kErrorNone      Successfully read the label and updated @p aLabelBuffer, @p aLabelLength, and @p aOffset.
     * @retval kErrorNotFound  Reached the end of name and no more label to read.
     * @retval kErrorParse     Name could not be parsed (invalid format).
     * @retval kErrorNoBufs    Label could not fit in @p aLabelLength chars.
     *
     */
    static Error ReadLabel(const Message &aMessage, uint16_t &aOffset, char *aLabelBuffer, uint8_t &aLabelLength);

    /**
     * This static method reads a full name from a message.
     *
     * On successful read, the read name follows  "<label1>.<label2>.<label3>.", i.e., a sequence of labels separated by
     * dot '.' character. The read name will ALWAYS end with a dot.
     *
     * This method verifies that the read labels in message do not contain any dot character, otherwise it returns
     * `kErrorParse`).
     *
     * @param[in]     aMessage         The message to read the name from. `aMessage.GetOffset()` MUST point to
     *                                 the start of DNS header (this is used to handle compressed names).
     * @param[in,out] aOffset          On input, the offset in @p aMessage pointing to the start of the name field.
     *                                 On exit (when parsed successfully), @p aOffset is updated to point to the byte
     *                                 after the end of name field.
     * @param[out]    aNameBuffer      A pointer to a char array to output the read name as a null-terminated C string.
     * @param[in,out] aNameBufferSize  The maximum number of chars in @p aNameBuffer array.
     *
     * @retval kErrorNone         Successfully read the name, @p aNameBuffer and @p Offset are updated.
     * @retval kErrorParse        Name could not be parsed (invalid format).
     * @retval kErrorNoBufs       Name could not fit in @p aNameBufferSize chars.
     *
     */
    static Error ReadName(const Message &aMessage, uint16_t &aOffset, char *aNameBuffer, uint16_t aNameBufferSize);

    /**
     * This static method compares a single name label from a message with a given label string.
     *
     * This method can be used to compare labels one by one. It checks whether the label read from @p aMessage matches
     * @p aLabel string (case-insensitive comparison).
     *
     * Unlike `CompareName()` which requires the labels in the the name string to contain no dot '.' character, this
     * method allows @p aLabel to include any character.
     *
     * @param[in]     aMessage        The message to read the label from to compare. `aMessage.GetOffset()` MUST point
     *                                to the start of DNS header (this is used to handle compressed names).
     * @param[in,out] aOffset         On input, the offset in @p aMessage pointing to the start of the label to read.
     *                                On exit and only when label is successfully read and does match @p aLabel,
     *                                @p aOffset is updated to point to the start of the next label.
     * @param[in]     aLabel          A pointer to a null terminated string containing the label to compare with.
     *
     * @retval kErrorNone          The label from @p aMessage matches @p aLabel. @p aOffset is updated.
     * @retval kErrorNotFound      The label from @p aMessage does not match @p aLabel (note that @p aOffset is not
     *                             updated in this case).
     * @retval kErrorParse         Name could not be parsed (invalid format).
     *
     */
    static Error CompareLabel(const Message &aMessage, uint16_t &aOffset, const char *aLabel);

    /**
     * This static method parses and compares a full name from a message with a given name.
     *
     * This method checks whether the encoded name in a message matches a given name string (using case-insensitive
     * comparison). It checks the name in the message in place and handles compressed names. If the name read from the
     * message does not match @p aName, it returns `kErrorNotFound`. `kErrorNone` indicates that the name matches
     * @p aName.
     *
     * The @p aName must follow  "<label1>.<label2>.<label3>", i.e., a sequence of labels separated by dot '.' char.
     * E.g., "example.com", "example.com." (same as previous one), "local.", "default.service.arpa", "." or "" (root).
     *
     * @param[in]     aMessage        The message to read the name from and compare with @p aName.
     *                                `aMessage.GetOffset()` MUST point to the start of DNS header (this is used to
     *                                handle compressed names).
     * @param[in,out] aOffset         On input, the offset in @p aMessage pointing to the start of the name field.
     *                                On exit (when parsed successfully independent of whether the read name matches
     *                                @p aName or not), @p aOffset is updated to point to the byte after the end of
     *                                the name field.
     * @param[in]     aName           A pointer to a null terminated string containing the name to compare with.
     *
     * @retval kErrorNone          The name from @p aMessage matches @p aName. @p aOffset is updated.
     * @retval kErrorNotFound      The name from @p aMessage does not match @p aName. @p aOffset is updated.
     * @retval kErrorParse         Name could not be parsed (invalid format).
     * @retval kErrorInvalidArgs   The @p aName is not a valid name (e.g. back to back "." chars)
     *
     */
    static Error CompareName(const Message &aMessage, uint16_t &aOffset, const char *aName);

    /**
     * This static method parses and compares a full name from a message with a name from another message.
     *
     * This method checks whether the encoded name in @p aMessage matches the name from @p aMessage2 (using
     * case-insensitive comparison). It compares the names in both messages in place and handles compressed names. Note
     * that this method works correctly even when the same message instance is used for both @p aMessage and
     * @p aMessage2 (e.g., at different offsets).
     *
     * Only the name in @p aMessage is fully parsed and checked for parse errors. This method assumes that the name in
     * @p aMessage2 was previously parsed and validated before calling this method (if there is a parse error in
     * @p aMessage2, it is treated as a name mismatch with @p aMessage).
     *
     * If the name in @p aMessage can be parsed fully (independent of whether the name matches or not with the name
     * from @p aMessage2), the @p aOffset is updated (note that @p aOffset2 for @p aMessage2 is not changed).
     *
     * @param[in]     aMessage        The message to read the name from and compare. `aMessage.GetOffset()` MUST point
     *                                to the start of DNS header (this is used to handle compressed names).
     * @param[in,out] aOffset         On input, the offset in @p aMessage pointing to the start of the name field.
     *                                On exit (when parsed successfully independent of whether the read name matches
     *                                or not), @p aOffset is updated to point to the byte after the end of the name
     *                                field.
     * @param[in]     aMessage2       The second message to read the name from and compare with name from @p aMessage.
     *                                `aMessage2.GetOffset()` MUST point to the start of DNS header.
     * @param[in]     aOffset2        The offset in @p aMessage2 pointing to the start of the name field.
     *
     * @retval kErrorNone       The name from @p aMessage matches the name from @p aMessage2. @p aOffset is updated.
     * @retval kErrorNotFound   The name from @p aMessage does not match the name from @p aMessage2. @p aOffset is
     *                          updated.
     * @retval kErrorParse      Name in @p aMessage could not be parsed (invalid format).
     *
     */
    static Error CompareName(const Message &aMessage, uint16_t &aOffset, const Message &aMessage2, uint16_t aOffset2);

    /**
     * This static method parses and compares a full name from a message with a given name (using case-insensitive
     * comparison).
     *
     * If @p aName is empty (not specified), then any name in @p aMessage is considered a match to it.
     *
     * @param[in]     aMessage        The message to read the name from and compare. `aMessage.GetOffset()` MUST point
     *                                to the start of DNS header (this is used to handle compressed names).
     * @param[in,out] aOffset         On input, the offset in @p aMessage pointing to the start of the name field.
     *                                On exit (when parsed successfully independent of whether the read name matches
     *                                or not), @p aOffset is updated to point to the byte after the end of the name
     *                                field.
     * @param[in]     aName           A reference to a name to compare with.
     *
     * @retval kErrorNone          The name from @p aMessage matches @p aName. @p aOffset is updated.
     * @retval kErrorNotFound      The name from @p aMessage does not match @p aName. @p aOffset is updated.
     * @retval kErrorParse         Name in @p aMessage could not be parsed (invalid format).
     *
     */
    static Error CompareName(const Message &aMessage, uint16_t &aOffset, const Name &aName);

    /**
     * This static method tests if a DNS name is a sub-domain of a given domain.
     *
     * Both @p aName and @p aDomain can end without dot ('.').
     *
     * @param[in]  aName    The dot-separated name.
     * @param[in]  aDomain  The dot-separated domain.
     *
     * @returns  TRUE if the name is a sub-domain of @p aDomain, FALSE if is not.
     *
     */
    static bool IsSubDomainOf(const char *aName, const char *aDomain);

private:
    // The first 2 bits of the encoded label specifies label type.
    //
    // - Value 00 indicates normal text label (lower 6-bits indicates the label length).
    // - Value 11 indicates pointer label type (lower 14-bits indicates the pointer offset).
    // - Values 01,10 are reserved (RFC 6891 recommends to not use)

    static constexpr uint8_t kLabelTypeMask    = 0xc0; // 0b1100_0000 (first two bits)
    static constexpr uint8_t kTextLabelType    = 0x00; // Text label type (00)
    static constexpr uint8_t kPointerLabelType = 0xc0; // Pointer label type - compressed name (11)

    static constexpr uint8_t kMaxEncodedLength = 255; ///< Max length of an encoded name.

    static constexpr uint16_t kPointerLabelTypeUint16 = 0xc000; // Pointer label type mask (first 2 bits).
    static constexpr uint16_t kPointerLabelOffsetMask = 0x3fff; // Mask for offset in a pointer label (lower 14 bits).

    static constexpr bool kIsSingleLabel = true; // Used in `LabelIterator::CompareLable()`.

    struct LabelIterator
    {
        static constexpr uint16_t kUnsetNameEndOffset = 0; // Special value indicating `mNameEndOffset` is not yet set.

        LabelIterator(const Message &aMessage, uint16_t aLabelOffset)
            : mMessage(aMessage)
            , mNextLabelOffset(aLabelOffset)
            , mNameEndOffset(kUnsetNameEndOffset)
        {
        }

        bool  IsEndOffsetSet(void) const { return (mNameEndOffset != kUnsetNameEndOffset); }
        Error GetNextLabel(void);
        Error ReadLabel(char *aLabelBuffer, uint8_t &aLabelLength, bool aAllowDotCharInLabel) const;
        bool  CompareLabel(const char *&aName, bool aIsSingleLabel) const;
        bool  CompareLabel(const LabelIterator &aOtherIterator) const;
        Error AppendLabel(Message &aMessage) const;

        static bool CaseInsensitiveMatch(uint8_t aFirst, uint8_t aSecond);

        const Message &mMessage;          // Message to read labels from.
        uint16_t       mLabelStartOffset; // Offset in `mMessage` to the first char of current label text.
        uint8_t        mLabelLength;      // Length of current label (number of chars).
        uint16_t       mNextLabelOffset;  // Offset in `mMessage` to the start of the next label.
        uint16_t       mNameEndOffset;    // Offset in `mMessage` to the byte after the end of domain name field.
    };

    Name(const char *aString, const Message *aMessage, uint16_t aOffset)
        : mString(aString)
        , mMessage(aMessage)
        , mOffset(aOffset)
    {
    }

    const char *   mString;  // String containing the name or `nullptr` if name is not from string.
    const Message *mMessage; // Message containing the encoded name, or `nullptr` if `Name` is not from message.
    uint16_t       mOffset;  // Offset in `mMessage` to the start of name (used when name is from `mMessage`).
};

/**
 * This type represents a TXT record entry representing a key/value pair (RFC 6763 - section 6.3).
 *
 */
class TxtEntry : public otDnsTxtEntry
{
    friend class TxtRecord;

public:
    /**
     * Minimum length of key string (RFC 6763 - section 6.4).
     *
     */
    static constexpr uint8_t kMinKeyLength = OT_DNS_TXT_KEY_MIN_LENGTH;

    /**
     * Recommended max length of key string (RFC 6763 - section 6.4).
     *
     */
    static constexpr uint8_t kMaxKeyLength = OT_DNS_TXT_KEY_MAX_LENGTH;

    /**
     * This class represents an iterator for TXT record entries (key/value pairs).
     *
     */
    class Iterator : public otDnsTxtEntryIterator
    {
        friend class TxtEntry;

    public:
        /**
         * This method initializes a TXT record iterator.
         *
         * The buffer pointer @p aTxtData and its content MUST persist and remain unchanged while the iterator object
         * is being used.
         *
         * @param[in] aTxtData        A pointer to buffer containing the encoded TXT data.
         * @param[in] aTxtDataLength  The length (number of bytes) of @p aTxtData.
         *
         */
        void Init(const uint8_t *aTxtData, uint16_t aTxtDataLength);

        /**
         * This method parses the TXT data from the `Iterator` and gets the next TXT record entry (key/value pair).
         *
         * The `Iterator` instance MUST be initialized using `Init()` before calling this method and the TXT data
         * buffer used to initialize the iterator MUST persist and remain unchanged.
         *
         * If the parsed key string length is smaller than or equal to `kMaxKeyLength` (recommended max key length)
         * the key string is returned in `mKey` in @p aEntry. But if the key is longer, then `mKey` is set to NULL and
         * the entire encoded TXT entry is returned in `mValue` and `mValueLength`.
         *
         * @param[out] aEntry          A reference to a `TxtEntry` to output the parsed/read entry.
         *
         * @retval kErrorNone       The next entry was parsed successfully. @p aEntry is updated.
         * @retval kErrorNotFound   No more entries in TXT data.
         * @retval kErrorParse      The TXT data from `Iterator` is not well-formed.
         *
         */
        Error GetNextEntry(TxtEntry &aEntry);

    private:
        static constexpr uint8_t kIndexTxtLength   = 0;
        static constexpr uint8_t kIndexTxtPosition = 1;

        const char *GetTxtData(void) const { return reinterpret_cast<const char *>(mPtr); }
        void        SetTxtData(const uint8_t *aTxtData) { mPtr = aTxtData; }
        uint16_t    GetTxtDataLength(void) const { return mData[kIndexTxtLength]; }
        void        SetTxtDataLength(uint16_t aLength) { mData[kIndexTxtLength] = aLength; }
        uint16_t    GetTxtDataPosition(void) const { return mData[kIndexTxtPosition]; }
        void        SetTxtDataPosition(uint16_t aValue) { mData[kIndexTxtPosition] = aValue; }
        void        IncreaseTxtDataPosition(uint16_t aIncrement) { mData[kIndexTxtPosition] += aIncrement; }
        char *      GetKeyBuffer(void) { return mChar; }
        const char *GetTxtDataEnd(void) const { return GetTxtData() + GetTxtDataLength(); }
    };

    /**
     * This is the default constructor for a `TxtEntry` object.
     *
     */
    TxtEntry(void) = default;

    /**
     * This constructor initializes a `TxtEntry` object.
     *
     * @param[in] aKey           A pointer to the key string.
     * @param[in] aValue         A pointer to a buffer containing the value.
     * @param[in] aValueLength   Number of bytes in @p aValue buffer.
     *
     */
    TxtEntry(const char *aKey, const uint8_t *aValue, uint8_t aValueLength) { Init(aKey, aValue, aValueLength); }

    /**
     * This method initializes a `TxtEntry` object.
     *
     * @param[in] aKey           A pointer to the key string.
     * @param[in] aValue         A pointer to a buffer containing the value.
     * @param[in] aValueLength   Number of bytes in @p aValue buffer.
     *
     */
    void Init(const char *aKey, const uint8_t *aValue, uint8_t aValueLength)
    {
        mKey         = aKey;
        mValue       = aValue;
        mValueLength = aValueLength;
    }

    /**
     * This method encodes and appends the `TxtEntry` to a message.
     *
     * @param[in] aMessage  The message to append to.
     *
     * @retval kErrorNone          Entry was appended successfully to @p aMessage.
     * @retval kErrorInvalidArgs   The `TxTEntry` info is not valid.
     * @retval kErrorNoBufs        Insufficient available buffers to grow the message.
     *
     */
    Error AppendTo(Message &aMessage) const;

    /**
     * This static method appends an array of `TxtEntry` items to a message.
     *
     * @param[in] aEntries     A pointer to array of `TxtEntry` items.
     * @param[in] aNumEntries  The number of entries in @p aEntries array.
     * @param[in] aMessage     The message to append to.
     *
     * @retval kErrorNone          Entries appended successfully to @p aMessage.
     * @retval kErrorInvalidArgs   The `TxTEntry` info is not valid.
     * @retval kErrorNoBufs        Insufficient available buffers to grow the message.
     *
     */
    static Error AppendEntries(const TxtEntry *aEntries, uint8_t aNumEntries, Message &aMessage);

    /**
     * This static method appends an array of `TxtEntry` items to a `MutableData` buffer.
     *
     * @param[in] aEntries     A pointer to array of `TxtEntry` items.
     * @param[in] aNumEntries  The number of entries in @p aEntries array.
     * @param[in] aData        The `MutableData` to append in.
     *
     * @retval kErrorNone          Entries appended successfully .
     * @retval kErrorInvalidArgs   The `TxTEntry` info is not valid.
     * @retval kErrorNoBufs        Insufficient available buffers.
     *
     */
    static Error AppendEntries(const TxtEntry *aEntries, uint8_t aNumEntries, MutableData<kWithUint16Length> &aData);

private:
    Error        AppendTo(Appender &aAppender) const;
    static Error AppendEntries(const TxtEntry *aEntries, uint8_t aNumEntries, Appender &aAppender);

    static constexpr uint8_t kMaxKeyValueEncodedSize = 255;
    static constexpr char    kKeyValueSeparator      = '=';
};

/**
 * This class implements Resource Record (RR) body format.
 *
 */
OT_TOOL_PACKED_BEGIN
class ResourceRecord
{
    friend class OptRecord;

public:
    // Resource Record Types.
    static constexpr uint16_t kTypeZero  = 0;   ///< Zero as special indicator for the SIG RR (SIG(0) from RFC 2931).
    static constexpr uint16_t kTypeA     = 1;   ///< Address record (IPv4).
    static constexpr uint16_t kTypeSoa   = 6;   ///< Start of (zone of) authority.
    static constexpr uint16_t kTypeCname = 5;   ///< CNAME record.
    static constexpr uint16_t kTypePtr   = 12;  ///< PTR record.
    static constexpr uint16_t kTypeTxt   = 16;  ///< TXT record.
    static constexpr uint16_t kTypeSig   = 24;  ///< SIG record.
    static constexpr uint16_t kTypeKey   = 25;  ///< KEY record.
    static constexpr uint16_t kTypeAaaa  = 28;  ///< IPv6 address record.
    static constexpr uint16_t kTypeSrv   = 33;  ///< SRV locator record.
    static constexpr uint16_t kTypeOpt   = 41;  ///< Option record.
    static constexpr uint16_t kTypeAny   = 255; ///< ANY record.

    // Resource Record Class Codes.
    static constexpr uint16_t kClassInternet = 1;   ///< Class code Internet (IN).
    static constexpr uint16_t kClassNone     = 254; ///< Class code None (NONE) - RFC 2136.
    static constexpr uint16_t kClassAny      = 255; ///< Class code Any (ANY).

    /**
     * This method initializes the resource record by setting its type and class.
     *
     * This method only sets the type and class fields. Other fields (TTL and length) remain unchanged/uninitialized.
     *
     * @param[in] aType   The type of the resource record.
     * @param[in] aClass  The class of the resource record (default is `kClassInternet`).
     *
     */
    void Init(uint16_t aType, uint16_t aClass = kClassInternet)
    {
        SetType(aType);
        SetClass(aClass);
    }

    /**
     * This method indicates whether the resources records matches a given type and class code.
     *
     * @param[in] aType   The resource record type to compare with.
     * @param[in] aClass  The resource record class code to compare with (default is `kClassInternet`).
     *
     * @returns TRUE if the resources records matches @p aType and @p aClass, FALSE otherwise.
     *
     */
    bool Matches(uint16_t aType, uint16_t aClass = kClassInternet)
    {
        return (mType == HostSwap16(aType)) && (mClass == HostSwap16(aClass));
    }

    /**
     * This method returns the type of the resource record.
     *
     * @returns The type of the resource record.
     *
     */
    uint16_t GetType(void) const { return HostSwap16(mType); }

    /**
     * This method sets the type of the resource record.
     *
     * @param[in]  aType The type of the resource record.
     *
     */
    void SetType(uint16_t aType) { mType = HostSwap16(aType); }

    /**
     * This method returns the class of the resource record.
     *
     * @returns The class of the resource record.
     *
     */
    uint16_t GetClass(void) const { return HostSwap16(mClass); }

    /**
     * This method sets the class of the resource record.
     *
     * @param[in]  aClass The class of the resource record.
     *
     */
    void SetClass(uint16_t aClass) { mClass = HostSwap16(aClass); }

    /**
     * This method returns the time to live field of the resource record.
     *
     * @returns The time to live field of the resource record.
     *
     */
    uint32_t GetTtl(void) const { return HostSwap32(mTtl); }

    /**
     * This method sets the time to live field of the resource record.
     *
     * @param[in]  aTtl The time to live field of the resource record.
     *
     */
    void SetTtl(uint32_t aTtl) { mTtl = HostSwap32(aTtl); }

    /**
     * This method returns the length of the resource record data.
     *
     * @returns The length of the resource record data.
     *
     */
    uint16_t GetLength(void) const { return HostSwap16(mLength); }

    /**
     * This method sets the length of the resource record data.
     *
     * @param[in]  aLength The length of the resource record data.
     *
     */
    void SetLength(uint16_t aLength) { mLength = HostSwap16(aLength); }

    /**
     * This method returns the size of (number of bytes) in resource record and its data RDATA section (excluding the
     * name field).
     *
     * @returns Size (number of bytes) of resource record and its data section (excluding the name field)
     *
     */
    uint32_t GetSize(void) const { return sizeof(ResourceRecord) + GetLength(); }

    /**
     * This static method parses and skips over a given number of resource records in a message from a given offset.
     *
     * @param[in]     aMessage     The message from which to parse/read the resource records. `aMessage.GetOffset()`
     *                             MUST point to the start of DNS header.
     * @param[in,out] aOffset      On input the offset in @p aMessage pointing to the start of the first record.
     *                             On exit (when parsed successfully), @p aOffset is updated to point to the byte after
     *                             the last parsed record.
     * @param[in]     aNumRecords  Number of resource records to parse.
     *
     * @retval kErrorNone      Parsed records successfully. @p aOffset is updated.
     * @retval kErrorParse     Could not parse the records from @p aMessage (e.g., ran out of bytes in @p aMessage).
     *
     */
    static Error ParseRecords(const Message &aMessage, uint16_t &aOffset, uint16_t aNumRecords);

    /**
     * This static method searches in a given message to find the first resource record matching a given record name.
     *
     * @param[in]     aMessage       The message in which to search for a matching resource record.
     *                               `aMessage.GetOffset()` MUST point to the start of DNS header.
     * @param[in,out] aOffset        On input, the offset in @p aMessage pointing to the start of the first record.
     *                               On exit, if a matching record is found, @p aOffset is updated to point to the byte
     *                               after the record name.
     *                               If a matching record could not be found, @p aOffset is updated to point to the byte
     *                               after the last record that was checked.
     * @param[in,out] aNumRecords    On input, the maximum number of records to check (starting from @p aOffset).
     *                               On exit and if a matching record is found, @p aNumRecords is updated to give the
     *                               number of remaining records after @p aOffset (excluding the matching record).
     * @param[in]     aName          The record name to match against.
     *
     * @retval kErrorNone         A matching record was found. @p aOffset, @p aNumRecords are updated.
     * @retval kErrorNotFound     A matching record could not be found. @p aOffset and @p aNumRecords are updated.
     * @retval kErrorParse        Could not parse records from @p aMessage (e.g., ran out of bytes in @p aMessage).
     *
     */
    static Error FindRecord(const Message &aMessage, uint16_t &aOffset, uint16_t &aNumRecords, const Name &aName);

    /**
     * This template static method searches in a message to find the i-th occurrence of resource records of specific
     * type with a given record name and if found, reads the record from the message.
     *
     * This method searches in @p aMessage starting from @p aOffset up to maximum of @p aNumRecords, for the
     * `(aIndex+1)`th occurrence of a resource record of `RecordType` with record name @p aName.
     *
     * On success (i.e., when a matching record is found and read from the message), @p aOffset is updated to point
     * to after the last byte read from the message and copied into @p aRecord. This allows the caller to read any
     * remaining fields in the record data.
     *
     * @tparam        RecordType     The resource record type (i.e., a sub-class of `ResourceRecord`).
     *
     * @param[in]     aMessage       The message to search within for matching resource records.
     *                               `aMessage.GetOffset()` MUST point to the start of DNS header.
     * @param[in,out] aOffset        On input, the offset in @p aMessage pointing to the start of the first record.
     *                               On exit and only if a matching record is found, @p aOffset is updated to point to
     *                               the last read byte in the record (allowing caller to read any remaining fields in
     *                               the record data from the message).
     * @param[in]     aNumRecords    The maximum number of records to check (starting from @p aOffset).
     * @param[in]     aIndex         The matching record index to find. @p aIndex value of zero returns the first
     *                               matching record.
     * @param[in]     aName          The record name to match against.
     * @param[in]     aRecord        A reference to a record object to read a matching record into.
     *                               If a matching record is found, `sizeof(RecordType)` bytes from @p aMessage are
     *                               read and copied into @p aRecord.
     *
     * @retval kErrorNone         A matching record was found. @p aOffset is updated.
     * @retval kErrorNotFound     A matching record could not be found.
     * @retval kErrorParse        Could not parse records from @p aMessage (e.g., ran out of bytes in @p aMessage).
     *
     */
    template <class RecordType>
    static Error FindRecord(const Message &aMessage,
                            uint16_t &     aOffset,
                            uint16_t       aNumRecords,
                            uint16_t       aIndex,
                            const Name &   aName,
                            RecordType &   aRecord)
    {
        return FindRecord(aMessage, aOffset, aNumRecords, aIndex, aName, RecordType::kType, aRecord,
                          sizeof(RecordType));
    }

    /**
     * This template static method tries to read a resource record of a given type from a message. If the record type
     * does not matches the type, it skips over the record.
     *
     * This method requires the record name to be already parsed/read from the message. On input, @p aOffset should
     * point to the start of the `ResourceRecord` fields (type, class, TTL, data length) in @p aMessage.
     *
     * This method verifies that the record is well-formed in the message. It then reads the record type and compares
     * it with `RecordType::kType` and ensures that the record size is at least `sizeof(RecordType)`. If it all matches,
     * the record is read into @p aRecord.
     *
     * On success (i.e., when a matching record is read from the message), the @p aOffset is updated to point to after
     * the last byte read from the message and copied into @p aRecord and not necessarily the end of the record.
     *  Depending on the `RecordType` format, there may still be more data bytes left in the record to be read. For
     * example, when reading a SRV record using `SrvRecord` type, @p aOffset would point to after the last field in
     * `SrvRecord`  which is the start of "target host domain name" field.
     *
     * @tparam        RecordType     The resource record type (i.e., a sub-class of `ResourceRecord`).
     *
     * @param[in]     aMessage       The message from which to read the record.
     * @param[in,out] aOffset        On input, the offset in @p aMessage pointing to the byte after the record name.
     *                               On exit, if a matching record is read, @p aOffset is updated to point to the last
     *                               read byte in the record.
     *                               If a matching record could not be read, @p aOffset is updated to point to the byte
     *                               after the entire record (skipping over the record).
     * @param[out]    aRecord        A reference to a record to read a matching record into.
     *                               If a matching record is found, `sizeof(RecordType)` bytes from @p aMessage are
     *                               read and copied into @p aRecord.
     *
     * @retval kErrorNone         A matching record was read successfully. @p aOffset, and @p aRecord are updated.
     * @retval kErrorNotFound     A matching record could not be found. @p aOffset is updated.
     * @retval kErrorParse        Could not parse records from @p aMessage (e.g., ran out of bytes in @p aMessage).
     *
     */
    template <class RecordType> static Error ReadRecord(const Message &aMessage, uint16_t &aOffset, RecordType &aRecord)
    {
        return ReadRecord(aMessage, aOffset, RecordType::kType, aRecord, sizeof(RecordType));
    }

protected:
    Error ReadName(const Message &aMessage,
                   uint16_t &     aOffset,
                   uint16_t       aStartOffset,
                   char *         aNameBuffer,
                   uint16_t       aNameBufferSize,
                   bool           aSkipRecord) const;
    Error SkipRecord(const Message &aMessage, uint16_t &aOffset) const;

private:
    static constexpr uint16_t kType = kTypeAny; // This is intended for used by `ReadRecord<RecordType>()` only.

    static Error FindRecord(const Message & aMessage,
                            uint16_t &      aOffset,
                            uint16_t        aNumRecords,
                            uint16_t        aIndex,
                            const Name &    aName,
                            uint16_t        aType,
                            ResourceRecord &aRecord,
                            uint16_t        aMinRecordSize);

    static Error ReadRecord(const Message & aMessage,
                            uint16_t &      aOffset,
                            uint16_t        aType,
                            ResourceRecord &aRecord,
                            uint16_t        aMinRecordSize);

    Error CheckRecord(const Message &aMessage, uint16_t aOffset) const;
    Error ReadFrom(const Message &aMessage, uint16_t aOffset);

    uint16_t mType;   // The type of the data in RDATA section.
    uint16_t mClass;  // The class of the data in RDATA section.
    uint32_t mTtl;    // Specifies the maximum time that the resource record may be cached.
    uint16_t mLength; // The length of RDATA section in bytes.

} OT_TOOL_PACKED_END;

/**
 * This class implements Resource Record body format of A type.
 *
 */
OT_TOOL_PACKED_BEGIN
class ARecord : public ResourceRecord
{
public:
    static constexpr uint16_t kType = kTypeA; ///< The A record type.

    /**
     * This method initializes the A Resource Record by setting its type, class, and length.
     *
     * Other record fields (TTL, address) remain unchanged/uninitialized.
     *
     */
    void Init(void)
    {
        ResourceRecord::Init(kTypeA);
        SetLength(sizeof(Ip4::Address));
    }

    /**
     * This method sets the IPv4 address of the resource record.
     *
     * @param[in]  aAddress The IPv4 address of the resource record.
     *
     */
    void SetAddress(const Ip4::Address &aAddress) { mAddress = aAddress; }

    /**
     * This method returns the reference to IPv4 address of the resource record.
     *
     * @returns The reference to IPv4 address of the resource record.
     *
     */
    const Ip4::Address &GetAddress(void) const { return mAddress; }

private:
    Ip4::Address mAddress; // IPv4 Address of A Resource Record.
} OT_TOOL_PACKED_END;

/**
 * This class implements Resource Record body format of CNAME type.
 *
 */
OT_TOOL_PACKED_BEGIN
class CnameRecord : public ResourceRecord
{
public:
    static constexpr uint16_t kType = kTypeCname; ///< The CNAME record type.

    /**
     * This method initializes the CNAME Resource Record by setting its type and class.
     *
     * Other record fields (TTL, length) remain unchanged/uninitialized.
     *
     * @param[in] aClass  The class of the resource record (default is `kClassInternet`).
     *
     */
    void Init(uint16_t aClass = kClassInternet) { ResourceRecord::Init(kTypeCname, aClass); }

    /**
     * This method parses and reads the CNAME alias name from a message.
     *
     * This method also verifies that the CNAME record is well-formed (e.g., the record data length `GetLength()`
     * matches the CNAME encoded name).
     *
     * @param[in]      aMessage         The message to read from. `aMessage.GetOffset()` MUST point to the start of
     *                                  DNS header.
     * @param[in,out]  aOffset          On input, the offset in @p aMessage to start of CNAME name field.
     *                                  On exit when successfully read, @p aOffset is updated to point to the byte
     *                                  after the entire PTR record (skipping over the record).
     * @param[out]     aNameBuffer      A pointer to a char array to output the read name as a null-terminated C string
     *                                  (MUST NOT be `nullptr`).
     * @param[in]      aNameBufferSize  The size of @p aNameBuffer.
     *
     * @retval kErrorNone           The CNAME name was read successfully. @p aOffset and @p aNameBuffer are updated.
     * @retval kErrorParse          The CNAME record in @p aMessage could not be parsed (invalid format).
     * @retval kErrorNoBufs         Name could not fit in @p aNameBufferSize chars.
     *
     */
    Error ReadCanonicalName(const Message &aMessage,
                            uint16_t &     aOffset,
                            char *         aNameBuffer,
                            uint16_t       aNameBufferSize) const
    {
        return ResourceRecord::ReadName(aMessage, aOffset, /* aStartOffset */ aOffset - sizeof(CnameRecord),
                                        aNameBuffer, aNameBufferSize, /* aSkipRecord */ true);
    }

} OT_TOOL_PACKED_END;

/**
 * This class implements Resource Record body format of PTR type.
 *
 */
OT_TOOL_PACKED_BEGIN
class PtrRecord : public ResourceRecord
{
public:
    static constexpr uint16_t kType = kTypePtr; ///< The PTR record type.

    /**
     * This method initializes the PTR Resource Record by setting its type and class.
     *
     * Other record fields (TTL, length) remain unchanged/uninitialized.
     *
     * @param[in] aClass  The class of the resource record (default is `kClassInternet`).
     *
     */
    void Init(uint16_t aClass = kClassInternet) { ResourceRecord::Init(kTypePtr, aClass); }

    /**
     * This method parses and reads the PTR name from a message.
     *
     * This method also verifies that the PTR record is well-formed (e.g., the record data length `GetLength()` matches
     * the PTR encoded name).
     *
     * @param[in]      aMessage         The message to read from.  `aMessage.GetOffset()` MUST point to the start of
     *                                  DNS header.
     * @param[in,out]  aOffset          On input, the offset in @p aMessage to start of PTR name field.
     *                                  On exit when successfully read, @p aOffset is updated to point to the byte
     *                                  after the entire PTR record (skipping over the record).
     * @param[out]     aNameBuffer      A pointer to a char array to output the read name as a null-terminated C string
     *                                  (MUST NOT be `nullptr`).
     * @param[in]      aNameBufferSize  The size of @p aNameBuffer.
     *
     * @retval kErrorNone           The PTR name was read successfully. @p aOffset and @p aNameBuffer are updated.
     * @retval kErrorParse          The PTR record in @p aMessage could not be parsed (invalid format).
     * @retval kErrorNoBufs         Name could not fit in @p aNameBufferSize chars.
     *
     */
    Error ReadPtrName(const Message &aMessage, uint16_t &aOffset, char *aNameBuffer, uint16_t aNameBufferSize) const
    {
        return ResourceRecord::ReadName(aMessage, aOffset, /* aStartOffset */ aOffset - sizeof(PtrRecord), aNameBuffer,
                                        aNameBufferSize,
                                        /* aSkipRecord */ true);
    }

    /**
     * This method parses and reads the PTR name from a message.
     *
     * This method also verifies that the PTR record is well-formed (e.g., the record data length `GetLength()` matches
     * the PTR encoded name).
     *
     * Unlike the previous method which reads the entire PTR name into a single char buffer, this method reads the
     * first label separately and into a different buffer @p aLabelBuffer and the rest of the name into @p aNameBuffer.
     * The @p aNameBuffer can be set to `nullptr` if the caller is only interested in the first label. This method is
     * intended for "Service Instance Name" where first label (`<Instance>` portion) can be a user-friendly string and
     * can contain dot character.
     *
     * @param[in]      aMessage          The message to read from. `aMessage.GetOffset()` MUST point to the start of
     *                                   DNS header.
     * @param[in,out]  aOffset           On input, the offset in @p aMessage to the start of PTR name field.
     *                                   On exit, when successfully read, @p aOffset is updated to point to the byte
     *                                   after the entire PTR record (skipping over the record).
     * @param[out]     aLabelBuffer      A pointer to a char array to output the first label as a null-terminated C
     *                                   string (MUST NOT be `nullptr`).
     * @param[in]      aLabelBufferSize  The size of @p aLabelBuffer.
     * @param[out]     aNameBuffer       A pointer to a char array to output the rest of name (after first label). Can
     *                                   be `nullptr` if caller is only interested in the first label.
     * @param[in]      aNameBufferSize   The size of @p aNameBuffer.
     *
     * @retval kErrorNone    The PTR name was read successfully. @p aOffset, @aLabelBuffer and @aNameBuffer are updated.
     * @retval kErrorParse   The PTR record in @p aMessage could not be parsed (invalid format).
     * @retval kErrorNoBufs  Either label or name could not fit in the related char buffers.
     *
     */
    Error ReadPtrName(const Message &aMessage,
                      uint16_t &     aOffset,
                      char *         aLabelBuffer,
                      uint8_t        aLabelBufferSize,
                      char *         aNameBuffer,
                      uint16_t       aNameBufferSize) const;

} OT_TOOL_PACKED_END;

/**
 * This class implements Resource Record body format of TXT type.
 *
 */
OT_TOOL_PACKED_BEGIN
class TxtRecord : public ResourceRecord
{
public:
    static constexpr uint16_t kType = kTypeTxt; ///< The TXT record type.

    /**
     * This method initializes the TXT Resource Record by setting its type and class.
     *
     * Other record fields (TTL, length) remain unchanged/uninitialized.
     *
     * @param[in] aClass  The class of the resource record (default is `kClassInternet`).
     *
     */
    void Init(uint16_t aClass = kClassInternet) { ResourceRecord::Init(kTypeTxt, aClass); }

    /**
     * This method parses and reads the TXT record data from a message.
     *
     * This method also checks if the TXT data is well-formed by calling `VerifyTxtData()`.
     *
     * @param[in]      aMessage         The message to read from.
     * @param[in,out]  aOffset          On input, the offset in @p aMessage to start of TXT record data.
     *                                  On exit when successfully read, @p aOffset is updated to point to the byte
     *                                  after the entire TXT record (skipping over the record).
     * @param[out]     aTxtBuffer       A pointer to a byte array to output the read TXT data.
     * @param[in,out]  aTxtBufferSize   On input, the size of @p aTxtBuffer (max bytes that can be read).
     *                                  On exit, @p aTxtBufferSize gives number of bytes written to @p aTxtBuffer.
     *
     * @retval kErrorNone           The TXT data was read successfully. @p aOffset, @p aTxtBuffer and @p aTxtBufferSize
     *                              are updated.
     * @retval kErrorParse          The TXT record in @p aMessage could not be parsed (invalid format).
     * @retval kErrorNoBufs         TXT data could not fit in @p aTxtBufferSize bytes.
     *
     */
    Error ReadTxtData(const Message &aMessage, uint16_t &aOffset, uint8_t *aTxtBuffer, uint16_t &aTxtBufferSize) const;

    /**
     * This static method tests if a buffer contains valid encoded TXT data.
     *
     * @param[in]  aTxtData     The TXT data buffer.
     * @param[in]  aTxtLength   The length of the TXT data buffer.
     * @param[in]  aAllowEmpty  True if zero-length TXT data is allowed.
     *
     * @returns  TRUE if @p aTxtData contains valid encoded TXT data, FALSE if not.
     *
     */
    static bool VerifyTxtData(const uint8_t *aTxtData, uint16_t aTxtLength, bool aAllowEmpty);

} OT_TOOL_PACKED_END;

/**
 * This class implements Resource Record body format of AAAA type.
 *
 */
OT_TOOL_PACKED_BEGIN
class AaaaRecord : public ResourceRecord
{
public:
    static constexpr uint16_t kType = kTypeAaaa; ///< The AAAA record type.

    /**
     * This method initializes the AAAA Resource Record by setting its type, class, and length.
     *
     * Other record fields (TTL, address) remain unchanged/uninitialized.
     *
     */
    void Init(void)
    {
        ResourceRecord::Init(kTypeAaaa);
        SetLength(sizeof(Ip6::Address));
    }

    /**
     * This method tells whether this is a valid AAAA record.
     *
     * @returns  A boolean indicates whether this is a valid AAAA record.
     *
     */
    bool IsValid(void) const;

    /**
     * This method sets the IPv6 address of the resource record.
     *
     * @param[in]  aAddress The IPv6 address of the resource record.
     *
     */
    void SetAddress(const Ip6::Address &aAddress) { mAddress = aAddress; }

    /**
     * This method returns the reference to IPv6 address of the resource record.
     *
     * @returns The reference to IPv6 address of the resource record.
     *
     */
    const Ip6::Address &GetAddress(void) const { return mAddress; }

private:
    Ip6::Address mAddress; // IPv6 Address of AAAA Resource Record.
} OT_TOOL_PACKED_END;

/**
 * This class implements Resource Record body format of SRV type (RFC 2782).
 *
 */
OT_TOOL_PACKED_BEGIN
class SrvRecord : public ResourceRecord
{
public:
    static constexpr uint16_t kType = kTypeSrv; ///< The SRV record type.

    /**
     * This method initializes the SRV Resource Record by settings its type and class.
     *
     * Other record fields (TTL, length, propriety, weight, port, ...) remain unchanged/uninitialized.
     *
     * @param[in] aClass  The class of the resource record (default is `kClassInternet`).
     *
     */
    void Init(uint16_t aClass = kClassInternet) { ResourceRecord::Init(kTypeSrv, aClass); }

    /**
     * This method returns the SRV record's priority value.
     *
     * @returns The priority value.
     *
     */
    uint16_t GetPriority(void) const { return HostSwap16(mPriority); }

    /**
     * This method sets the SRV record's priority value.
     *
     * @param[in]  aPriority  The priority value.
     *
     */
    void SetPriority(uint16_t aPriority) { mPriority = HostSwap16(aPriority); }

    /**
     * This method returns the SRV record's weight value.
     *
     * @returns The weight value.
     *
     */
    uint16_t GetWeight(void) const { return HostSwap16(mWeight); }

    /**
     * This method sets the SRV record's weight value.
     *
     * @param[in]  aWeight  The weight value.
     *
     */
    void SetWeight(uint16_t aWeight) { mWeight = HostSwap16(aWeight); }

    /**
     * This method returns the SRV record's port number on the target host for this service.
     *
     * @returns The port number.
     *
     */
    uint16_t GetPort(void) const { return HostSwap16(mPort); }

    /**
     * This method sets the SRV record's port number on the target host for this service.
     *
     * @param[in]  aPort  The port number.
     *
     */
    void SetPort(uint16_t aPort) { mPort = HostSwap16(aPort); }

    /**
     * This method parses and reads the SRV target host name from a message.
     *
     * This method also verifies that the SRV record is well-formed (e.g., the record data length `GetLength()` matches
     * the SRV encoded name).
     *
     * @param[in]      aMessage         The message to read from. `aMessage.GetOffset()` MUST point to the start of
     *                                  DNS header.
     * @param[in,out]  aOffset          On input, the offset in @p aMessage to start of target host name field.
     *                                  On exit when successfully read, @p aOffset is updated to point to the byte
     *                                  after the entire SRV record (skipping over the record).
     * @param[out]     aNameBuffer      A pointer to a char array to output the read name as a null-terminated C string
     *                                  (MUST NOT be `nullptr`).
     * @param[in]      aNameBufferSize  The size of @p aNameBuffer.
     *
     * @retval kErrorNone            The host name was read successfully. @p aOffset and @p aNameBuffer are updated.
     * @retval kErrorParse           The SRV record in @p aMessage could not be parsed (invalid format).
     * @retval kErrorNoBufs          Name could not fit in @p aNameBufferSize chars.
     *
     */
    Error ReadTargetHostName(const Message &aMessage,
                             uint16_t &     aOffset,
                             char *         aNameBuffer,
                             uint16_t       aNameBufferSize) const
    {
        return ResourceRecord::ReadName(aMessage, aOffset, /* aStartOffset */ aOffset - sizeof(SrvRecord), aNameBuffer,
                                        aNameBufferSize,
                                        /* aSkipRecord */ true);
    }

private:
    uint16_t mPriority;
    uint16_t mWeight;
    uint16_t mPort;
    // Followed by the target host domain name.

} OT_TOOL_PACKED_END;

/**
 * This class implements Resource Record body format of KEY type (RFC 2535).
 *
 */
OT_TOOL_PACKED_BEGIN
class KeyRecord : public ResourceRecord
{
public:
    static constexpr uint16_t kType = kTypeKey; ///< The KEY record type.

    // Protocol field values (RFC 2535 - section 3.1.3).
    static constexpr uint8_t kProtocolTls    = 1; ///< TLS protocol code.
    static constexpr uint8_t kProtocolDnsSec = 3; ///< DNS security protocol code.

    // Algorithm field values (RFC 8624 - section 3.1).
    static constexpr uint8_t kAlgorithmEcdsaP256Sha256 = 13; ///< ECDSA-P256-SHA256 algorithm.
    static constexpr uint8_t kAlgorithmEcdsaP384Sha384 = 14; ///< ECDSA-P384-SHA384 algorithm.
    static constexpr uint8_t kAlgorithmEd25519         = 15; ///< ED25519 algorithm.
    static constexpr uint8_t kAlgorithmEd448           = 16; ///< ED448 algorithm.

    /**
     * This enumeration type represents the use (or key type) flags (RFC 2535 - section 3.1.2).
     *
     */
    enum UseFlags : uint8_t
    {
        kAuthConfidPermitted = 0x00, ///< Use of the key for authentication and/or confidentiality is permitted.
        kAuthPermitted       = 0x40, ///< Use of the key is only permitted for authentication.
        kConfidPermitted     = 0x80, ///< Use of the key is only permitted for confidentiality.
        kNoKey               = 0xc0, ///< No key value (e.g., can indicate zone is not secure).
    };

    /**
     * This enumeration type represents key owner (or name type) flags (RFC 2535 - section 3.1.2).
     *
     */
    enum OwnerFlags : uint8_t
    {
        kOwnerUser     = 0x00, ///< Key is associated with a "user" or "account" at end entity.
        kOwnerZone     = 0x01, ///< Key is a zone key (used for data origin authentication).
        kOwnerNonZone  = 0x02, ///< Key is associated with a non-zone "entity".
        kOwnerReserved = 0x03, ///< Reserved for future use.
    };

    // Constants for flag bits for the "signatory" flags (RFC 2137).
    //
    // The flags defined are for non-zone (`kOwnerNoneZone`) keys (RFC 2137 - section 3.1.3).

    /**
     * Key is authorized to attach, detach, and move zones.
     *
     */
    static constexpr uint8_t kSignatoryFlagZone = 1 << 3;

    /**
     * Key is authorized to add and delete RRs even if RRs auth with other key.
     *
     */
    static constexpr uint8_t kSignatoryFlagStrong = 1 << 2;

    /**
     * Key is authorized to add and update RRs for only a single owner name.
     *
     */
    static constexpr uint8_t kSignatoryFlagUnique = 1 << 1;

    /**
     * If the other flags are zero, this is used to indicate it is an update key.
     *
     */
    static constexpr uint8_t kSignatoryFlagGeneral = 1 << 0;

    /**
     * This method initializes the KEY Resource Record by setting its type and class.
     *
     * Other record fields (TTL, length, flags, protocol, algorithm) remain unchanged/uninitialized.
     *
     * @param[in] aClass  The class of the resource record (default is `kClassInternet`).
     *
     */
    void Init(uint16_t aClass = kClassInternet) { ResourceRecord::Init(kTypeKey, aClass); }

    /**
     * This method tells whether the KEY record is valid.
     *
     * @returns  TRUE if this is a valid KEY record, FALSE if an invalid KEY record.
     *
     */
    bool IsValid(void) const;

    /**
     * This method gets the key use (or key type) flags.
     *
     * @returns The key use flags.
     *
     */
    UseFlags GetUseFlags(void) const { return static_cast<UseFlags>(mFlags[0] & kUseFlagsMask); }

    /**
     * This method gets the owner (or name type) flags.
     *
     * @returns The key owner flags.
     *
     */
    OwnerFlags GetOwnerFlags(void) const { return static_cast<OwnerFlags>(mFlags[0] & kOwnerFlagsMask); }

    /**
     * This method gets the signatory flags.
     *
     * @returns The signatory flags.
     *
     */
    uint8_t GetSignatoryFlags(void) const { return (mFlags[1] & kSignatoryFlagsMask); }

    /**
     * This method sets the flags field.
     *
     * @param[in] aUseFlags        The `UseFlags` value.
     * @param[in] aOwnerFlags      The `OwnerFlags` value.
     * @param[in] aSignatoryFlags  The signatory flags.
     *
     */
    void SetFlags(UseFlags aUseFlags, OwnerFlags aOwnerFlags, uint8_t aSignatoryFlags)
    {
        mFlags[0] = (static_cast<uint8_t>(aUseFlags) | static_cast<uint8_t>(aOwnerFlags));
        mFlags[1] = (aSignatoryFlags & kSignatoryFlagsMask);
    }

    /**
     * This method returns the KEY record's protocol value.
     *
     * @returns The protocol value.
     *
     */
    uint8_t GetProtocol(void) const { return mProtocol; }

    /**
     * This method sets the KEY record's protocol value.
     *
     * @param[in]  aProtocol  The protocol value.
     *
     */
    void SetProtocol(uint8_t aProtocol) { mProtocol = aProtocol; }

    /**
     * This method returns the KEY record's algorithm value.
     *
     * @returns The algorithm value.
     *
     */
    uint8_t GetAlgorithm(void) const { return mAlgorithm; }

    /**
     * This method sets the KEY record's algorithm value.
     *
     * @param[in]  aAlgorithm  The algorithm value.
     *
     */
    void SetAlgorithm(uint8_t aAlgorithm) { mAlgorithm = aAlgorithm; }

private:
    static constexpr uint8_t kUseFlagsMask       = 0xc0; // top two bits in the first flag byte.
    static constexpr uint8_t kOwnerFlagsMask     = 0x03; // lowest two bits in the first flag byte.
    static constexpr uint8_t kSignatoryFlagsMask = 0x0f; // lower 4 bits in the second flag byte.

    // Flags format:
    //
    //    0   1   2   3   4   5   6   7   8   9   0   1   2   3   4   5
    //  +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
    //  |  Use  | Z | XT| Z | Z | Owner | Z | Z | Z | Z |      SIG      |
    //  +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
    //  \                              / \                             /
    //   ---------- mFlags[0] ---------   -------- mFlags[1] ----------

    uint8_t mFlags[2];
    uint8_t mProtocol;
    uint8_t mAlgorithm;
    // Followed by the public key

} OT_TOOL_PACKED_END;

#if OPENTHREAD_CONFIG_SRP_SERVER_ENABLE
OT_TOOL_PACKED_BEGIN
class Ecdsa256KeyRecord : public KeyRecord, public Clearable<Ecdsa256KeyRecord>, public Equatable<Ecdsa256KeyRecord>
{
public:
    /**
     * This method initializes the KEY Resource Record to ECDSA with curve P-256.
     *
     * Other record fields (TTL, length, flags, protocol) remain unchanged/uninitialized.
     *
     */
    void Init(void);

    /**
     * This method tells whether this is a valid ECDSA DNSKEY with curve P-256.
     *
     * @returns  A boolean that indicates whether this is a valid ECDSA DNSKEY RR with curve P-256.
     *
     */
    bool IsValid(void) const;

    /**
     * This method returns the ECDSA P-256 public kek.
     *
     * @returns  A reference to the public key.
     *
     */
    const Crypto::Ecdsa::P256::PublicKey &GetKey(void) const { return mKey; }

private:
    Crypto::Ecdsa::P256::PublicKey mKey;
} OT_TOOL_PACKED_END;
#endif // OPENTHREAD_CONFIG_SRP_SERVER_ENABLE

/**
 * This class implements Resource Record body format of SIG type (RFC 2535 - section-4.1).
 *
 *
 */
OT_TOOL_PACKED_BEGIN
class SigRecord : public ResourceRecord, public Clearable<SigRecord>
{
public:
    static constexpr uint16_t kType = kTypeSig; ///< The SIG record type.

    /**
     * This method initializes the SIG Resource Record by setting its type and class.
     *
     * Other record fields (TTL, length, ...) remain unchanged/uninitialized.
     *
     * SIG(0) requires SIG RR to set class field as ANY or `kClassAny` (RFC 2931 - section 3).
     *
     * @param[in] aClass  The class of the resource record.
     *
     */
    void Init(uint16_t aClass) { ResourceRecord::Init(kTypeSig, aClass); }

    /**
     * This method tells whether the SIG record is valid.
     *
     * @returns  TRUE if this is a valid SIG record, FALSE if not a valid SIG record.
     *
     */
    bool IsValid(void) const;

    /**
     * This method returns the SIG record's type-covered value.
     *
     * @returns The type-covered value.
     *
     */
    uint16_t GetTypeCovered(void) const { return HostSwap16(mTypeCovered); }

    /**
     * This method sets the SIG record's type-covered value.
     *
     * @param[in]  aTypeCovered  The type-covered value.
     *
     */
    void SetTypeCovered(uint8_t aTypeCovered) { mTypeCovered = HostSwap16(aTypeCovered); }

    /**
     * This method returns the SIG record's algorithm value.
     *
     * @returns The algorithm value.
     *
     */
    uint8_t GetAlgorithm(void) const { return mAlgorithm; }

    /**
     * This method sets the SIG record's algorithm value.
     *
     * @param[in]  aAlgorithm  The algorithm value.
     *
     */
    void SetAlgorithm(uint8_t aAlgorithm) { mAlgorithm = aAlgorithm; }

    /**
     * This method returns the SIG record's labels-count (number of labels, not counting null label, in the original
     * name of the owner).
     *
     * @returns The labels-count value.
     *
     */
    uint8_t GetLabels(void) const { return mLabels; }

    /**
     * This method sets the SIG record's labels-count (number of labels, not counting null label, in the original
     * name of the owner).
     *
     * @param[in]  aLabels  The labels-count value.
     *
     */
    void SetLabels(uint8_t aLabels) { mLabels = aLabels; }

    /**
     * This method returns the SIG record's original TTL value.
     *
     * @returns The original TTL value.
     *
     */
    uint32_t GetOriginalTtl(void) const { return HostSwap32(mOriginalTtl); }

    /**
     * This method sets the SIG record's original TTL value.
     *
     * @param[in]  aOriginalTtl  The original TTL value.
     *
     */
    void SetOriginalTtl(uint32_t aOriginalTtl) { mOriginalTtl = HostSwap32(aOriginalTtl); }

    /**
     * This method returns the SIG record's expiration time value.
     *
     * @returns The expiration time value (seconds since Jan 1, 1970).
     *
     */
    uint32_t GetExpiration(void) const { return HostSwap32(mExpiration); }

    /**
     * This method sets the SIG record's expiration time value.
     *
     * @param[in]  aExpiration  The expiration time value (seconds since Jan 1, 1970).
     *
     */
    void SetExpiration(uint32_t aExpiration) { mExpiration = HostSwap32(aExpiration); }

    /**
     * This method returns the SIG record's inception time value.
     *
     * @returns The inception time value (seconds since Jan 1, 1970).
     *
     */
    uint32_t GetInception(void) const { return HostSwap32(mInception); }

    /**
     * This method sets the SIG record's inception time value.
     *
     * @param[in]  aInception  The inception time value (seconds since Jan 1, 1970).
     *
     */
    void SetInception(uint32_t aInception) { mInception = HostSwap32(aInception); }

    /**
     * This method returns the SIG record's key tag value.
     *
     * @returns The key tag value.
     *
     */
    uint16_t GetKeyTag(void) const { return HostSwap16(mKeyTag); }

    /**
     * This method sets the SIG record's key tag value.
     *
     * @param[in]  aKeyTag  The key tag value.
     *
     */
    void SetKeyTag(uint16_t aKeyTag) { mKeyTag = HostSwap16(aKeyTag); }

    /**
     * This method returns a pointer to the start of the record data fields.
     *
     * @returns A pointer to the start of the record data fields.
     *
     */
    const uint8_t *GetRecordData(void) const { return reinterpret_cast<const uint8_t *>(&mTypeCovered); }

    /**
     * This method parses and reads the SIG signer name from a message.
     *
     * @param[in]      aMessage         The message to read from. `aMessage.GetOffset()` MUST point to the start of DNS
     *                                  header.
     * @param[in,out]  aOffset          On input, the offset in @p aMessage to start of signer name field.
     *                                  On exit when successfully read, @p aOffset is updated to point to the byte
     *                                  after the name field (i.e., start of signature field).
     * @param[out]     aNameBuffer      A pointer to a char array to output the read name as a null-terminated C string
     *                                  (MUST NOT be `nullptr`).
     * @param[in]      aNameBufferSize  The size of @p aNameBuffer.
     *
     * @retval kErrorNone           The name was read successfully. @p aOffset and @p aNameBuffer are updated.
     * @retval kErrorParse          The SIG record in @p aMessage could not be parsed (invalid format).
     * @retval kErrorNoBufs         Name could not fit in @p aNameBufferSize chars.
     *
     */
    Error ReadSignerName(const Message &aMessage, uint16_t &aOffset, char *aNameBuffer, uint16_t aNameBufferSize) const
    {
        return ResourceRecord::ReadName(aMessage, aOffset, /* aStartOffset */ aOffset - sizeof(SigRecord), aNameBuffer,
                                        aNameBufferSize,
                                        /* aSkipRecord */ false);
    }

private:
    uint16_t mTypeCovered; // type of the other RRs covered by this SIG. set to zero for SIG(0).
    uint8_t  mAlgorithm;   // Algorithm number (see `KeyRecord` enumeration).
    uint8_t  mLabels;      // Number of labels (not counting null label) in the original name of the owner of RR.
    uint32_t mOriginalTtl; // Original time-to-live (should set to zero for SIG(0)).
    uint32_t mExpiration;  // Signature expiration time (seconds since Jan 1, 1970).
    uint32_t mInception;   // Signature inception time (seconds since Jan 1, 1970).
    uint16_t mKeyTag;      // Key tag.
    // Followed by signer name fields and signature fields
} OT_TOOL_PACKED_END;

/**
 * This class implements DNS OPT Pseudo Resource Record header for EDNS(0) (RFC 6891 - Section 6.1).
 *
 */
OT_TOOL_PACKED_BEGIN
class OptRecord : public ResourceRecord
{
public:
    static constexpr uint16_t kType = kTypeOpt; ///< The OPT record type.

    /**
     * This method initializes the OPT Resource Record by setting its type and clearing extended Response Code, version
     * and all flags.
     *
     * Other record fields (UDP payload size, length) remain unchanged/uninitialized.
     *
     */
    void Init(void)
    {
        SetType(kTypeOpt);
        SetTtl(0);
    }

    /**
     * This method gets the requester's UDP payload size (the number of bytes of the largest UDP payload that can be
     * delivered in the requester's network).
     *
     * The field is encoded in the CLASS field.
     *
     * @returns The UDP payload size.
     *
     */
    uint16_t GetUdpPayloadSize(void) const { return GetClass(); }

    /**
     * This method gets the requester's UDP payload size (the number of bytes of the largest UDP payload that can be
     * delivered in the requester's network).
     *
     * @param[in] aPayloadSize  The UDP payload size.
     *
     */
    void SetUdpPayloadSize(uint16_t aPayloadSize) { SetClass(aPayloadSize); }

    /**
     * This method gets the upper 8-bit of the extended 12-bit Response Code.
     *
     * Value of 0 indicates that an unextended Response code is in use.
     *
     * @return The upper 8-bit of the extended 12-bit Response Code.
     *
     */
    uint8_t GetExtendedResponseCode(void) const { return GetTtlByteAt(kExtRCodeByteIndex); }

    /**
     * This method sets the upper 8-bit of the extended 12-bit Response Code.
     *
     * Value of 0 indicates that an unextended Response code is in use.
     *
     * @param[in] aExtendedResponse The upper 8-bit of the extended 12-bit Response Code.
     *
     */
    void SetExtnededResponseCode(uint8_t aExtendedResponse) { GetTtlByteAt(kExtRCodeByteIndex) = aExtendedResponse; }

    /**
     * This method gets the Version field.
     *
     * @returns The version.
     *
     */
    uint8_t GetVersion(void) const { return GetTtlByteAt(kVersionByteIndex); }

    /**
     * This method set the Version field.
     *
     * @param[in] aVersion  The version.
     *
     */
    void SetVersion(uint8_t aVersion) { GetTtlByteAt(kVersionByteIndex) = aVersion; }

    /**
     * This method indicates whether the DNSSEC OK flag is set or not.
     *
     * @returns True if DNSSEC OK flag is set in the header, false otherwise.
     *
     */
    bool IsDnsSecurityFlagSet(void) const { return (GetTtlByteAt(kFlagByteIndex) & kDnsSecFlag) != 0; }

    /**
     * This method clears the DNSSEC OK bit flag.
     *
     */
    void ClearDnsSecurityFlag(void) { GetTtlByteAt(kFlagByteIndex) &= ~kDnsSecFlag; }

    /**
     * This method sets the DNSSEC OK bit flag.
     *
     */
    void SetDnsSecurityFlag(void) { GetTtlByteAt(kFlagByteIndex) |= kDnsSecFlag; }

private:
    // The OPT RR re-purposes the existing CLASS and TTL fields in the
    // RR. The CLASS field (`uint16_t`) is used for requester UDP
    // payload size. The TTL field is used for extended Response Code,
    // version and flags as follows:
    //
    //    0   1   2   3   4   5   6   7   8   9   0   1   2   3   4   5
    //  +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
    //  |         EXTENDED-RCODE        |            VERSION            |
    //  +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
    //  | DO|                Z          |             Z                 |
    //  +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
    //
    // The variable data part of OPT RR can contain zero of more `Option`.

    static constexpr uint8_t kExtRCodeByteIndex = 0;      // Byte index of Extended RCODE within the TTL field.
    static constexpr uint8_t kVersionByteIndex  = 1;      // Byte index of Version within the TTL field.
    static constexpr uint8_t kFlagByteIndex     = 2;      // Byte index of flag byte within the TTL field.
    static constexpr uint8_t kDnsSecFlag        = 1 << 7; // DNSSec OK bit flag.

    uint8_t  GetTtlByteAt(uint8_t aIndex) const { return reinterpret_cast<const uint8_t *>(&mTtl)[aIndex]; }
    uint8_t &GetTtlByteAt(uint8_t aIndex) { return reinterpret_cast<uint8_t *>(&mTtl)[aIndex]; }

} OT_TOOL_PACKED_END;

/**
 * This class implements the body of an Option in OPT Pseudo Resource Record (RFC 6981 - Section 6.1).
 *
 */
OT_TOOL_PACKED_BEGIN
class Option
{
public:
    static constexpr uint16_t kUpdateLease = 2; ///< Update lease option code.

    /**
     * This method returns the option code value.
     *
     * @returns The option code value.
     *
     */
    uint16_t GetOptionCode(void) const { return HostSwap16(mOptionCode); }

    /**
     * This method sets the option code value.
     *
     * @param[in]  aOptionCode  The option code value.
     *
     */
    void SetOptionCode(uint16_t aOptionCode) { mOptionCode = HostSwap16(aOptionCode); }

    /**
     * This method returns the option length value.
     *
     * @returns The option length (size of option data in bytes).
     *
     */
    uint16_t GetOptionLength(void) const { return HostSwap16(mOptionLength); }

    /**
     * This method sets the option length value.
     *
     * @param[in]  aOptionLength  The option length (size of option data in bytes).
     *
     */
    void SetOptionLength(uint16_t aOptionLength) { mOptionLength = HostSwap16(aOptionLength); }

    /**
     * This method returns the size of (number of bytes) in the Option and its data.
     *
     * @returns Size (number of bytes) of the Option its data section.
     *
     */
    uint32_t GetSize(void) const { return sizeof(Option) + GetOptionLength(); }

private:
    uint16_t mOptionCode;
    uint16_t mOptionLength;
    // Followed by Option data (varies per option code).

} OT_TOOL_PACKED_END;

/**
 * This class implements an Update Lease Option body.
 *
 * This implementation is intended for use in Dynamic DNS Update Lease Requests and Responses as specified in
 * https://tools.ietf.org/html/draft-sekar-dns-ul-02.
 *
 */
OT_TOOL_PACKED_BEGIN
class LeaseOption : public Option
{
public:
    static constexpr uint16_t kOptionLength = sizeof(uint32_t) + sizeof(uint32_t); ///< lease and key lease values

    /**
     * This method initialize the Update Lease Option by setting the Option Code and Option Length.
     *
     * The lease and key lease intervals remain unchanged/uninitialized.
     *
     */
    void Init(void)
    {
        SetOptionCode(kUpdateLease);
        SetOptionLength(kOptionLength);
    }

    /**
     * This method tells whether this is a valid Lease Option.
     *
     * @returns  TRUE if this is a valid Lease Option, FALSE if not a valid Lease Option.
     *
     */
    bool IsValid(void) const;

    /**
     * This method returns the Update Lease OPT record's lease interval value.
     *
     * @returns The lease interval value (in seconds).
     *
     */
    uint32_t GetLeaseInterval(void) const { return HostSwap32(mLeaseInterval); }

    /**
     * This method sets the Update Lease OPT record's lease interval value.
     *
     * @param[in]  aLeaseInterval  The lease interval value.
     *
     */
    void SetLeaseInterval(uint32_t aLeaseInterval) { mLeaseInterval = HostSwap32(aLeaseInterval); }

    /**
     * This method returns the Update Lease OPT record's key lease interval value.
     *
     * @returns The key lease interval value (in seconds).
     *
     */
    uint32_t GetKeyLeaseInterval(void) const { return HostSwap32(mKeyLeaseInterval); }

    /**
     * This method sets the Update Lease OPT record's key lease interval value.
     *
     * @param[in]  aKeyLeaseInterval  The key lease interval value (in seconds).
     *
     */
    void SetKeyLeaseInterval(uint32_t aKeyLeaseInterval) { mKeyLeaseInterval = HostSwap32(aKeyLeaseInterval); }

private:
    uint32_t mLeaseInterval;
    uint32_t mKeyLeaseInterval;
} OT_TOOL_PACKED_END;

/**
 * This class implements Question format.
 *
 */
OT_TOOL_PACKED_BEGIN
class Question
{
public:
    /**
     * Default constructor for Question
     *
     */
    Question(void) = default;

    /**
     * Constructor for Question.
     *
     */
    explicit Question(uint16_t aType, uint16_t aClass = ResourceRecord::kClassInternet)
    {
        SetType(aType);
        SetClass(aClass);
    }

    /**
     * This method returns the type of the question.
     *
     * @returns The type of the question.
     *
     */
    uint16_t GetType(void) const { return HostSwap16(mType); }

    /**
     * This method sets the type of the question.
     *
     * @param[in]  aType The type of the question.
     *
     */
    void SetType(uint16_t aType) { mType = HostSwap16(aType); }

    /**
     * This method returns the class of the question.
     *
     * @returns The class of the question.
     *
     */
    uint16_t GetClass(void) const { return HostSwap16(mClass); }

    /**
     * This method sets the class of the question.
     *
     * @param[in]  aClass The class of the question.
     *
     */
    void SetClass(uint16_t aClass) { mClass = HostSwap16(aClass); }

private:
    uint16_t mType;  // The type of the data in question section.
    uint16_t mClass; // The class of the data in question section.
} OT_TOOL_PACKED_END;

/**
 * This class implements Zone section body for DNS Update (RFC 2136 - section 2.3).
 *
 */
OT_TOOL_PACKED_BEGIN
class Zone : public Question
{
public:
    /**
     * Constructor for Zone.
     *
     * @param[in] aClass  The class of the zone (default is `kClassInternet`).
     *
     */
    explicit Zone(uint16_t aClass = ResourceRecord::kClassInternet)
        : Question(ResourceRecord::kTypeSoa, aClass)
    {
    }
} OT_TOOL_PACKED_END;

/**
 * @}
 *
 */

} // namespace Dns

DefineCoreType(otDnsTxtEntry, Dns::TxtEntry);
DefineCoreType(otDnsTxtEntryIterator, Dns::TxtEntry::Iterator);

} // namespace ot

#endif // DNS_HEADER_HPP_
