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

#ifndef COAP_HPP_
#define COAP_HPP_

#include "openthread-core-config.h"

#include <openthread/coap.h>

#include "coap/coap_message.hpp"
#include "common/as_core_type.hpp"
#include "common/debug.hpp"
#include "common/linked_list.hpp"
#include "common/locator.hpp"
#include "common/message.hpp"
#include "common/non_copyable.hpp"
#include "common/timer.hpp"
#include "net/ip6.hpp"
#include "net/netif.hpp"
#include "net/udp6.hpp"

/**
 * @file
 *   This file includes definitions for CoAP client and server functionality.
 */

namespace ot {

namespace Coap {

/**
 * @addtogroup core-coap
 *
 * @{
 *
 */

/**
 * This type represents a function pointer which is called when a CoAP response is received or on the request timeout.
 *
 * Please see otCoapResponseHandler for details.
 *
 */
typedef otCoapResponseHandler ResponseHandler;

/**
 * This type represents a function pointer which is called when a CoAP request associated with a given URI path is
 * received.
 *
 * Please see otCoapRequestHandler for details.
 *
 */
typedef otCoapRequestHandler RequestHandler;

/**
 * This structure represents the CoAP transmission parameters.
 *
 */
class TxParameters : public otCoapTxParameters
{
    friend class CoapBase;
    friend class ResponsesQueue;

public:
    /**
     * This static method coverts a pointer to `otCoapTxParameters` to `Coap::TxParamters`
     *
     * If the pointer is `nullptr`, the default parameters are used instead.
     *
     * @param[in] aTxParameters   A pointer to tx parameter.
     *
     * @returns A reference to corresponding `TxParamters` if  @p aTxParameters is not `nullptr`, otherwise the default
     *          tx parameters.
     *
     */
    static const TxParameters &From(const otCoapTxParameters *aTxParameters)
    {
        return aTxParameters ? *static_cast<const TxParameters *>(aTxParameters) : GetDefault();
    }

    /**
     * This method validates whether the CoAP transmission parameters are valid.
     *
     * @returns Whether the parameters are valid.
     *
     */
    bool IsValid(void) const;

    /**
     * This static method returns default CoAP tx parameters.
     *
     * @returns The default tx parameters.
     *
     */
    static const TxParameters &GetDefault(void) { return static_cast<const TxParameters &>(kDefaultTxParameters); }

private:
    static constexpr uint32_t kDefaultAckTimeout                 = 2000; // in msec
    static constexpr uint8_t  kDefaultAckRandomFactorNumerator   = 3;
    static constexpr uint8_t  kDefaultAckRandomFactorDenominator = 2;
    static constexpr uint8_t  kDefaultMaxRetransmit              = 4;
    static constexpr uint32_t kDefaultMaxLatency                 = 100000; // in msec

    uint32_t CalculateInitialRetransmissionTimeout(void) const;
    uint32_t CalculateExchangeLifetime(void) const;
    uint32_t CalculateMaxTransmitWait(void) const;
    uint32_t CalculateSpan(uint8_t aMaxRetx) const;

    static const otCoapTxParameters kDefaultTxParameters;
};

/**
 * This class implements CoAP resource handling.
 *
 */
class Resource : public otCoapResource, public LinkedListEntry<Resource>
{
    friend class CoapBase;

public:
    /**
     * This constructor initializes the resource.
     *
     * @param[in]  aUriPath  A pointer to a null-terminated string for the URI path.
     * @param[in]  aHandler  A function pointer that is called when receiving a CoAP message for @p aUriPath.
     * @param[in]  aContext  A pointer to arbitrary context information.
     */
    Resource(const char *aUriPath, RequestHandler aHandler, void *aContext)
    {
        mUriPath = aUriPath;
        mHandler = aHandler;
        mContext = aContext;
        mNext    = nullptr;
    }

