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

#ifndef DNS_CLIENT_HPP_
#define DNS_CLIENT_HPP_

#include "openthread-core-config.h"

#if OPENTHREAD_CONFIG_DNS_CLIENT_ENABLE

#include <openthread/dns_client.h>

#include "common/as_core_type.hpp"
#include "common/clearable.hpp"
#include "common/message.hpp"
#include "common/non_copyable.hpp"
#include "common/timer.hpp"
#include "net/dns_types.hpp"
#include "net/ip6.hpp"
#include "net/netif.hpp"

/**
 * @file
 *   This file includes definitions for the DNS client.
 */

#if OPENTHREAD_CONFIG_DNS_CLIENT_DEFAULT_SERVER_ADDRESS_AUTO_SET_ENABLE

#if !OPENTHREAD_CONFIG_SRP_CLIENT_ENABLE
#error "DNS_CLIENT_DEFAULT_SERVER_ADDRESS_AUTO_SET_ENABLE requires OPENTHREAD_CONFIG_SRP_CLIENT_ENABLE"
#endif

#if !OPENTHREAD_CONFIG_SRP_CLIENT_AUTO_START_API_ENABLE
#error "DNS_CLIENT_DEFAULT_SERVER_ADDRESS_AUTO_SET_ENABLE requires OPENTHREAD_CONFIG_SRP_CLIENT_AUTO_START_API_ENABLE"
#endif

#endif

#if !OPENTHREAD_CONFIG_TCP_ENABLE && OPENTHREAD_CONFIG_DNS_CLIENT_OVER_TCP_ENABLE
#error "OPENTHREAD_CONFIG_DNS_CLIENT_OVER_TCP_ENABLE requires OPENTHREAD_CONFIG_TCP_ENABLE"
#endif

/**
 * Represents an opaque (and empty) type for a response to an address resolution DNS query.
 *
 */
struct otDnsAddressResponse
{
};

#if OPENTHREAD_CONFIG_DNS_CLIENT_SERVICE_DISCOVERY_ENABLE

/**
 * Represents an opaque (and empty) type for a response to browse (service instance enumeration) DNS query.
 *
 */
struct otDnsBrowseResponse
{
};

/**
 * Represents an opaque (and empty) type for a response to service inst resolution DNS query.
 *
 */
struct otDnsServiceResponse
{
};

#endif // OPENTHREAD_CONFIG_DNS_CLIENT_SERVICE_DISCOVERY_ENABLE

namespace ot {

namespace Srp {
class Client;
}

namespace Dns {

/**
 * Implements DNS client.
 *
 */
class Client : public InstanceLocator, private NonCopyable
{
    friend class ot::Srp::Client;

    typedef Message Query; // `Message` is used to save `Query` related info.

public:
    /**
     * Represents a DNS query configuration (e.g., server address, response wait timeout, etc).
     *
     */
    class QueryConfig : public otDnsQueryConfig, public Clearable<QueryConfig>
    {
        friend class Client;

    public:
        /**
         * Type represents the "Recursion Desired" (RD) flag in a `otDnsQueryConfig`.
         *
         */
        enum RecursionFlag : uint8_t
        {
            kFlagUnspecified      = OT_DNS_FLAG_UNSPECIFIED,       ///< The flag is not specified.
            kFlagRecursionDesired = OT_DNS_FLAG_RECURSION_DESIRED, ///< Server can resolve the query recursively.
            kFlagNoRecursion      = OT_DNS_FLAG_NO_RECURSION,      ///< Server can not resolve the query recursively.
        };

#if OPENTHREAD_CONFIG_DNS_CLIENT_NAT64_ENABLE
        /**
         * Type represents the NAT64 mode.
         *
         */
        enum Nat64Mode : uint8_t
        {
            kNat64Unspecified = OT_DNS_NAT64_UNSPECIFIED, ///< NAT64 mode is not specified. Use default NAT64 mode.
            kNat64Allow       = OT_DNS_NAT64_ALLOW,       ///< Allow NAT64 address translation.
            kNat64Disallow    = OT_DNS_NAT64_DISALLOW,    ///< Disallow NAT64 address translation.
        };
#endif

        /**
         * Type represents the service resolution mode.
         *
         */
        enum ServiceMode : uint8_t
        {
            kServiceModeUnspecified    = OT_DNS_SERVICE_MODE_UNSPECIFIED,      ///< Unspecified. Use default.
            kServiceModeSrv            = OT_DNS_SERVICE_MODE_SRV,              ///< SRV record only.
            kServiceModeTxt            = OT_DNS_SERVICE_MODE_TXT,              ///< TXT record only.
            kServiceModeSrvTxt         = OT_DNS_SERVICE_MODE_SRV_TXT,          ///< SRV and TXT same msg.
            kServiceModeSrvTxtSeparate = OT_DNS_SERVICE_MODE_SRV_TXT_SEPARATE, ///< SRV and TXT separate msgs.
            kServiceModeSrvTxtOptimize = OT_DNS_SERVICE_MODE_SRV_TXT_OPTIMIZE, ///< Same msg first, if fail separate.
        };