    /**
     * This method returns a pointer to the URI path.
     *
     * @returns A pointer to the URI path.
     *
     */
    const char *GetUriPath(void) const { return mUriPath; }

protected:
    void HandleRequest(Message &aMessage, const Ip6::MessageInfo &aMessageInfo) const
    {
        mHandler(mContext, &aMessage, &aMessageInfo);
    }
};

#if OPENTHREAD_CONFIG_COAP_BLOCKWISE_TRANSFER_ENABLE
/**
 * This class implements CoAP block-wise resource handling.
 *
 */
class ResourceBlockWise : public otCoapBlockwiseResource
{
    friend class CoapBase;

public:
    /**
     * This constructor initializes the resource.
     *
     * @param[in]  aUriPath         A pointer to a NULL-terminated string for the Uri-Path.
     * @param[in]  aHandler         A function pointer that is called when receiving a CoAP message for @p aUriPath.
     * @param[in]  aContext         A pointer to arbitrary context information.
     * @param[in]  aReceiveHook     A function pointer that is called when receiving a CoAP block message for @p
     *                              aUriPath.
     * @param[in]  aTransmitHook    A function pointer that is called when transmitting a CoAP block message from @p
     *                              aUriPath.
     */
    ResourceBlockWise(const char *                aUriPath,
                      otCoapRequestHandler        aHandler,
                      void *                      aContext,
                      otCoapBlockwiseReceiveHook  aReceiveHook,
                      otCoapBlockwiseTransmitHook aTransmitHook)
    {
        mUriPath      = aUriPath;
        mHandler      = aHandler;
        mContext      = aContext;
        mReceiveHook  = aReceiveHook;
        mTransmitHook = aTransmitHook;
        mNext         = nullptr;
    }

    Error HandleBlockReceive(const uint8_t *aBlock,
                             uint32_t       aPosition,
                             uint16_t       aBlockLength,
                             bool           aMore,
                             uint32_t       aTotalLength) const
    {
        return mReceiveHook(otCoapBlockwiseResource::mContext, aBlock, aPosition, aBlockLength, aMore, aTotalLength);
    }

    Error HandleBlockTransmit(uint8_t *aBlock, uint32_t aPosition, uint16_t *aBlockLength, bool *aMore) const
    {
        return mTransmitHook(otCoapBlockwiseResource::mContext, aBlock, aPosition, aBlockLength, aMore);
    }

    /**
     * This method gets the next entry in the linked list.
     *
     * @returns A pointer to the next entry in the linked list or `nullptr` if at the end of the list.
     *
     */
    const ResourceBlockWise *GetNext(void) const
    {
        return static_cast<const ResourceBlockWise *>(static_cast<const ResourceBlockWise *>(this)->mNext);
    }

    /**
     * This method gets the next entry in the linked list.
     *
     * @returns A pointer to the next entry in the linked list or `nullptr` if at the end of the list.
     *
     */
    ResourceBlockWise *GetNext(void)
    {
        return static_cast<ResourceBlockWise *>(static_cast<ResourceBlockWise *>(this)->mNext);
    }

    /**
     * This method sets the next pointer on the entry.
     *
     * @param[in] aNext  A pointer to the next entry.
     *
     */
    void SetNext(ResourceBlockWise *aNext) { static_cast<ResourceBlockWise *>(this)->mNext = aNext; }

    /**
     * This method returns a pointer to the URI path.
     *
     * @returns A pointer to the URI path.
     *
     */
    const char *GetUriPath(void) const { return mUriPath; }

protected:
    void HandleRequest(Message &aMessage, const Ip6::MessageInfo &aMessageInfo) const
    {
        mHandler(mContext, &aMessage, &aMessageInfo);
    }
};
#endif

/**
 * This class caches CoAP responses to implement message deduplication.
 *
 */
class ResponsesQueue
{
public:
    /**
     * Default class constructor.
     *
     * @param[in]  aInstance  A reference to the OpenThread instance.
     *
     */
    explicit ResponsesQueue(Instance &aInstance);

    /**
     * This method adds a given response to the cache.
     *
     * If matching response (the same Message ID, source endpoint address and port) exists in the cache given
     * response is not added.
     *
     * The CoAP response is copied before it is added to the cache.
     *
     * @param[in]  aMessage      The CoAP response to add to the cache.
     * @param[in]  aMessageInfo  The message info corresponding to @p aMessage.
     * @param[in]  aTxParameters Transmission parameters.
     *
     */
    void EnqueueResponse(Message &aMessage, const Ip6::MessageInfo &aMessageInfo, const TxParameters &aTxParameters);

    /**
     * This method removes all responses from the cache.
     *
     */
    void DequeueAllResponses(void);

    /**
     * This method gets a copy of CoAP response from the cache that matches a given Message ID and source endpoint.
     *
     * @param[in]  aRequest      The CoAP message containing Message ID.
     * @param[in]  aMessageInfo  The message info containing source endpoint address and port.
     * @param[out] aResponse     A pointer to return a copy of a cached CoAP response matching given arguments.
     *
     * @retval kErrorNone      Matching response found and successfully created a copy.
     * @retval kErrorNoBufs    Matching response found but there is not sufficient buffer to create a copy.
     * @retval kErrorNotFound  Matching response not found.
     *
     */
    Error GetMatchedResponseCopy(const Message &aRequest, const Ip6::MessageInfo &aMessageInfo, Message **aResponse);

    /**
     * This method gets a reference to the cached CoAP responses queue.
     *
     * @returns  A reference to the cached CoAP responses queue.
     *
     */
    const MessageQueue &GetResponses(void) const { return mQueue; }

private:
    static constexpr uint16_t kMaxCachedResponses = OPENTHREAD_CONFIG_COAP_SERVER_MAX_CACHED_RESPONSES;

    struct ResponseMetadata
    {
        Error AppendTo(Message &aMessage) const { return aMessage.Append(*this); }
        void  ReadFrom(const Message &aMessage);

        TimeMilli        mDequeueTime;
        Ip6::MessageInfo mMessageInfo;
    };

    const Message *FindMatchedResponse(const Message &aRequest, const Ip6::MessageInfo &aMessageInfo) const;
    void           DequeueResponse(Message &aMessage);
    void           UpdateQueue(void);

    static void HandleTimer(Timer &aTimer);
    void        HandleTimer(void);

    MessageQueue      mQueue;
    TimerMilliContext mTimer;
};

/**
 * This class implements the CoAP client and server.
 *
 */
class CoapBase : public InstanceLocator, private NonCopyable
{
    friend class ResponsesQueue;

public:
#if OPENTHREAD_CONFIG_COAP_BLOCKWISE_TRANSFER_ENABLE
    static constexpr uint16_t kMaxBlockLength = OPENTHREAD_CONFIG_COAP_MAX_BLOCK_LENGTH;
#endif

    /**
     * This function pointer is called before CoAP server processing a CoAP message.
     *
     * @param[in]   aMessage        A reference to the message.
     @ @param[in]   aMessageInfo    A reference to the message info associated with @p aMessage.
     * @param[in]   aContext        A pointer to arbitrary context information.
     *
     * @retval  kErrorNone      Server should continue processing this message, other return values indicates the
     *                          server should stop processing this message.
     * @retval  kErrorNotTmf    The message is not a TMF message.
     *
     */
    typedef Error (*Interceptor)(const Message &aMessage, const Ip6::MessageInfo &aMessageInfo, void *aContext);

    /**
     * This method clears requests and responses used by this CoAP agent.
     *
     */
    void ClearRequestsAndResponses(void);

    /**
     * This method clears requests with specified source address used by this CoAP agent.
     *
     * @param[in]  aAddress A reference to the specified address.
     *
     */
    void ClearRequests(const Ip6::Address &aAddress);

#if OPENTHREAD_CONFIG_COAP_BLOCKWISE_TRANSFER_ENABLE

    /**
     * This method adds a block-wise resource to the CoAP server.
     *
     * @param[in]  aResource  A reference to the resource.
     *
     */
    void AddBlockWiseResource(ResourceBlockWise &aResource);

    /**
     * This method removes a block-wise resource from the CoAP server.
     *
     * @param[in]  aResource  A reference to the resource.
     *
     */
    void RemoveBlockWiseResource(ResourceBlockWise &aResource);
#endif

    /**
     * This method adds a resource to the CoAP server.
     *
     * @param[in]  aResource  A reference to the resource.
     *
     */
    void AddResource(Resource &aResource);

    /**
     * This method removes a resource from the CoAP server.
     *
     * @param[in]  aResource  A reference to the resource.
     *
     */
    void RemoveResource(Resource &aResource);

    /* This method sets the default handler for unhandled CoAP requests.
     *
     * @param[in]  aHandler   A function pointer that shall be called when an unhandled request arrives.
     * @param[in]  aContext   A pointer to arbitrary context information. May be `nullptr` if not used.
     *
     */
    void SetDefaultHandler(RequestHandler aHandler, void *aContext);

    /**
     * This method allocates a new message with a CoAP header.
     *
     * @param[in]  aSettings  The message settings.
     *
     * @returns A pointer to the message or `nullptr` if failed to allocate message.
     *
     */
    Message *NewMessage(const Message::Settings &aSettings = Message::Settings::GetDefault());