        /**
         * Type represents the DNS transport protocol selection.
         *
         */
        enum TransportProto : uint8_t
        {
            kDnsTransportUnspecified = OT_DNS_TRANSPORT_UNSPECIFIED, /// Dns transport is unspecified.
            kDnsTransportUdp         = OT_DNS_TRANSPORT_UDP,         /// Dns query should be sent via UDP.
            kDnsTransportTcp         = OT_DNS_TRANSPORT_TCP,         /// Dns query should be sent via TCP.
        };

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

        /**
         * Gets the server socket address (IPv6 address and port number).
         *
         * @returns The server socket address.
         *
         */
        const Ip6::SockAddr &GetServerSockAddr(void) const
        {
            return static_cast<const Ip6::SockAddr &>(mServerSockAddr);
        }

        /**
         * Gets the wait time to receive response from server (in msec).
         *
         * @returns The timeout interval in msec.
         *
         */
        uint32_t GetResponseTimeout(void) const { return mResponseTimeout; }

        /**
         * Gets the maximum number of query transmit attempts before reporting failure.
         *
         * @returns The maximum number of query transmit attempts.
         *
         */
        uint8_t GetMaxTxAttempts(void) const { return mMaxTxAttempts; }

        /**
         * Gets the recursion flag indicating whether the server can resolve the query recursively or not.
         *
         * @returns The recursion flag.
         *
         */
        RecursionFlag GetRecursionFlag(void) const { return static_cast<RecursionFlag>(mRecursionFlag); }

#if OPENTHREAD_CONFIG_DNS_CLIENT_NAT64_ENABLE
        /**
         * Gets the NAT64 mode.
         *
         * @returns The NAT64 mode.
         *
         */
        Nat64Mode GetNat64Mode(void) const { return static_cast<Nat64Mode>(mNat64Mode); }
#endif
        /**
         * Gets the service resolution mode.
         *
         * @returns The service resolution mode.
         *
         */
        ServiceMode GetServiceMode(void) const { return static_cast<ServiceMode>(mServiceMode); }

        /**
         * Gets the transport protocol.
         *
         * @returns The transport protocol.
         *
         */
        TransportProto GetTransportProto(void) const { return static_cast<TransportProto>(mTransportProto); };

    private:
        static constexpr uint32_t kDefaultResponseTimeout = OPENTHREAD_CONFIG_DNS_CLIENT_DEFAULT_RESPONSE_TIMEOUT;
        static constexpr uint16_t kDefaultServerPort      = OPENTHREAD_CONFIG_DNS_CLIENT_DEFAULT_SERVER_PORT;
        static constexpr uint8_t  kDefaultMaxTxAttempts   = OPENTHREAD_CONFIG_DNS_CLIENT_DEFAULT_MAX_TX_ATTEMPTS;
        static constexpr bool kDefaultRecursionDesired    = OPENTHREAD_CONFIG_DNS_CLIENT_DEFAULT_RECURSION_DESIRED_FLAG;
        static constexpr ServiceMode kDefaultServiceMode =
            static_cast<ServiceMode>(OPENTHREAD_CONFIG_DNS_CLIENT_DEFAULT_SERVICE_MODE);

        static_assert(kDefaultServiceMode != kServiceModeUnspecified, "Invalid default service mode");

#if OPENTHREAD_CONFIG_DNS_CLIENT_NAT64_ENABLE
        static constexpr bool kDefaultNat64Allowed = OPENTHREAD_CONFIG_DNS_CLIENT_DEFAULT_NAT64_ALLOWED;
#endif

        enum InitMode : uint8_t
        {
            kInitFromDefaults,
        };

        static const char kDefaultServerAddressString[];

        explicit QueryConfig(InitMode aMode);

        Ip6::SockAddr &GetServerSockAddr(void) { return AsCoreType(&mServerSockAddr); }

        void SetResponseTimeout(uint32_t aResponseTimeout) { mResponseTimeout = aResponseTimeout; }
        void SetMaxTxAttempts(uint8_t aMaxTxAttempts) { mMaxTxAttempts = aMaxTxAttempts; }
        void SetRecursionFlag(RecursionFlag aFlag) { mRecursionFlag = static_cast<otDnsRecursionFlag>(aFlag); }
        void SetServiceMode(ServiceMode aMode) { mServiceMode = static_cast<otDnsServiceMode>(aMode); }
#if OPENTHREAD_CONFIG_DNS_CLIENT_NAT64_ENABLE
        void SetNat64Mode(Nat64Mode aMode) { mNat64Mode = static_cast<otDnsNat64Mode>(aMode); }
#endif
        void SetTransportProto(TransportProto aTransportProto)
        {
            mTransportProto = static_cast<otDnsTransportProto>(aTransportProto);
        }

        void SetFrom(const QueryConfig *aConfig, const QueryConfig &aDefaultConfig);
    };

#if OPENTHREAD_CONFIG_DNS_CLIENT_SERVICE_DISCOVERY_ENABLE
    /**
     * Provides info for a DNS service instance.
     *
     */
    typedef otDnsServiceInfo ServiceInfo;
#endif

    /**
     * Represents a DNS query response.
     *
     */
    class Response : public otDnsAddressResponse,
#if OPENTHREAD_CONFIG_DNS_CLIENT_SERVICE_DISCOVERY_ENABLE
                     public otDnsBrowseResponse,
                     public otDnsServiceResponse,
#endif
                     public Clearable<Response>
    {
        friend class Client;

    protected:
        enum Section : uint8_t
        {
            kAnswerSection,
            kAdditionalDataSection,
        };

        Response(void) { Clear(); }

        Error GetName(char *aNameBuffer, uint16_t aNameBufferSize) const;
        void  SelectSection(Section aSection, uint16_t &aOffset, uint16_t &aNumRecord) const;
        Error CheckForHostNameAlias(Section aSection, Name &aHostName) const;
        Error FindHostAddress(Section       aSection,
                              const Name   &aHostName,
                              uint16_t      aIndex,
                              Ip6::Address &aAddress,
                              uint32_t     &aTtl) const;
#if OPENTHREAD_CONFIG_DNS_CLIENT_NAT64_ENABLE
        Error FindARecord(Section aSection, const Name &aHostName, uint16_t aIndex, ARecord &aARecord) const;
#endif

#if OPENTHREAD_CONFIG_DNS_CLIENT_SERVICE_DISCOVERY_ENABLE
        void  InitServiceInfo(ServiceInfo &aServiceInfo) const;
        Error ReadServiceInfo(Section aSection, const Name &aName, ServiceInfo &aServiceInfo) const;
        Error ReadTxtRecord(Section aSection, const Name &aName, ServiceInfo &aServiceInfo) const;
#endif
        void PopulateFrom(const Message &aMessage);

        Instance      *mInstance;              // The OpenThread instance.
        Query         *mQuery;                 // The associated query.
        const Message *mMessage;               // The response message.
        Response      *mNext;                  // The next response when we have related queries.
        uint16_t       mAnswerOffset;          // Answer section offset in `mMessage`.
        uint16_t       mAnswerRecordCount;     // Number of records in answer section.
        uint16_t       mAdditionalOffset;      // Additional data section offset in `mMessage`.
        uint16_t       mAdditionalRecordCount; // Number of records in additional data section.
#if OPENTHREAD_CONFIG_DNS_CLIENT_NAT64_ENABLE
        // This flag is only used in an IPv6 address query response.
        // It indicates that the response does not contain any IPv6
        // addresses but server provided at least one IPv4 address
        // in the additional data section for NAT64 address synthesis.
        bool mIp6QueryResponseRequiresNat64;
#endif
    };

    /**
     * Represents the function pointer callback which is called when a DNS response for an address resolution
     * query is received.
     *
     */
    typedef otDnsAddressCallback AddressCallback;

    /**
     * Represents an address resolution query DNS response.
     *
     */
    class AddressResponse : public Response
    {
        friend class Client;

    public:
        /**
         * Gets the host name associated with an address resolution DNS response.
         *
         * MUST only be used from `AddressCallback`.
         *
         * @param[out] aNameBuffer       A buffer to char array to output the host name.
         * @param[in]  aNameBufferSize   The size of @p aNameBuffer.
         *
         * @retval kErrorNone    The host name was read successfully.
         * @retval kErrorNoBufs  The name does not fit in @p aNameBuffer.
         *
         */
        Error GetHostName(char *aNameBuffer, uint16_t aNameBufferSize) const
        {
            return GetName(aNameBuffer, aNameBufferSize);
        }

        /**
         * Gets the IPv6 address associated with an address resolution DNS response.
         *
         * MUST only be used from `AddressCallback`.
         *
         * The response may include multiple IPv6 address records. @p aIndex can be used to iterate through the list of
         * addresses. Index zero gets the the first address and so on. When we reach end of the list, this method
         * returns `kErrorNotFound`.
         *
         * @param[in]  aIndex        The address record index to retrieve.
         * @param[out] aAddress      A reference to an IPv6 address to output the address.
         * @param[out] aTtl          A reference to a `uint32_t` to output TTL for the address.
         *
         * @retval kErrorNone          The address was read successfully.
         * @retval kErrorNotFound      No address record at @p aIndex.
         * @retval kErrorParse         Could not parse the records.
         * @retval kErrorInvalidState  No NAT64 prefix (applicable only when NAT64 is allowed).
         *
         */
        Error GetAddress(uint16_t aIndex, Ip6::Address &aAddress, uint32_t &aTtl) const;

    private:
#if OPENTHREAD_CONFIG_DNS_CLIENT_NAT64_ENABLE
        Error GetNat64Prefix(Ip6::Prefix &aPrefix) const;
#endif
    };

#if OPENTHREAD_CONFIG_DNS_CLIENT_SERVICE_DISCOVERY_ENABLE