    /**
     * This method allocates a new message with a CoAP header that has Network Control priority level.
     *
     * @returns A pointer to the message or `nullptr` if failed to allocate message.
     *
     */
    Message *NewPriorityMessage(void)
    {
        return NewMessage(Message::Settings(Message::kWithLinkSecurity, Message::kPriorityNet));
    }

    /**
     * This method allocates and initializes a new CoAP Confirmable Post message with Network Control priority level.
     *
     * The CoAP header is initialized as `kTypeConfirmable` and `kCodePost` with a given URI path and a randomly
     * generated token (of default length). This method also sets the payload marker (`SetPayloadMarker()` on message.
     * Even if message has no payload, calling `SetPayloadMarker()` is harmless, since `SendMessage()` will check and
     * remove the payload marker when there is no payload.
     *
     * @param[in] aUriPath   The URI path string.
     *
     * @returns A pointer to the message or `nullptr` if failed to allocate message.
     *
     */
    Message *NewPriorityConfirmablePostMessage(const char *aUriPath);

    /**
     * This method allocates and initializes a new CoAP Confirmable Post message with normal priority level.
     *
     * The CoAP header is initialized as `kTypeConfirmable` and `kCodePost` with a given URI path and a randomly
     * generated token (of default length). This method also sets the payload marker (calling `SetPayloadMarker()`).
     * Even if message has no payload, calling `SetPayloadMarker()` is harmless, since `SendMessage()` will check and
     * remove the payload marker when there is no payload.
     *
     * @param[in] aUriPath   The URI path string.
     *
     * @returns A pointer to the message or `nullptr` if failed to allocate message.
     *
     */
    Message *NewConfirmablePostMessage(const char *aUriPath);

    /**
     * This method allocates and initializes a new CoAP Non-confirmable Post message with Network Control priority
     * level.
     *
     * The CoAP header is initialized as `kTypeNonConfirmable` and `kCodePost` with a given URI path and a randomly
     * generated token (of default length). This method also sets the payload marker (calling `SetPayloadMarker()`).
     * Even if message has no payload, calling `SetPayloadMarker()` is harmless, since `SendMessage()` will check and
     * remove the payload marker when there is no payload.
     *
     * @param[in] aUriPath   The URI path string.
     *
     * @returns A pointer to the message or `nullptr` if failed to allocate message.
     *
     */
    Message *NewPriorityNonConfirmablePostMessage(const char *aUriPath);

    /**
     * This method allocates and initializes a new CoAP Non-confirmable Post message with normal priority level.
     *
     * The CoAP header is initialized as `kTypeNonConfirmable` and `kCodePost` with a given URI path and a randomly
     * generated token (of default length). This method also sets the payload marker (calling `SetPayloadMarker()`).
     * Even if message has no payload, calling `SetPayloadMarker()` is harmless, since `SendMessage()` will check and
     * remove the payload marker when there is no payload.
     *
     * @param[in] aUriPath   The URI path string.
     *
     * @returns A pointer to the message or `nullptr` if failed to allocate message.
     *
     */
    Message *NewNonConfirmablePostMessage(const char *aUriPath);

    /**
     * This method allocates and initializes a new CoAP response message with Network Control priority level for a
     * given request message.
     *
     * The CoAP header is initialized as `kTypeAck` with `kCodeChanged`. The token and message ID is copied from
     * @p aRequest. This method also sets the payload marker (calling `SetPayloadMarker()`). Even if message has
     * no payload, calling `SetPayloadMarker()` is harmless, since `SendMessage()` will check and remove the payload
     * marker when there is no payload.
     *
     * @returns A pointer to the message or `nullptr` if failed to allocate message.
     *
     */
    Message *NewPriorityResponseMessage(const Message &aRequest);