    /**
     * Represents the function pointer callback which is called when a response for a browse (service
     * instance enumeration) DNS query is received.
     *
     */
    typedef otDnsBrowseCallback BrowseCallback;

    /**
     * Represents a browse (service instance enumeration) DNS response.
     *
     */
    class BrowseResponse : public Response
    {
        friend class Client;

    public:
        /**
         * Gets the service name associated with a DNS browse response.
         *
         * MUST only be used from `BrowseCallback`.
         *
         * @param[out] aNameBuffer       A buffer to char array to output the host name.
         * @param[in]  aNameBufferSize   The size of @p aNameBuffer.
         *
         * @retval kErrorNone    The host name was read successfully.
         * @retval kErrorNoBufs  The name does not fit in @p aNameBuffer.
         *
         */
        Error GetServiceName(char *aNameBuffer, uint16_t aNameBufferSize) const
        {
            return GetName(aNameBuffer, aNameBufferSize);
        }

        /**
         * Gets a service instance associated with a DNS browse (service instance enumeration) response.
         *
         * MUST only be used from `BrowseCallback`.
         *
         * A response may include multiple service instance records. @p aIndex can be used to iterate through the list.
         * Index zero gives the the first record. When we reach end of the list, `kErrorNotFound` is returned.
         *
         * Note that this method gets the service instance label and not the full service instance name which is of the
         * form `<Instance>.<Service>.<Domain>`.
         *
         * @param[in]  aIndex             The service instance record index to retrieve.
         * @param[out] aLabelBuffer       A char array to output the service instance label (MUST NOT be NULL).
         * @param[in]  aLabelBufferSize   The size of @p aLabelBuffer.
         *
         * @retval kErrorNone         The service instance was read successfully.
         * @retval kErrorNoBufs       The name does not fit in @p aNameBuffer.
         * @retval kErrorNotFound     No service instance record at @p aIndex.
         * @retval kErrorParse        Could not parse the records.
         *
         */
        Error GetServiceInstance(uint16_t aIndex, char *aLabelBuffer, uint8_t aLabelBufferSize) const;

        /**
         * Gets info for a service instance from a DNS browse (service instance enumeration) response.
         *
         * MUST only be used from `BrowseCallback`.
         *
         * A browse DNS response should include the SRV, TXT, and AAAA records for the service instances that are
         * enumerated (note that it is a SHOULD and not a MUST requirement). This method tries to retrieve this info
         * for a given service instance.
         *
         * - If no matching SRV record is found, `kErrorNotFound` is returned.
         * - If a matching SRV record is found, @p aServiceInfo is updated returning `kErrorNone`.
         * - If no matching TXT record is found, `mTxtDataSize` in @p aServiceInfo is set to zero.
         * - If no matching AAAA record is found, `mHostAddress is set to all zero or unspecified address.
         * - If there are multiple AAAA records for the host name `mHostAddress` is set to the first one. The other
         *   addresses can be retrieved using `GetHostAddress()` method.
         *
         * @param[in]  aInstanceLabel     The service instance label (MUST NOT be `nullptr`).
         * @param[out] aServiceInfo       A `ServiceInfo` to output the service instance information.
         *
         * @retval kErrorNone         The service instance info was read. @p aServiceInfo is updated.
         * @retval kErrorNotFound     Could not find a matching SRV record for @p aInstanceLabel.
         * @retval kErrorNoBufs       The host name and/or the TXT data could not fit in given buffers.
         * @retval kErrorParse        Could not parse the records.
         *
         */
        Error GetServiceInfo(const char *aInstanceLabel, ServiceInfo &aServiceInfo) const;

        /**
         * Gets the host IPv6 address from a DNS browse (service instance enumeration) response.
         *
         * MUST only be used from `BrowseCallback`.
         *
         * The response can include zero or more IPv6 address records. @p aIndex can be used to iterate through the
         * list of addresses. Index zero gets the first address and so on. When we reach end of the list, this method
         * returns `kErrorNotFound`.
         *
         * @param[in]  aHostName     The host name to get the address (MUST NOT be `nullptr`).
         * @param[in]  aIndex        The address record index to retrieve.
         * @param[out] aAddress      A reference to an IPv6 address to output the address.
         * @param[out] aTtl          A reference to a `uint32_t` to output TTL for the address.
         *
         * @retval kErrorNone       The address was read successfully.
         * @retval kErrorNotFound   No address record for @p aHostname at @p aIndex.
         * @retval kErrorParse      Could not parse the records.
         *
         */
        Error GetHostAddress(const char *aHostName, uint16_t aIndex, Ip6::Address &aAddress, uint32_t &aTtl) const;

    private:
        Error FindPtrRecord(const char *aInstanceLabel, Name &aInstanceName) const;
    };

    /**
     * Represents the function pointer callback which is called when a response for a service instance
     * resolution DNS query is received.
     *
     */
    typedef otDnsServiceCallback ServiceCallback;

    /**
     * Represents a service instance resolution DNS response.
     *
     */
    class ServiceResponse : public Response
    {
        friend class Client;

    public:
        /**
         * Gets the service instance name associated with a DNS service instance resolution response.
         *
         * MUST only be used from `ServiceCallback`.
         *
         * @param[out] aLabelBuffer      A buffer to char array to output the service instance label (MUST NOT be NULL).
         * @param[in]  aLabelBufferSize  The size of @p aLabelBuffer.
         * @param[out] aNameBuffer       A buffer to char array to output the rest of service name (can be NULL if user
         *                               is not interested in getting the name).
         * @param[in]  aNameBufferSize   The size of @p aNameBuffer.
         *
         * @retval kErrorNone    The service instance name was read successfully.
         * @retval kErrorNoBufs  Either the label or name does not fit in the given buffers.
         *
         */
        Error GetServiceName(char    *aLabelBuffer,
                             uint8_t  aLabelBufferSize,
                             char    *aNameBuffer,
                             uint16_t aNameBufferSize) const;

        /**
         * Gets info for a service instance from a DNS service instance resolution response.
         *
         * MUST only be used from `ServiceCallback`.
         *
         * - If no matching SRV record is found, `kErrorNotFound` is returned.
         * - If a matching SRV record is found, @p aServiceInfo is updated and `kErrorNone` is returned.
         * - If no matching TXT record is found, `mTxtDataSize` in @p aServiceInfo is set to zero.
         * - If no matching AAAA record is found, `mHostAddress is set to all zero or unspecified address.
         * - If there are multiple AAAA records for the host name, `mHostAddress` is set to the first one. The other
         *   addresses can be retrieved using `GetHostAddress()` method.
         *
         * @param[out] aServiceInfo       A `ServiceInfo` to output the service instance information
         *
         * @retval kErrorNone         The service instance info was read. @p aServiceInfo is updated.
         * @retval kErrorNotFound     Could not find a matching SRV record.
         * @retval kErrorNoBufs       The host name and/or TXT data could not fit in the given buffers.
         * @retval kErrorParse        Could not parse the records in the @p aResponse.
         *
         */
        Error GetServiceInfo(ServiceInfo &aServiceInfo) const;

        /**
         * Gets the host IPv6 address from a DNS service instance resolution response.
         *
         * MUST only be used from `ServiceCallback`.
         *
         * The response can include zero or more IPv6 address records. @p aIndex can be used to iterate through the
         * list of addresses. Index zero gets the first address and so on. When we reach end of the list, this method
         * returns `kErrorNotFound`.
         *
         * @param[in]  aHostName     The host name to get the address (MUST NOT be `nullptr`).
         * @param[in]  aIndex        The address record index to retrieve.
         * @param[out] aAddress      A reference to an IPv6 address to output the address.
         * @param[out] aTtl          A reference to a `uint32_t` to output TTL for the address.
         *
         * @retval kErrorNone       The address was read successfully.
         * @retval kErrorNotFound   No address record for @p aHostname at @p aIndex.
         * @retval kErrorParse      Could not parse the records.
         *
         */
        Error GetHostAddress(const char *aHostName, uint16_t aIndex, Ip6::Address &aAddress, uint32_t &aTtl) const;
    };

#endif // OPENTHREAD_CONFIG_DNS_CLIENT_SERVICE_DISCOVERY_ENABLE

    /**
     * Initializes the object.
     *
     * @param[in]  aInstance     A reference to the OpenThread instance.
     *
     */
    explicit Client(Instance &aInstance);

    /**
     * Starts the DNS client.
     *
     * @retval kErrorNone     Successfully started the DNS client.
     * @retval kErrorAlready  The socket is already open.
     *
     */
    Error Start(void);

    /**
     * Stops the DNS client.
     *
     */
    void Stop(void);

    /**
     * Gets the current default query config being used by DNS client.
     *
     * @returns The current default query config.
     *
     */
    const QueryConfig &GetDefaultConfig(void) const { return mDefaultConfig; }

    /**
     * Sets the default query config.
     *
     * @param[in] aQueryConfig   The new default query config.
     *
     */
    void SetDefaultConfig(const QueryConfig &aQueryConfig);

    /**
     * Resets the default config to the config used when the OpenThread stack starts.
     *
     * When OpenThread stack starts, the default DNS query config is determined from a set of OT config options such as
     * `OPENTHREAD_CONFIG_DNS_CLIENT_DEFAULT_SERVER_IP6_ADDRESS`, `_DEFAULT_SERVER_PORT`, or `_DEFAULT_RESPONSE_TIMEOUT`
     * etc. (see `config/dns_client.h` for all related config options).
     *
     */
    void ResetDefaultConfig(void);