    /**
     * This method allocates and initializes a new CoAP response message with regular priority level for a given
     * request message.
     *
     * The CoAP header is initialized as `kTypeAck` with `kCodeChanged`. The token and message ID is copied from
     * @p aRequest. This method also sets the payload marker (calling `SetPayloadMarker()`). Even if message has
     * no payload, calling `SetPayloadMarker()` is harmless, since `SendMessage()` will check and remove the payload
     * marker when there is no payload.
     *
     * @returns A pointer to the message or `nullptr` if failed to allocate message.
     *
     */
    Message *NewResponseMessage(const Message &aRequest);

#if OPENTHREAD_CONFIG_COAP_BLOCKWISE_TRANSFER_ENABLE
    /**
     * This method sends a CoAP message block-wise with custom transmission parameters.
     *
     * If a response for a request is expected, respective function and context information should be provided.
     * If no response is expected, these arguments should be NULL pointers.
     * If Message Id was not set in the header (equal to 0), this function will assign unique Message Id to the message.
     *
     * @param[in]  aMessage      A reference to the message to send.
     * @param[in]  aMessageInfo  A reference to the message info associated with @p aMessage.
     * @param[in]  aTxParameters A reference to transmission parameters for this message.
     * @param[in]  aHandler      A function pointer that shall be called on response reception or time-out.
     * @param[in]  aContext      A pointer to arbitrary context information.
     * @param[in]  aTransmitHook A pointer to a hook function for outgoing block-wise transfer.
     * @param[in]  aReceiveHook  A pointer to a hook function for incoming block-wise transfer.
     *
     * @retval kErrorNone     Successfully sent CoAP message.
     * @retval kErrorNoBufs   Failed to allocate retransmission data.
     *
     */
    Error SendMessage(Message &                   aMessage,
                      const Ip6::MessageInfo &    aMessageInfo,
                      const TxParameters &        aTxParameters,
                      otCoapResponseHandler       aHandler      = nullptr,
                      void *                      aContext      = nullptr,
                      otCoapBlockwiseTransmitHook aTransmitHook = nullptr,
                      otCoapBlockwiseReceiveHook  aReceiveHook  = nullptr);
#else  // OPENTHREAD_CONFIG_COAP_BLOCKWISE_TRANSFER_ENABLE

    /**
     * This method sends a CoAP message with custom transmission parameters.
     *
     * If a response for a request is expected, respective function and context information should be provided.
     * If no response is expected, these arguments should be `nullptr` pointers.
     * If Message Id was not set in the header (equal to 0), this function will assign unique Message Id to the message.
     *
     * @param[in]  aMessage      A reference to the message to send.
     * @param[in]  aMessageInfo  A reference to the message info associated with @p aMessage.
     * @param[in]  aTxParameters A reference to transmission parameters for this message.
     * @param[in]  aHandler      A function pointer that shall be called on response reception or time-out.
     * @param[in]  aContext      A pointer to arbitrary context information.
     *
     * @retval kErrorNone    Successfully sent CoAP message.
     * @retval kErrorNoBufs  Insufficient buffers available to send the CoAP message.
     *
     */
    Error SendMessage(Message &               aMessage,
                      const Ip6::MessageInfo &aMessageInfo,
                      const TxParameters &    aTxParameters,
                      ResponseHandler         aHandler = nullptr,
                      void *                  aContext = nullptr);
#endif // OPENTHREAD_CONFIG_COAP_BLOCKWISE_TRANSFER_ENABLE

    /**
     * This method sends a CoAP message with default transmission parameters.
     *
     * If a response for a request is expected, respective function and context information should be provided.
     * If no response is expected, these arguments should be `nullptr` pointers.
     * If Message Id was not set in the header (equal to 0), this function will assign unique Message Id to the message.
     *
     * @param[in]  aMessage      A reference to the message to send.
     * @param[in]  aMessageInfo  A reference to the message info associated with @p aMessage.
     * @param[in]  aHandler      A function pointer that shall be called on response reception or time-out.
     * @param[in]  aContext      A pointer to arbitrary context information.
     *
     * @retval kErrorNone    Successfully sent CoAP message.
     * @retval kErrorNoBufs  Insufficient buffers available to send the CoAP response.
     *
     */
    Error SendMessage(Message &               aMessage,
                      const Ip6::MessageInfo &aMessageInfo,
                      ResponseHandler         aHandler = nullptr,
                      void *                  aContext = nullptr);

    /**
     * This method sends a CoAP reset message.
     *
     * @param[in]  aRequest        A reference to the CoAP Message that was used in CoAP request.
     * @param[in]  aMessageInfo    The message info corresponding to the CoAP request.
     *
     * @retval kErrorNone          Successfully enqueued the CoAP response message.
     * @retval kErrorNoBufs        Insufficient buffers available to send the CoAP response.
     * @retval kErrorInvalidArgs   The @p aRequest is not of confirmable type.
     *
     */
    Error SendReset(Message &aRequest, const Ip6::MessageInfo &aMessageInfo);