    /**
     * Sends an address resolution DNS query for AAAA (IPv6) record for a given host name.
     *
     * The @p aConfig can be nullptr. In this case the default config (from `GetDefaultConfig()`) will be used as
     * the config for this query. In a non-nullptr @p aConfig, some of the fields can be left unspecified (value zero).
     * The unspecified fields are then replaced by the values from the default config.
     *
     * @param[in]  aHostName        The host name for which to query the address (MUST NOT be `nullptr`).
     * @param[in]  aCallback        A callback function pointer to report the result of query.
     * @param[in]  aContext         A pointer to arbitrary context information passed to @p aCallback.
     * @param[in]  aConfig          The config to use for this query.
     *
     * @retval kErrorNone           Successfully sent DNS query.
     * @retval kErrorNoBufs         Failed to allocate retransmission data.
     * @retval kErrorInvalidArgs    The host name is not valid format.
     * @retval kErrorInvalidState   Cannot send query since Thread interface is not up.
     *
     */
    Error ResolveAddress(const char        *aHostName,
                         AddressCallback    aCallback,
                         void              *aContext,
                         const QueryConfig *aConfig = nullptr);

#if OPENTHREAD_CONFIG_DNS_CLIENT_NAT64_ENABLE
    /**
     * Sends an address resolution DNS query for A (IPv4) record for a given host name.
     *
     * When a successful response is received, the addresses are returned from @p aCallback as NAT64 IPv6 translated
     * versions of the IPv4 addresses from the query response.
     *
     * The @p aConfig can be nullptr. In this case the default config (from `GetDefaultConfig()`) will be used as
     * the config for this query. In a non-nullptr @p aConfig, some of the fields can be left unspecified (value zero).
     * The unspecified fields are then replaced by the values from the default config.
     *
     * @param[in]  aHostName        The host name for which to query the address (MUST NOT be `nullptr`).
     * @param[in]  aCallback        A callback function pointer to report the result of query.
     * @param[in]  aContext         A pointer to arbitrary context information passed to @p aCallback.
     * @param[in]  aConfig          The config to use for this query.
     *
     * @retval kErrorNone           Successfully sent DNS query.
     * @retval kErrorNoBufs         Failed to allocate retransmission data.
     * @retval kErrorInvalidArgs    The host name is not valid format or NAT64 is not enabled in config.
     * @retval kErrorInvalidState   Cannot send query since Thread interface is not up, or there is no NAT64 prefix.
     *
     */
    Error ResolveIp4Address(const char        *aHostName,
                            AddressCallback    aCallback,
                            void              *aContext,
                            const QueryConfig *aConfig = nullptr);
#endif

#if OPENTHREAD_CONFIG_DNS_CLIENT_SERVICE_DISCOVERY_ENABLE

    /**
     * Sends a browse (service instance enumeration) DNS query for a given service name.
     *
     * The @p aConfig can be nullptr. In this case the default config (from `GetDefaultConfig()`) will be used as
     * the config for this query. In a non-nullptr @p aConfig, some of the fields can be left unspecified (value zero).
     * The unspecified fields are then replaced by the values from the default config.
     *
     * @param[in]  aServiceName     The service name to query for (MUST NOT be `nullptr`).
     * @param[in]  aCallback        The callback to report the response or errors (such as time-out).
     * @param[in]  aContext         A pointer to arbitrary context information.
     * @param[in]  aConfig          The config to use for this query.
     *
     * @retval kErrorNone       Query sent successfully. @p aCallback will be invoked to report the status.
     * @retval kErrorNoBufs     Insufficient buffer to prepare and send query.
     *
     */
    Error Browse(const char        *aServiceName,
                 BrowseCallback     aCallback,
                 void              *aContext,
                 const QueryConfig *aConfig = nullptr);

    /**
     * Starts a DNS service instance resolution for a given service instance.
     *
     * The @p aConfig can be `nullptr`. In this case the default config (from `GetDefaultConfig()`) will be used as
     * the config for this query. In a non-`nullptr` @p aConfig, some of the fields can be left unspecified (value
     * zero). The unspecified fields are then replaced by the values from the default config.
     *
     * @param[in]  aInstanceLabel     The service instance label.
     * @param[in]  aServiceName       The service name (together with @p aInstanceLabel form full instance name).
     * @param[in]  aCallback          A function pointer that shall be called on response reception or time-out.
     * @param[in]  aContext           A pointer to arbitrary context information.
     * @param[in]  aConfig            The config to use for this query.
     *
     * @retval kErrorNone         Query sent successfully. @p aCallback will be invoked to report the status.
     * @retval kErrorNoBufs       Insufficient buffer to prepare and send query.
     * @retval kErrorInvalidArgs  @p aInstanceLabel is `nullptr`.
     *
     */
    Error ResolveService(const char          *aInstanceLabel,
                         const char          *aServiceName,
                         otDnsServiceCallback aCallback,
                         void                *aContext,
                         const QueryConfig   *aConfig = nullptr);

    /**
     * Starts a DNS service instance resolution for a given service instance, with a potential follow-up
     * host name resolution (if the server/resolver does not provide AAAA/A records for the host name in the response
     * to SRV query).
     *
     * The @p aConfig can be `nullptr`. In this case the default config (from `GetDefaultConfig()`) will be used as
     * the config for this query. In a non-`nullptr` @p aConfig, some of the fields can be left unspecified (value
     * zero). The unspecified fields are then replaced by the values from the default config.
     *
     * @param[in]  aInstanceLabel     The service instance label.
     * @param[in]  aServiceName       The service name (together with @p aInstanceLabel form full instance name).
     * @param[in]  aCallback          A function pointer that shall be called on response reception or time-out.
     * @param[in]  aContext           A pointer to arbitrary context information.
     * @param[in]  aConfig            The config to use for this query.
     *
     * @retval kErrorNone         Query sent successfully. @p aCallback will be invoked to report the status.
     * @retval kErrorNoBufs       Insufficient buffer to prepare and send query.
     * @retval kErrorInvalidArgs  @p aInstanceLabel is `nullptr` or the @p aConfig is invalid.
     *
     */
    Error ResolveServiceAndHostAddress(const char        *aInstanceLabel,
                                       const char        *aServiceName,
                                       ServiceCallback    aCallback,
                                       void              *aContext,
                                       const QueryConfig *aConfig = nullptr);

#endif // OPENTHREAD_CONFIG_DNS_CLIENT_SERVICE_DISCOVERY_ENABLE

private:
    static constexpr uint16_t kMaxCnameAliasNameChanges = 40;

    enum QueryType : uint8_t
    {
        kIp6AddressQuery, // IPv6 Address resolution.
#if OPENTHREAD_CONFIG_DNS_CLIENT_NAT64_ENABLE
        kIp4AddressQuery, // IPv4 Address resolution
#endif
#if OPENTHREAD_CONFIG_DNS_CLIENT_SERVICE_DISCOVERY_ENABLE
        kBrowseQuery,        // Browse (service instance enumeration).
        kServiceQuerySrvTxt, // Service instance resolution both SRV and TXT records.
        kServiceQuerySrv,    // Service instance resolution SRV record only.
        kServiceQueryTxt,    // Service instance resolution TXT record only.
#endif
        kNoQuery,
    };

#if OPENTHREAD_CONFIG_DNS_CLIENT_OVER_TCP_ENABLE
    enum TcpState : uint8_t
    {
        kTcpUninitialized = 0,
        kTcpConnecting,
        kTcpConnectedIdle,
        kTcpConnectedSending,
    };
#endif

    union Callback
    {
        AddressCallback mAddressCallback;
#if OPENTHREAD_CONFIG_DNS_CLIENT_SERVICE_DISCOVERY_ENABLE
        BrowseCallback  mBrowseCallback;
        ServiceCallback mServiceCallback;
#endif
    };

    typedef MessageQueue QueryList; // List of queries.

    struct QueryInfo : public Clearable<QueryInfo> // Query related Info
    {
        void ReadFrom(const Query &aQuery) { IgnoreError(aQuery.Read(0, *this)); }

        QueryType   mQueryType;
        uint16_t    mMessageId;
        Callback    mCallback;
        void       *mCallbackContext;
        TimeMilli   mRetransmissionTime;
        QueryConfig mConfig;
        uint8_t     mTransmissionCount;
        bool        mShouldResolveHostAddr;
        Query      *mMainQuery;
        Query      *mNextQuery;
        Message    *mSavedResponse;
        // Followed by the name (service, host, instance) encoded as a `Dns::Name`.
    };

    static constexpr uint16_t kNameOffsetInQuery = sizeof(QueryInfo);

    Error       StartQuery(QueryInfo &aInfo, const char *aLabel, const char *aName, QueryType aSecondType = kNoQuery);
    Error       AllocateQuery(const QueryInfo &aInfo, const char *aLabel, const char *aName, Query *&aQuery);
    void        FreeQuery(Query &aQuery);
    void        UpdateQuery(Query &aQuery, const QueryInfo &aInfo) { aQuery.Write(0, aInfo); }
    Query      &FindMainQuery(Query &aQuery);
    Error       SendQuery(Query &aQuery, QueryInfo &aInfo, bool aUpdateTimer);
    void        FinalizeQuery(Query &aQuery, Error aError);
    void        FinalizeQuery(Response &Response, Error aError);
    static void GetQueryTypeAndCallback(const Query &aQuery, QueryType &aType, Callback &aCallback, void *&aContext);
    Error       AppendNameFromQuery(const Query &aQuery, Message &aMessage);
    Query      *FindQueryById(uint16_t aMessageId);
    static void HandleUdpReceive(void *aContext, otMessage *aMessage, const otMessageInfo *aMsgInfo);
    void        ProcessResponse(const Message &aResponseMessage);
    Error       ParseResponse(const Message &aResponseMessage, Query *&aQuery, Error &aResponseError);
    bool        CanFinalizeQuery(Query &aQuery);
    void        SaveQueryResponse(Query &aQuery, const Message &aResponseMessage);
    Query      *PopulateResponse(Response &aResponse, Query &aQuery, const Message &aResponseMessage);
    void        PrepareResponseAndFinalize(Query &aQuery, const Message &aResponseMessage, Response *aPrevResponse);
    void        HandleTimer(void);

#if OPENTHREAD_CONFIG_DNS_CLIENT_NAT64_ENABLE
    Error ReplaceWithIp4Query(Query &aQuery);
#endif
#if OPENTHREAD_CONFIG_DNS_CLIENT_SERVICE_DISCOVERY_ENABLE
    Error Resolve(const char        *aInstanceLabel,
                  const char        *aServiceName,
                  ServiceCallback    aCallback,
                  void              *aContext,
                  const QueryConfig *aConfig,
                  bool               aShouldResolveHostAddr);
    Error ReplaceWithSeparateSrvTxtQueries(Query &aQuery);
    void  ResolveHostAddressIfNeeded(Query &aQuery, const Message &aResponseMessage);
#endif

#if OPENTHREAD_CONFIG_DNS_CLIENT_DEFAULT_SERVER_ADDRESS_AUTO_SET_ENABLE
    void UpdateDefaultConfigAddress(void);
#endif

#if OPENTHREAD_CONFIG_DNS_CLIENT_OVER_TCP_ENABLE
    static void HandleTcpEstablishedCallback(otTcpEndpoint *aEndpoint);
    static void HandleTcpSendDoneCallback(otTcpEndpoint *aEndpoint, otLinkedBuffer *aData);
    static void HandleTcpDisconnectedCallback(otTcpEndpoint *aEndpoint, otTcpDisconnectedReason aReason);
    static void HandleTcpReceiveAvailableCallback(otTcpEndpoint *aEndpoint,
                                                  size_t         aBytesAvailable,
                                                  bool           aEndOfStream,
                                                  size_t         aBytesRemaining);