    /**
     * This method sends header-only CoAP response message.
     *
     * @param[in]  aCode           The CoAP code of this response.
     * @param[in]  aRequest        A reference to the CoAP Message that was used in CoAP request.
     * @param[in]  aMessageInfo    The message info corresponding to the CoAP request.
     *
     * @retval kErrorNone          Successfully enqueued the CoAP response message.
     * @retval kErrorNoBufs        Insufficient buffers available to send the CoAP response.
     * @retval kErrorInvalidArgs   The @p aRequest header is not of confirmable type.
     *
     */
    Error SendHeaderResponse(Message::Code aCode, const Message &aRequest, const Ip6::MessageInfo &aMessageInfo);

    /**
     * This method sends a CoAP ACK empty message which is used in Separate Response for confirmable requests.
     *
     * @param[in]  aRequest        A reference to the CoAP Message that was used in CoAP request.
     * @param[in]  aMessageInfo    The message info corresponding to the CoAP request.
     *
     * @retval kErrorNone          Successfully enqueued the CoAP response message.
     * @retval kErrorNoBufs        Insufficient buffers available to send the CoAP response.
     * @retval kErrorInvalidArgs   The @p aRequest header is not of confirmable type.
     *
     */
    Error SendAck(const Message &aRequest, const Ip6::MessageInfo &aMessageInfo);

    /**
     * This method sends a CoAP ACK message on which a dummy CoAP response is piggybacked.
     *
     * @param[in]  aRequest        A reference to the CoAP Message that was used in CoAP request.
     * @param[in]  aMessageInfo    The message info corresponding to the CoAP request.
     * @param[in]  aCode           The CoAP code of the dummy CoAP response.
     *
     * @retval kErrorNone          Successfully enqueued the CoAP response message.
     * @retval kErrorNoBufs        Insufficient buffers available to send the CoAP response.
     * @retval kErrorInvalidArgs   The @p aRequest header is not of confirmable type.
     *
     */
    Error SendEmptyAck(const Message &aRequest, const Ip6::MessageInfo &aMessageInfo, Code aCode = kCodeChanged);

    /**
     * This method sends a header-only CoAP message to indicate no resource matched for the request.
     *
     * @param[in]  aRequest        A reference to the CoAP Message that was used in CoAP request.
     * @param[in]  aMessageInfo    The message info corresponding to the CoAP request.
     *
     * @retval kErrorNone          Successfully enqueued the CoAP response message.
     * @retval kErrorNoBufs        Insufficient buffers available to send the CoAP response.
     *
     */
    Error SendNotFound(const Message &aRequest, const Ip6::MessageInfo &aMessageInfo);

#if OPENTHREAD_CONFIG_COAP_BLOCKWISE_TRANSFER_ENABLE
    /**
     * This method sends a header-only CoAP message to indicate not all blocks have been sent or
     * were sent out of order.
     *
     * @param[in]  aRequest        A reference to the CoAP Message that was used in CoAP request.
     * @param[in]  aMessageInfo    The message info corresponding to the CoAP request.
     *
     * @retval kErrorNone          Successfully enqueued the CoAP response message.
     * @retval kErrorNoBufs        Insufficient buffers available to send the CoAP response.
     *
     */
    Error SendRequestEntityIncomplete(const Message &aRequest, const Ip6::MessageInfo &aMessageInfo)
    {
        return SendHeaderResponse(kCodeRequestIncomplete, aRequest, aMessageInfo);
    }
#endif

    /**
     * This method aborts CoAP transactions associated with given handler and context.
     *
     * The associated response handler will be called with kErrorAbort.
     *
     * @param[in]  aHandler  A function pointer that should be called when the transaction ends.
     * @param[in]  aContext  A pointer to arbitrary context information.
     *
     * @retval kErrorNone      Successfully aborted CoAP transactions.
     * @retval kErrorNotFound  CoAP transaction associated with given handler was not found.
     *
     */
    Error AbortTransaction(ResponseHandler aHandler, void *aContext);

    /**
     * This method sets interceptor to be called before processing a CoAP packet.
     *
     * @param[in]   aInterceptor    A pointer to the interceptor.
     * @param[in]   aContext        A pointer to arbitrary context information.
     *
     */
    void SetInterceptor(Interceptor aInterceptor, void *aContext);

    /**
     * This method returns a reference to the request message list.
     *
     * @returns A reference to the request message list.
     *
     */
    const MessageQueue &GetRequestMessages(void) const { return mPendingRequests; }