    void  HandleTcpEstablished(otTcpEndpoint *aEndpoint);
    void  HandleTcpSendDone(otTcpEndpoint *aEndpoint, otLinkedBuffer *aData);
    void  HandleTcpDisconnected(otTcpEndpoint *aEndpoint, otTcpDisconnectedReason aReason);
    void  HandleTcpReceiveAvailable(otTcpEndpoint *aEndpoint,
                                    size_t         aBytesAvailable,
                                    bool           aEndOfStream,
                                    size_t         aBytesRemaining);
    Error InitTcpSocket(void);
    Error ReadFromLinkBuffer(const otLinkedBuffer *&aLinkedBuffer,
                             size_t                &aOffset,
                             Message               &aMessage,
                             uint16_t               aLength);
    void  PrepareTcpMessage(Message &aMessage);
#endif // OPENTHREAD_CONFIG_DNS_CLIENT_OVER_TCP_ENABLE

    static const uint8_t         kQuestionCount[];
    static const uint16_t *const kQuestionRecordTypes[];

    static const uint16_t kIp6AddressQueryRecordTypes[];
#if OPENTHREAD_CONFIG_DNS_CLIENT_NAT64_ENABLE
    static const uint16_t kIp4AddressQueryRecordTypes[];
#endif
#if OPENTHREAD_CONFIG_DNS_CLIENT_SERVICE_DISCOVERY_ENABLE
    static const uint16_t kBrowseQueryRecordTypes[];
    static const uint16_t kServiceQueryRecordTypes[];
#endif

    static constexpr uint16_t kUdpQueryMaxSize = 512;

    using RetryTimer = TimerMilliIn<Client, &Client::HandleTimer>;

    Ip6::Udp::Socket mSocket;

#if OPENTHREAD_CONFIG_DNS_CLIENT_OVER_TCP_ENABLE
    Ip6::Tcp::Endpoint mEndpoint;

    otLinkedBuffer mSendLink;
    uint8_t        mSendBufferBytes[OPENTHREAD_CONFIG_DNS_CLIENT_OVER_TCP_QUERY_MAX_SIZE];
    uint8_t        mReceiveBufferBytes[OPENTHREAD_CONFIG_DNS_CLIENT_OVER_TCP_QUERY_MAX_SIZE];

    TcpState mTcpState;
#endif

    QueryList   mMainQueries;
    RetryTimer  mTimer;
    QueryConfig mDefaultConfig;
#if OPENTHREAD_CONFIG_DNS_CLIENT_DEFAULT_SERVER_ADDRESS_AUTO_SET_ENABLE
    bool mUserDidSetDefaultAddress;
#endif
};

} // namespace Dns

DefineCoreType(otDnsQueryConfig, Dns::Client::QueryConfig);
DefineCoreType(otDnsAddressResponse, Dns::Client::AddressResponse);
#if OPENTHREAD_CONFIG_DNS_CLIENT_SERVICE_DISCOVERY_ENABLE
DefineCoreType(otDnsBrowseResponse, Dns::Client::BrowseResponse);
DefineCoreType(otDnsServiceResponse, Dns::Client::ServiceResponse);
DefineCoreType(otDnsServiceInfo, Dns::Client::ServiceInfo);
#endif

} // namespace ot

#endif // OPENTHREAD_CONFIG_DNS_CLIENT_ENABLE

#endif // DNS_CLIENT_HPP_