    /**
     * This method returns a reference to the cached response list.
     *
     * @returns A reference to the cached response list.
     *
     */
    const MessageQueue &GetCachedResponses(void) const { return mResponsesQueue.GetResponses(); }

protected:
    /**
     * This function pointer is called to send a CoAP message.
     *
     * @param[in]  aCoapBase     A reference to the CoAP agent.
     * @param[in]  aMessage      A reference to the message to send.
     * @param[in]  aMessageInfo  A reference to the message info associated with @p aMessage.
     *
     * @retval kErrorNone    Successfully sent CoAP message.
     * @retval kErrorNoBufs  Failed to allocate retransmission data.
     *
     */
    typedef Error (*Sender)(CoapBase &aCoapBase, ot::Message &aMessage, const Ip6::MessageInfo &aMessageInfo);

    /**
     * This constructor initializes the object.
     *
     * @param[in]  aInstance        A reference to the OpenThread instance.
     * @param[in]  aSender          A function pointer to send CoAP message, which SHOULD be a static
     *                              member method of a descendant of this class.
     *
     */
    CoapBase(Instance &aInstance, Sender aSender);

    /**
     * This method receives a CoAP message.
     *
     * @param[in]  aMessage      A reference to the received message.
     * @param[in]  aMessageInfo  A reference to the message info associated with @p aMessage.
     *
     */
    void Receive(ot::Message &aMessage, const Ip6::MessageInfo &aMessageInfo);

private:
    struct Metadata
    {
        Error AppendTo(Message &aMessage) const { return aMessage.Append(*this); }
        void  ReadFrom(const Message &aMessage);
        void  UpdateIn(Message &aMessage) const;

        Ip6::Address    mSourceAddress;            // IPv6 address of the message source.
        Ip6::Address    mDestinationAddress;       // IPv6 address of the message destination.
        uint16_t        mDestinationPort;          // UDP port of the message destination.
        ResponseHandler mResponseHandler;          // A function pointer that is called on response reception.
        void *          mResponseContext;          // A pointer to arbitrary context information.
        TimeMilli       mNextTimerShot;            // Time when the timer should shoot for this message.
        uint32_t        mRetransmissionTimeout;    // Delay that is applied to next retransmission.
        uint8_t         mRetransmissionsRemaining; // Number of retransmissions remaining.
#if OPENTHREAD_CONFIG_BACKBONE_ROUTER_ENABLE
        uint8_t mHopLimit; // The hop limit.
#endif
        bool mAcknowledged : 1;  // Information that request was acknowledged.
        bool mConfirmable : 1;   // Information that message is confirmable.
        bool mMulticastLoop : 1; // Information that multicast loop is enabled.
#if OPENTHREAD_CONFIG_BACKBONE_ROUTER_ENABLE
        bool mIsHostInterface : 1; // TRUE if packets sent/received via host interface, FALSE otherwise.
#endif
#if OPENTHREAD_CONFIG_COAP_OBSERVE_API_ENABLE
        bool mObserve : 1; // Information that this request involves Observations.
#endif
#if OPENTHREAD_CONFIG_COAP_BLOCKWISE_TRANSFER_ENABLE
        otCoapBlockwiseReceiveHook  mBlockwiseReceiveHook;  // Function pointer called on Block2 response reception.
        otCoapBlockwiseTransmitHook mBlockwiseTransmitHook; // Function pointer called on Block1 response reception.
#endif
    };

    Message *InitMessage(Message *aMessage, Type aType, const char *aUriPath);
    Message *InitResponse(Message *aMessage, const Message &aResponse);

    static void HandleRetransmissionTimer(Timer &aTimer);
    void        HandleRetransmissionTimer(void);

    void     ClearRequests(const Ip6::Address *aAddress);
    Message *CopyAndEnqueueMessage(const Message &aMessage, uint16_t aCopyLength, const Metadata &aMetadata);
    void     DequeueMessage(Message &aMessage);
    Message *FindRelatedRequest(const Message &aResponse, const Ip6::MessageInfo &aMessageInfo, Metadata &aMetadata);
    void     FinalizeCoapTransaction(Message &               aRequest,
                                     const Metadata &        aMetadata,
                                     Message *               aResponse,
                                     const Ip6::MessageInfo *aMessageInfo,
                                     Error                   aResult);

#if OPENTHREAD_CONFIG_COAP_BLOCKWISE_TRANSFER_ENABLE
    void  FreeLastBlockResponse(void);
    Error CacheLastBlockResponse(Message *aResponse);

    Error PrepareNextBlockRequest(Message::BlockType aType,
                                  bool               aMoreBlocks,
                                  Message &          aRequestOld,
                                  Message &          aRequest,
                                  Message &          aMessage);
    Error ProcessBlock1Request(Message &                aMessage,
                               const Ip6::MessageInfo & aMessageInfo,
                               const ResourceBlockWise &aResource,
                               uint32_t                 aTotalLength);
    Error ProcessBlock2Request(Message &                aMessage,
                               const Ip6::MessageInfo & aMessageInfo,
                               const ResourceBlockWise &aResource);
#endif
    void ProcessReceivedRequest(Message &aMessage, const Ip6::MessageInfo &aMessageInfo);
    void ProcessReceivedResponse(Message &aMessage, const Ip6::MessageInfo &aMessageInfo);

#if OPENTHREAD_CONFIG_COAP_BLOCKWISE_TRANSFER_ENABLE
    Error SendNextBlock1Request(Message &               aRequest,
                                Message &               aMessage,
                                const Ip6::MessageInfo &aMessageInfo,
                                const Metadata &        aCoapMetadata);
    Error SendNextBlock2Request(Message &               aRequest,
                                Message &               aMessage,
                                const Ip6::MessageInfo &aMessageInfo,
                                const Metadata &        aCoapMetadata,
                                uint32_t                aTotalLength,
                                bool                    aBeginBlock1Transfer);
#endif
    void  SendCopy(const Message &aMessage, const Ip6::MessageInfo &aMessageInfo);
    Error SendEmptyMessage(Type aType, const Message &aRequest, const Ip6::MessageInfo &aMessageInfo);

    Error Send(ot::Message &aMessage, const Ip6::MessageInfo &aMessageInfo);

    MessageQueue      mPendingRequests;
    uint16_t          mMessageId;
    TimerMilliContext mRetransmissionTimer;

    LinkedList<Resource> mResources;

    void *         mContext;
    Interceptor    mInterceptor;
    ResponsesQueue mResponsesQueue;

    RequestHandler mDefaultHandler;
    void *         mDefaultHandlerContext;

    const Sender mSender;

#if OPENTHREAD_CONFIG_COAP_BLOCKWISE_TRANSFER_ENABLE
    LinkedList<ResourceBlockWise> mBlockWiseResources;
    Message *                     mLastResponse;
#endif
};

/**
 * This class implements the CoAP client and server.
 *
 */
class Coap : public CoapBase
{
public:
    /**
     * This constructor initializes the object.
     *
     * @param[in] aInstance      A reference to the OpenThread instance.
     *
     */
    explicit Coap(Instance &aInstance);

    /**
     * This method starts the CoAP service.
     *
     * @param[in]  aPort             The local UDP port to bind to.
     * @param[in]  aNetifIdentifier  The network interface identifier to bind.
     *
     * @retval kErrorNone    Successfully started the CoAP service.
     * @retval kErrorFailed  Failed to start CoAP agent.
     *
     */
    Error Start(uint16_t aPort, otNetifIdentifier aNetifIdentifier = OT_NETIF_UNSPECIFIED);

    /**
     * This method stops the CoAP service.
     *
     * @retval kErrorNone    Successfully stopped the CoAP service.
     * @retval kErrorFailed  Failed to stop CoAP agent.
     *
     */
    Error Stop(void);

protected:
    Ip6::Udp::Socket mSocket;

private:
    static Error Send(CoapBase &aCoapBase, ot::Message &aMessage, const Ip6::MessageInfo &aMessageInfo);
    static void  HandleUdpReceive(void *aContext, otMessage *aMessage, const otMessageInfo *aMessageInfo);
    Error        Send(ot::Message &aMessage, const Ip6::MessageInfo &aMessageInfo);
};

} // namespace Coap

DefineCoreType(otCoapTxParameters, Coap::TxParameters);
DefineCoreType(otCoapResource, Coap::Resource);
#if OPENTHREAD_CONFIG_COAP_BLOCKWISE_TRANSFER_ENABLE
DefineCoreType(otCoapBlockwiseResource, Coap::ResourceBlockWise);
#endif

} // namespace ot

#endif // COAP_HPP_
