/*
 *  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 implements a simple CLI for the CoAP service.
 */

#include "cli_coap.hpp"

#if OPENTHREAD_CONFIG_COAP_API_ENABLE

#include <openthread/random_noncrypto.h>

#include <ctype.h>

#include "cli/cli.hpp"

namespace ot {
namespace Cli {

Coap::Coap(otInstance *aInstance, OutputImplementer &aOutputImplementer)
    : Utils(aInstance, aOutputImplementer)
    , mUseDefaultRequestTxParameters(true)
    , mUseDefaultResponseTxParameters(true)
#if OPENTHREAD_CONFIG_COAP_OBSERVE_API_ENABLE
    , mObserveSerial(0)
    , mRequestTokenLength(0)
    , mSubscriberTokenLength(0)
    , mSubscriberConfirmableNotifications(false)
#endif
#if OPENTHREAD_CONFIG_COAP_BLOCKWISE_TRANSFER_ENABLE
    , mBlockCount(1)
#endif
{
    ClearAllBytes(mResource);
#if OPENTHREAD_CONFIG_COAP_OBSERVE_API_ENABLE
    ClearAllBytes(mRequestAddr);
    ClearAllBytes(mSubscriberSock);
    ClearAllBytes(mRequestToken);
    ClearAllBytes(mSubscriberToken);
    ClearAllBytes(mRequestUri);
#endif
    ClearAllBytes(mUriPath);
    strncpy(mResourceContent, "0", sizeof(mResourceContent));
    mResourceContent[sizeof(mResourceContent) - 1] = '\0';
}

#if OPENTHREAD_CONFIG_COAP_OBSERVE_API_ENABLE
otError Coap::CancelResourceSubscription(void)
{
    otError       error   = OT_ERROR_NONE;
    otMessage    *message = nullptr;
    otMessageInfo messageInfo;

    ClearAllBytes(messageInfo);
    messageInfo.mPeerAddr = mRequestAddr;
    messageInfo.mPeerPort = OT_DEFAULT_COAP_PORT;

    VerifyOrExit(mRequestTokenLength != 0, error = OT_ERROR_INVALID_STATE);

    message = otCoapNewMessage(GetInstancePtr(), nullptr);
    VerifyOrExit(message != nullptr, error = OT_ERROR_NO_BUFS);

    otCoapMessageInit(message, OT_COAP_TYPE_CONFIRMABLE, OT_COAP_CODE_GET);

    SuccessOrExit(error = otCoapMessageSetToken(message, mRequestToken, mRequestTokenLength));
    SuccessOrExit(error = otCoapMessageAppendObserveOption(message, 1));
    SuccessOrExit(error = otCoapMessageAppendUriPathOptions(message, mRequestUri));
    SuccessOrExit(error = otCoapSendRequest(GetInstancePtr(), message, &messageInfo, &Coap::HandleResponse, this));

    ClearAllBytes(mRequestAddr);
    ClearAllBytes(mRequestUri);
    mRequestTokenLength = 0;

exit:

    if ((error != OT_ERROR_NONE) && (message != nullptr))
    {
        otMessageFree(message);
    }

    return error;
}

void Coap::CancelSubscriber(void)
{
    ClearAllBytes(mSubscriberSock);
    mSubscriberTokenLength = 0;
}
#endif // OPENTHREAD_CONFIG_COAP_OBSERVE_API_ENABLE

void Coap::PrintPayload(otMessage *aMessage)
{
    uint8_t  buf[kMaxBufferSize];
    uint16_t bytesToPrint;
    uint16_t bytesPrinted = 0;
    uint16_t length       = otMessageGetLength(aMessage) - otMessageGetOffset(aMessage);

    if (length > 0)
    {
        OutputFormat(" with payload: ");

        while (length > 0)
        {
            bytesToPrint = Min(length, static_cast<uint16_t>(sizeof(buf)));
            otMessageRead(aMessage, otMessageGetOffset(aMessage) + bytesPrinted, buf, bytesToPrint);

            OutputBytes(buf, static_cast<uint8_t>(bytesToPrint));

            length -= bytesToPrint;
            bytesPrinted += bytesToPrint;
        }
    }

    OutputNewLine();
}

#if OPENTHREAD_CONFIG_COAP_OBSERVE_API_ENABLE
/**
 * @cli coap cancel
 * @code
 * coap cancel
 * Done
 * @endcode
 * @par
 * Cancels an existing observation subscription to a remote resource on the CoAP server.
 * @note This command is available only when `OPENTHREAD_CONFIG_COAP_OBSERVE_API_ENABLE` is set.
 * @csa{coap observe}
 */
template <> otError Coap::Process<Cmd("cancel")>(Arg aArgs[])
{
    OT_UNUSED_VARIABLE(aArgs);

    return CancelResourceSubscription();
}
#endif

/**
 * @cli coap resource (get,set)
 * @code
 * coap resource test-resource
 * Done
 * @endcode
 * @code
 * coap resource
 * test-resource
 * Done
 * @endcode
 * @cparam coap resource [@ca{uri-path}]
 * @par
 * Gets or sets the URI path of the CoAP server resource.
 * @sa otCoapAddResource
 * @sa otCoapAddBlockWiseResource
 */
template <> otError Coap::Process<Cmd("resource")>(Arg aArgs[])
{
    otError error = OT_ERROR_NONE;

    if (!aArgs[0].IsEmpty())
    {
        VerifyOrExit(aArgs[0].GetLength() < kMaxUriLength, error = OT_ERROR_INVALID_ARGS);

        mResource.mUriPath = mUriPath;
        mResource.mContext = this;
        mResource.mHandler = &Coap::HandleRequest;

#if OPENTHREAD_CONFIG_COAP_BLOCKWISE_TRANSFER_ENABLE
        mResource.mReceiveHook  = &Coap::BlockwiseReceiveHook;
        mResource.mTransmitHook = &Coap::BlockwiseTransmitHook;

        if (!aArgs[1].IsEmpty())
        {
            SuccessOrExit(error = aArgs[1].ParseAsUint32(mBlockCount));
        }
#endif

        strncpy(mUriPath, aArgs[0].GetCString(), sizeof(mUriPath) - 1);

#if OPENTHREAD_CONFIG_COAP_BLOCKWISE_TRANSFER_ENABLE
        otCoapAddBlockWiseResource(GetInstancePtr(), &mResource);
#else
        otCoapAddResource(GetInstancePtr(), &mResource);
#endif
    }
    else
    {
        OutputLine("%s", mResource.mUriPath != nullptr ? mResource.mUriPath : "");
    }

exit:
    return error;
}

/**
 * @cli coap set
 * @code
 * coap set Testing123
 * Done
 * @endcode
 * @cparam coap set @ca{new-content}
 * @par
 * Sets the content sent by the resource on the CoAP server.
 * If a CoAP client is observing the resource, a notification is sent to that client.
 * @csa{coap observe}
 * @sa otCoapMessageInit
 * @sa otCoapNewMessage
 */
template <> otError Coap::Process<Cmd("set")>(Arg aArgs[])
{
#if OPENTHREAD_CONFIG_COAP_OBSERVE_API_ENABLE
    otMessage    *notificationMessage = nullptr;
    otMessageInfo messageInfo;
#endif
    otError error = OT_ERROR_NONE;

    if (!aArgs[0].IsEmpty())
    {
        VerifyOrExit(aArgs[0].GetLength() < sizeof(mResourceContent), error = OT_ERROR_INVALID_ARGS);
        strncpy(mResourceContent, aArgs[0].GetCString(), sizeof(mResourceContent));
        mResourceContent[sizeof(mResourceContent) - 1] = '\0';

#if OPENTHREAD_CONFIG_COAP_OBSERVE_API_ENABLE
        if (mSubscriberTokenLength > 0)
        {
            // Notify the subscriber
            ClearAllBytes(messageInfo);
            messageInfo.mPeerAddr = mSubscriberSock.mAddress;
            messageInfo.mPeerPort = mSubscriberSock.mPort;

            OutputFormat("sending coap notification to ");
            OutputIp6AddressLine(mSubscriberSock.mAddress);

            notificationMessage = otCoapNewMessage(GetInstancePtr(), nullptr);
            VerifyOrExit(notificationMessage != nullptr, error = OT_ERROR_NO_BUFS);

            otCoapMessageInit(
                notificationMessage,
                ((mSubscriberConfirmableNotifications) ? OT_COAP_TYPE_CONFIRMABLE : OT_COAP_TYPE_NON_CONFIRMABLE),
                OT_COAP_CODE_CONTENT);

            SuccessOrExit(error = otCoapMessageSetToken(notificationMessage, mSubscriberToken, mSubscriberTokenLength));
            SuccessOrExit(error = otCoapMessageAppendObserveOption(notificationMessage, mObserveSerial++));
            SuccessOrExit(error = otCoapMessageSetPayloadMarker(notificationMessage));
            SuccessOrExit(error = otMessageAppend(notificationMessage, mResourceContent,
                                                  static_cast<uint16_t>(strlen(mResourceContent))));

            SuccessOrExit(error = otCoapSendRequest(GetInstancePtr(), notificationMessage, &messageInfo,
                                                    &Coap::HandleNotificationResponse, this));
        }
#endif // OPENTHREAD_CONFIG_COAP_OBSERVE_API_ENABLE
    }
    else
    {
        OutputLine("%s", mResourceContent);
    }

exit:

#if OPENTHREAD_CONFIG_COAP_OBSERVE_API_ENABLE
    if ((error != OT_ERROR_NONE) && (notificationMessage != nullptr))
    {
        otMessageFree(notificationMessage);
    }
#endif

    return error;
}

/**
 * @cli coap start
 * @code
 * coap start
 * Done
 * @endcode
 * @par
 * Starts the CoAP server. @moreinfo{@coap}.
 * @sa otCoapStart
 */
template <> otError Coap::Process<Cmd("start")>(Arg aArgs[])
{
    OT_UNUSED_VARIABLE(aArgs);

    return otCoapStart(GetInstancePtr(), OT_DEFAULT_COAP_PORT);
}

/**
 * @cli coap stop
 * @code
 * coap stop
 * Done
 * @endcode
 * @par api_copy
 * #otCoapStop
 */
template <> otError Coap::Process<Cmd("stop")>(Arg aArgs[])
{
    OT_UNUSED_VARIABLE(aArgs);

#if OPENTHREAD_CONFIG_COAP_BLOCKWISE_TRANSFER_ENABLE
    otCoapRemoveBlockWiseResource(GetInstancePtr(), &mResource);
#else
    otCoapRemoveResource(GetInstancePtr(), &mResource);
#endif

    return otCoapStop(GetInstancePtr());
}

/**
 * @cli coap parameters(get,set)
 * @code
 * coap parameters request
 * Transmission parameters for request:
 * ACK_TIMEOUT=1000 ms, ACK_RANDOM_FACTOR=255/254, MAX_RETRANSMIT=2
 * Done
 * @endcode
 * @code
 * coap parameters request default
 * Transmission parameters for request:
 * default
 * Done
 * @endcode
 * @code
 * coap parameters request 1000 255 254 2
 * Transmission parameters for request:
 * ACK_TIMEOUT=1000 ms, ACK_RANDOM_FACTOR=255/254, MAX_RETRANSMIT=2
 * Done
 * @endcode
 * @cparam coap parameters @ca{type} [@ca{default} | <!--
 * -->@ca{ack_timeout ack_random_factor_numerator <!--
 * -->ack_random_factor_denominator max_retransmit}]
 *   * `type`: `request` for CoAP requests, or `response` for CoAP responses.
        If no more parameters are given, the command prints the current configuration.
 *   * `default`: Sets the transmission parameters to
        the following default values:
 *       * `ack_timeout`: 2000 milliseconds
 *       * `ack_random_factor_numerator`: 3
 *       * `ack_random_factor_denominator`: 2
 *       * `max_retransmit`: 4
 *   * `ack_timeout`: The `ACK_TIMEOUT` (0-UINT32_MAX) in milliseconds.
       Refer to RFC7252.
 *   * `ack_random_factor_numerator`:
       The `ACK_RANDOM_FACTOR` numerator, with possible values
       of 0-255. Refer to RFC7252.
 *   * `ack_random_factor_denominator`:
 *     The `ACK_RANDOM_FACTOR` denominator, with possible values
 *     of 0-255. Refer to RFC7252.
 *   * `max_retransmit`: The `MAX_RETRANSMIT` (0-255). Refer to RFC7252.
 * @par
 * Gets current CoAP parameter values if the command is run with no optional
 * parameters.
 * @par
 * Sets the CoAP parameters either to their default values or to the values
 * you specify, depending on the syntax chosen.
 */
template <> otError Coap::Process<Cmd("parameters")>(Arg aArgs[])
{
    otError             error = OT_ERROR_NONE;
    bool               *defaultTxParameters;
    otCoapTxParameters *txParameters;

    if (aArgs[0] == "request")
    {
        txParameters        = &mRequestTxParameters;
        defaultTxParameters = &mUseDefaultRequestTxParameters;
    }
    else if (aArgs[0] == "response")
    {
        txParameters        = &mResponseTxParameters;
        defaultTxParameters = &mUseDefaultResponseTxParameters;
    }
    else
    {
        ExitNow(error = OT_ERROR_INVALID_ARGS);
    }

    if (!aArgs[1].IsEmpty())
    {
        if (aArgs[1] == "default")
        {
            *defaultTxParameters = true;
        }
        else
        {
            SuccessOrExit(error = aArgs[1].ParseAsUint32(txParameters->mAckTimeout));
            SuccessOrExit(error = aArgs[2].ParseAsUint8(txParameters->mAckRandomFactorNumerator));
            SuccessOrExit(error = aArgs[3].ParseAsUint8(txParameters->mAckRandomFactorDenominator));
            SuccessOrExit(error = aArgs[4].ParseAsUint8(txParameters->mMaxRetransmit));

            VerifyOrExit(txParameters->mAckRandomFactorNumerator > txParameters->mAckRandomFactorDenominator,
                         error = OT_ERROR_INVALID_ARGS);

            *defaultTxParameters = false;
        }
    }

    OutputLine("Transmission parameters for %s:", aArgs[0].GetCString());

    if (*defaultTxParameters)
    {
        OutputLine("default");
    }
    else
    {
        OutputLine("ACK_TIMEOUT=%lu ms, ACK_RANDOM_FACTOR=%u/%u, MAX_RETRANSMIT=%u", ToUlong(txParameters->mAckTimeout),
                   txParameters->mAckRandomFactorNumerator, txParameters->mAckRandomFactorDenominator,
                   txParameters->mMaxRetransmit);
    }

exit:
    return error;
}

/**
 * @cli coap get
 * @code
 * coap get fdde:ad00:beef:0:2780:9423:166c:1aac test-resource
 * Done
 * @endcode
 * @code
 * coap get fdde:ad00:beef:0:2780:9423:166c:1aac test-resource block-1024
 * Done
 * @endcode
 * @cparam coap get @ca{address} @ca{uri-path} [@ca{type}]
 *   * `address`: IPv6 address of the CoAP server.
 *   * `uri-path`: URI path of the resource.
 *   * `type`:
 *       * `con`: Confirmable
 *       * `non-con`: Non-confirmable (default)
 *       * `block-`: Use this option, followed by the block-wise value,
 *          if the response should be transferred block-wise. Valid
 *          values are: `block-16`, `block-32`, `block-64`, `block-128`,
 *          `block-256`, `block-512`, or `block-1024`.
 * @par
 * Gets information about the specified CoAP resource on the CoAP server.
 */
template <> otError Coap::Process<Cmd("get")>(Arg aArgs[]) { return ProcessRequest(aArgs, OT_COAP_CODE_GET); }

/**
 * @cli coap post
 * @code
 * coap post fdde:ad00:beef:0:2780:9423:166c:1aac test-resource con hellothere
 * Done
 * @endcode
 * @code
 * coap post fdde:ad00:beef:0:2780:9423:166c:1aac test-resource block-1024 10
 * Done
 * @endcode
 * @cparam coap post @ca{address} @ca{uri-path} [@ca{type}] [@ca{payload}]
 *   * `address`: IPv6 address of the CoAP server.
 *   * `uri-path`: URI path of the resource.
 *   * `type`:
 *         * `con`: Confirmable
 *         * `non-con`: Non-confirmable (default)
 *         * `block-`: Use this option, followed by the block-wise value,
 *            to send blocks with a randomly generated number of bytes
 *            for the payload. Valid values are:
 *            `block-16`, `block-32`, `block-64`, `block-128`,
 *            `block-256`, `block-512`, or `block-1024`.
 *   * `payload`: CoAP payload request, which if used is either a string or an
 *     integer, depending on the `type`. If the `type` is `con` or `non-con`,
 *     the `payload` parameter is optional. If you leave out the
 *     `payload` parameter, an empty payload is sent. However, If you use the
 *     `payload` parameter, its value must be a string, such as
 *     `hellothere`.  If the `type` is `block-`,
 *     the value of the`payload` parameter must be an integer that specifies
 *     the number of blocks to send. The `block-` type requires
 *     `OPENTHREAD_CONFIG_COAP_BLOCKWISE_TRANSFER_ENABLE` to be set.
 * @par
 * Creates the specified CoAP resource. @moreinfo{@coap}.
 */
template <> otError Coap::Process<Cmd("post")>(Arg aArgs[]) { return ProcessRequest(aArgs, OT_COAP_CODE_POST); }

/**
 * @cli coap put
 * @code
 * coap put fdde:ad00:beef:0:2780:9423:166c:1aac test-resource con hellothere
 * Done
 * @endcode
 * @code
 * coap put fdde:ad00:beef:0:2780:9423:166c:1aac test-resource block-1024 10
 * Done
 * @endcode
 * @cparam coap put @ca{address} @ca{uri-path} [@ca{type}] [@ca{payload}]
 *   * `address`: IPv6 address of the CoAP server.
 *   * `uri-path`: URI path of the resource.
 *   * `type`:
 *         * `con`: Confirmable
 *         * `non-con`: Non-confirmable (default)
 *         * `block-`: Use this option, followed by the block-wise value,
 *            to send blocks with a randomly generated number of bytes
 *            for the payload. Valid values are:
 *            `block-16`, `block-32`, `block-64`, `block-128`,
 *            `block-256`, `block-512`, or `block-1024`.
 *   * `payload`: CoAP payload request, which if used is either a string or an
 *     integer, depending on the `type`. If the `type` is `con` or `non-con`,
 *     the `payload` parameter is optional. If you leave out the
 *     `payload` parameter, an empty payload is sent. However, If you use the
 *     `payload` parameter, its value must be a string, such as
 *     `hellothere`. If the `type` is `block-`,
 *     the value of the`payload` parameter must be an integer that specifies
 *     the number of blocks to send. The `block-` type requires
 *     `OPENTHREAD_CONFIG_COAP_BLOCKWISE_TRANSFER_ENABLE` to be set.
 * @par
 * Modifies the specified CoAP resource. @moreinfo{@coap}.
 */
template <> otError Coap::Process<Cmd("put")>(Arg aArgs[]) { return ProcessRequest(aArgs, OT_COAP_CODE_PUT); }

/**
 * @cli coap delete
 * @code
 * coap delete fdde:ad00:beef:0:2780:9423:166c:1aac test-resource con hellothere
 * Done
 * @endcode
 * @cparam coap delete @ca{address} @ca{uri-path} [@ca{type}] [@ca{payload}]
 *   * `address`: IPv6 address of the CoAP server.
 *   * `uri-path`: URI path of the resource.
 *   * `type`:
 *       * `con`: Confirmable
 *       * `non-con`: Non-confirmable (default)
 *   * `payload`: The CoAP payload string. For example, `hellothere`.
 *  @par
 *  Deletes the specified CoAP resource.
 */
template <> otError Coap::Process<Cmd("delete")>(Arg aArgs[]) { return ProcessRequest(aArgs, OT_COAP_CODE_DELETE); }

#if OPENTHREAD_CONFIG_COAP_OBSERVE_API_ENABLE
/**
 * @cli coap observe
 * @code
 * coap observe fdde:ad00:beef:0:2780:9423:166c:1aac test-resource
 * Done
 * @endcode
 * @cparam coap observe @ca{address} @ca{uri-path} [@ca{type}]
 *   * `address`: IPv6 address of the CoAP server.
 *   * `uri-path`: URI path of the resource.
 *   * `type`:
 *       * `con`: Confirmable
 *       * `non-con`: Non-confirmable (default).
 * @par
 * Triggers a subscription request which allows the CoAP client to
 * observe the specified resource on the CoAP server for possible changes
 * in its state.
 * @note This command is available only when `OPENTHREAD_CONFIG_COAP_OBSERVE_API_ENABLE` is set.
 */
template <> otError Coap::Process<Cmd("observe")>(Arg aArgs[])
{
    return ProcessRequest(aArgs, OT_COAP_CODE_GET, /* aCoapObserve */ true);
}
#endif

#if OPENTHREAD_CONFIG_COAP_OBSERVE_API_ENABLE
otError Coap::ProcessRequest(Arg aArgs[], otCoapCode aCoapCode, bool aCoapObserve)
#else
otError Coap::ProcessRequest(Arg aArgs[], otCoapCode aCoapCode)
#endif
{
    otError       error   = OT_ERROR_NONE;
    otMessage    *message = nullptr;
    otMessageInfo messageInfo;
    uint16_t      payloadLength = 0;

    // Default parameters
    char         coapUri[kMaxUriLength] = "test";
    otCoapType   coapType               = OT_COAP_TYPE_NON_CONFIRMABLE;
    otIp6Address coapDestinationIp;
#if OPENTHREAD_CONFIG_COAP_BLOCKWISE_TRANSFER_ENABLE
    bool           coapBlock     = false;
    otCoapBlockSzx coapBlockSize = OT_COAP_OPTION_BLOCK_SZX_16;
    BlockType      coapBlockType = (aCoapCode == OT_COAP_CODE_GET) ? kBlockType2 : kBlockType1;
#endif

#if OPENTHREAD_CONFIG_COAP_OBSERVE_API_ENABLE && OPENTHREAD_CONFIG_COAP_BLOCKWISE_TRANSFER_ENABLE
    if (aCoapObserve)
    {
        coapBlockType = kBlockType1;
    }
#endif

    SuccessOrExit(error = aArgs[0].ParseAsIp6Address(coapDestinationIp));

    VerifyOrExit(!aArgs[1].IsEmpty(), error = OT_ERROR_INVALID_ARGS);
    VerifyOrExit(aArgs[1].GetLength() < sizeof(coapUri), error = OT_ERROR_INVALID_ARGS);
    strcpy(coapUri, aArgs[1].GetCString());

    // CoAP-Type
    if (!aArgs[2].IsEmpty())
    {
        if (aArgs[2] == "con")
        {
            coapType = OT_COAP_TYPE_CONFIRMABLE;
        }
#if OPENTHREAD_CONFIG_COAP_BLOCKWISE_TRANSFER_ENABLE
        else if (aArgs[2] == "block-16")
        {
            coapType      = OT_COAP_TYPE_CONFIRMABLE;
            coapBlock     = true;
            coapBlockSize = OT_COAP_OPTION_BLOCK_SZX_16;
        }
        else if (aArgs[2] == "block-32")
        {
            coapType      = OT_COAP_TYPE_CONFIRMABLE;
            coapBlock     = true;
            coapBlockSize = OT_COAP_OPTION_BLOCK_SZX_32;
        }
        else if (aArgs[2] == "block-64")
        {
            coapType      = OT_COAP_TYPE_CONFIRMABLE;
            coapBlock     = true;
            coapBlockSize = OT_COAP_OPTION_BLOCK_SZX_64;
        }
        else if (aArgs[2] == "block-128")
        {
            coapType      = OT_COAP_TYPE_CONFIRMABLE;
            coapBlock     = true;
            coapBlockSize = OT_COAP_OPTION_BLOCK_SZX_128;
        }
        else if (aArgs[2] == "block-256")
        {
            coapType      = OT_COAP_TYPE_CONFIRMABLE;
            coapBlock     = true;
            coapBlockSize = OT_COAP_OPTION_BLOCK_SZX_256;
        }
        else if (aArgs[2] == "block-512")
        {
            coapType      = OT_COAP_TYPE_CONFIRMABLE;
            coapBlock     = true;
            coapBlockSize = OT_COAP_OPTION_BLOCK_SZX_512;
        }
        else if (aArgs[2] == "block-1024")
        {
            coapType      = OT_COAP_TYPE_CONFIRMABLE;
            coapBlock     = true;
            coapBlockSize = OT_COAP_OPTION_BLOCK_SZX_1024;
        }
#endif // OPENTHREAD_CONFIG_COAP_BLOCKWISE_TRANSFER_ENABLE
    }

#if OPENTHREAD_CONFIG_COAP_OBSERVE_API_ENABLE
    if (aCoapObserve && mRequestTokenLength)
    {
        // New observe request, cancel any existing observation
        SuccessOrExit(error = CancelResourceSubscription());
    }
#endif

    message = otCoapNewMessage(GetInstancePtr(), nullptr);
    VerifyOrExit(message != nullptr, error = OT_ERROR_NO_BUFS);

    otCoapMessageInit(message, coapType, aCoapCode);
    otCoapMessageGenerateToken(message, OT_COAP_DEFAULT_TOKEN_LENGTH);

#if OPENTHREAD_CONFIG_COAP_OBSERVE_API_ENABLE
    if (aCoapObserve)
    {
        SuccessOrExit(error = otCoapMessageAppendObserveOption(message, 0));
    }
#endif

    SuccessOrExit(error = otCoapMessageAppendUriPathOptions(message, coapUri));

#if OPENTHREAD_CONFIG_COAP_BLOCKWISE_TRANSFER_ENABLE
    if (coapBlock)
    {
        if (coapBlockType == kBlockType1)
        {
            SuccessOrExit(error = otCoapMessageAppendBlock1Option(message, 0, true, coapBlockSize));
        }
        else
        {
            SuccessOrExit(error = otCoapMessageAppendBlock2Option(message, 0, false, coapBlockSize));
        }
    }
#endif

    if (!aArgs[3].IsEmpty())
    {
#if OPENTHREAD_CONFIG_COAP_BLOCKWISE_TRANSFER_ENABLE
        if (coapBlock)
        {
            SuccessOrExit(error = aArgs[3].ParseAsUint32(mBlockCount));
        }
        else
        {
#endif
            payloadLength = aArgs[3].GetLength();

            if (payloadLength > 0)
            {
                SuccessOrExit(error = otCoapMessageSetPayloadMarker(message));
            }
#if OPENTHREAD_CONFIG_COAP_BLOCKWISE_TRANSFER_ENABLE
        }
#endif
    }

    // Embed content into message if given
    if (payloadLength > 0)
    {
        SuccessOrExit(error = otMessageAppend(message, aArgs[3].GetCString(), payloadLength));
    }

    ClearAllBytes(messageInfo);
    messageInfo.mPeerAddr = coapDestinationIp;
    messageInfo.mPeerPort = OT_DEFAULT_COAP_PORT;

#if OPENTHREAD_CONFIG_COAP_OBSERVE_API_ENABLE
    if (aCoapObserve)
    {
        // Make a note of the message details for later so we can cancel it later.
        memcpy(&mRequestAddr, &coapDestinationIp, sizeof(mRequestAddr));
        mRequestTokenLength = otCoapMessageGetTokenLength(message);
        memcpy(mRequestToken, otCoapMessageGetToken(message), mRequestTokenLength);
        // Use `memcpy` instead of `strncpy` here because GCC will give warnings for `strncpy` when the dest's length is
        // not bigger than the src's length.
        memcpy(mRequestUri, coapUri, sizeof(mRequestUri) - 1);
    }
#endif

    if ((coapType == OT_COAP_TYPE_CONFIRMABLE) || (aCoapCode == OT_COAP_CODE_GET))
    {
#if OPENTHREAD_CONFIG_COAP_BLOCKWISE_TRANSFER_ENABLE
        if (coapBlock)
        {
            if (aCoapCode == OT_COAP_CODE_PUT || aCoapCode == OT_COAP_CODE_POST)
            {
                SuccessOrExit(error = otCoapMessageSetPayloadMarker(message));
            }
            error = otCoapSendRequestBlockWiseWithParameters(GetInstancePtr(), message, &messageInfo,
                                                             &Coap::HandleResponse, this, GetRequestTxParameters(),
                                                             Coap::BlockwiseTransmitHook, Coap::BlockwiseReceiveHook);
        }
        else
        {
#endif
            error = otCoapSendRequestWithParameters(GetInstancePtr(), message, &messageInfo, &Coap::HandleResponse,
                                                    this, GetRequestTxParameters());
#if OPENTHREAD_CONFIG_COAP_BLOCKWISE_TRANSFER_ENABLE
        }
#endif
    }
    else
    {
        error = otCoapSendRequestWithParameters(GetInstancePtr(), message, &messageInfo, nullptr, nullptr,
                                                GetResponseTxParameters());
    }

exit:

    if ((error != OT_ERROR_NONE) && (message != nullptr))
    {
        otMessageFree(message);
    }

    return error;
}

otError Coap::Process(Arg aArgs[])
{
#define CmdEntry(aCommandString)                            \
    {                                                       \
        aCommandString, &Coap::Process<Cmd(aCommandString)> \
    }

    static constexpr Command kCommands[] = {
#if OPENTHREAD_CONFIG_COAP_OBSERVE_API_ENABLE
        CmdEntry("cancel"),
#endif
        CmdEntry("delete"),
        CmdEntry("get"),
#if OPENTHREAD_CONFIG_COAP_OBSERVE_API_ENABLE
        CmdEntry("observe"),
#endif
        CmdEntry("parameters"),
        CmdEntry("post"),
        CmdEntry("put"),
        CmdEntry("resource"),
        CmdEntry("set"),
        CmdEntry("start"),
        CmdEntry("stop"),
    };

#undef CmdEntry

    static_assert(BinarySearch::IsSorted(kCommands), "kCommands is not sorted");

    otError        error = OT_ERROR_INVALID_COMMAND;
    const Command *command;

    if (aArgs[0].IsEmpty() || (aArgs[0] == "help"))
    {
        OutputCommandTable(kCommands);
        ExitNow(error = aArgs[0].IsEmpty() ? OT_ERROR_INVALID_ARGS : OT_ERROR_NONE);
    }

    command = BinarySearch::Find(aArgs[0].GetCString(), kCommands);
    VerifyOrExit(command != nullptr);

    error = (this->*command->mHandler)(aArgs + 1);

exit:
    return error;
}

void Coap::HandleRequest(void *aContext, otMessage *aMessage, const otMessageInfo *aMessageInfo)
{
    static_cast<Coap *>(aContext)->HandleRequest(aMessage, aMessageInfo);
}

void Coap::HandleRequest(otMessage *aMessage, const otMessageInfo *aMessageInfo)
{
    otError    error           = OT_ERROR_NONE;
    otMessage *responseMessage = nullptr;
    otCoapCode responseCode    = OT_COAP_CODE_EMPTY;
#if OPENTHREAD_CONFIG_COAP_OBSERVE_API_ENABLE
    uint64_t observe        = 0;
    bool     observePresent = false;
#endif
#if OPENTHREAD_CONFIG_COAP_BLOCKWISE_TRANSFER_ENABLE
    uint64_t blockValue   = 0;
    bool     blockPresent = false;
#endif
#if OPENTHREAD_CONFIG_COAP_BLOCKWISE_TRANSFER_ENABLE || OPENTHREAD_CONFIG_COAP_OBSERVE_API_ENABLE
    otCoapOptionIterator iterator;
#endif

    OutputFormat("coap request from ");
    OutputIp6Address(aMessageInfo->mPeerAddr);
    OutputFormat(" ");

    switch (otCoapMessageGetCode(aMessage))
    {
    case OT_COAP_CODE_GET:
        OutputFormat("GET");
#if OPENTHREAD_CONFIG_COAP_BLOCKWISE_TRANSFER_ENABLE || OPENTHREAD_CONFIG_COAP_OBSERVE_API_ENABLE
        SuccessOrExit(error = otCoapOptionIteratorInit(&iterator, aMessage));
#endif
#if OPENTHREAD_CONFIG_COAP_OBSERVE_API_ENABLE
        if (otCoapOptionIteratorGetFirstOptionMatching(&iterator, OT_COAP_OPTION_OBSERVE) != nullptr)
        {
            SuccessOrExit(error = otCoapOptionIteratorGetOptionUintValue(&iterator, &observe));
            observePresent = true;

            OutputFormat(" OBS=");
            OutputUint64(observe);
        }
#endif
#if OPENTHREAD_CONFIG_COAP_BLOCKWISE_TRANSFER_ENABLE
        if (otCoapOptionIteratorGetFirstOptionMatching(&iterator, OT_COAP_OPTION_BLOCK2) != nullptr)
        {
            SuccessOrExit(error = otCoapOptionIteratorGetOptionUintValue(&iterator, &blockValue));
            blockPresent = true;
        }
#endif
        break;

    case OT_COAP_CODE_DELETE:
        OutputFormat("DELETE");
        break;

    case OT_COAP_CODE_PUT:
        OutputFormat("PUT");
        break;

    case OT_COAP_CODE_POST:
        OutputFormat("POST");
        break;

    default:
        OutputLine("Undefined");
        ExitNow(error = OT_ERROR_PARSE);
    }

    PrintPayload(aMessage);

    if (otCoapMessageGetType(aMessage) == OT_COAP_TYPE_CONFIRMABLE ||
        otCoapMessageGetCode(aMessage) == OT_COAP_CODE_GET)
    {
#if OPENTHREAD_CONFIG_COAP_OBSERVE_API_ENABLE
        if (observePresent && (mSubscriberTokenLength > 0) && (observe == 0))
        {
            // There is already a subscriber
            responseCode = OT_COAP_CODE_SERVICE_UNAVAILABLE;
        }
        else
#endif
            if (otCoapMessageGetCode(aMessage) == OT_COAP_CODE_GET)
        {
            responseCode = OT_COAP_CODE_CONTENT;
#if OPENTHREAD_CONFIG_COAP_OBSERVE_API_ENABLE
            if (observePresent)
            {
                if (observe == 0)
                {
                    // New subscriber
                    OutputLine("Subscribing client");
                    mSubscriberSock.mAddress = aMessageInfo->mPeerAddr;
                    mSubscriberSock.mPort    = aMessageInfo->mPeerPort;
                    mSubscriberTokenLength   = otCoapMessageGetTokenLength(aMessage);
                    memcpy(mSubscriberToken, otCoapMessageGetToken(aMessage), mSubscriberTokenLength);

                    /*
                     * Implementer note.
                     *
                     * Here, we try to match a confirmable GET request with confirmable
                     * notifications, however this is not a requirement of RFC7641:
                     * the server can send notifications of either type regardless of
                     * what the client used to subscribe initially.
                     */
                    mSubscriberConfirmableNotifications = (otCoapMessageGetType(aMessage) == OT_COAP_TYPE_CONFIRMABLE);
                }
                else if (observe == 1)
                {
                    // See if it matches our subscriber token
                    if ((otCoapMessageGetTokenLength(aMessage) == mSubscriberTokenLength) &&
                        (memcmp(otCoapMessageGetToken(aMessage), mSubscriberToken, mSubscriberTokenLength) == 0))
                    {
                        // Unsubscribe request
                        CancelSubscriber();
                    }
                }
            }
#endif // OPENTHREAD_CONFIG_COAP_OBSERVE_API_ENABLE
        }
        else
        {
            responseCode = OT_COAP_CODE_CHANGED;
        }

        responseMessage = otCoapNewMessage(GetInstancePtr(), nullptr);
        VerifyOrExit(responseMessage != nullptr, error = OT_ERROR_NO_BUFS);

        SuccessOrExit(
            error = otCoapMessageInitResponse(responseMessage, aMessage, OT_COAP_TYPE_ACKNOWLEDGMENT, responseCode));

        if (responseCode == OT_COAP_CODE_CONTENT)
        {
#if OPENTHREAD_CONFIG_COAP_OBSERVE_API_ENABLE
            if (observePresent && (observe == 0))
            {
                SuccessOrExit(error = otCoapMessageAppendObserveOption(responseMessage, mObserveSerial++));
            }
#endif
#if OPENTHREAD_CONFIG_COAP_BLOCKWISE_TRANSFER_ENABLE
            if (blockPresent)
            {
                SuccessOrExit(error = otCoapMessageAppendBlock2Option(responseMessage,
                                                                      static_cast<uint32_t>(blockValue >> 4), true,
                                                                      static_cast<otCoapBlockSzx>(blockValue & 0x7)));
                SuccessOrExit(error = otCoapMessageSetPayloadMarker(responseMessage));
            }
            else
            {
#endif
                SuccessOrExit(error = otCoapMessageSetPayloadMarker(responseMessage));
                SuccessOrExit(error = otMessageAppend(responseMessage, mResourceContent,
                                                      static_cast<uint16_t>(strlen(mResourceContent))));
#if OPENTHREAD_CONFIG_COAP_BLOCKWISE_TRANSFER_ENABLE
            }
#endif
        }

#if OPENTHREAD_CONFIG_COAP_BLOCKWISE_TRANSFER_ENABLE
        if (blockPresent)
        {
            SuccessOrExit(error = otCoapSendResponseBlockWiseWithParameters(GetInstancePtr(), responseMessage,
                                                                            aMessageInfo, GetResponseTxParameters(),
                                                                            this, mResource.mTransmitHook));
        }
        else
        {
#endif
            SuccessOrExit(error = otCoapSendResponseWithParameters(GetInstancePtr(), responseMessage, aMessageInfo,
                                                                   GetResponseTxParameters()));
#if OPENTHREAD_CONFIG_COAP_BLOCKWISE_TRANSFER_ENABLE
        }
#endif
    }

exit:

    if (error != OT_ERROR_NONE)
    {
        if (responseMessage != nullptr)
        {
            OutputLine("coap send response error %d: %s", error, otThreadErrorToString(error));
            otMessageFree(responseMessage);
        }
    }
    else if (responseCode >= OT_COAP_CODE_RESPONSE_MIN)
    {
        OutputLine("coap response sent");
    }
}

#if OPENTHREAD_CONFIG_COAP_OBSERVE_API_ENABLE
void Coap::HandleNotificationResponse(void                *aContext,
                                      otMessage           *aMessage,
                                      const otMessageInfo *aMessageInfo,
                                      otError              aError)
{
    static_cast<Coap *>(aContext)->HandleNotificationResponse(aMessage, aMessageInfo, aError);
}

void Coap::HandleNotificationResponse(otMessage *aMessage, const otMessageInfo *aMessageInfo, otError aError)
{
    OT_UNUSED_VARIABLE(aMessage);

    switch (aError)
    {
    case OT_ERROR_NONE:
        if (aMessageInfo != nullptr)
        {
            OutputFormat("Received ACK in reply to notification from ");
            OutputIp6AddressLine(aMessageInfo->mPeerAddr);
        }
        break;

    default:
        OutputLine("coap receive notification response error %d: %s", aError, otThreadErrorToString(aError));
        CancelSubscriber();
        break;
    }
}
#endif // OPENTHREAD_CONFIG_COAP_OBSERVE_API_ENABLE

void Coap::HandleResponse(void *aContext, otMessage *aMessage, const otMessageInfo *aMessageInfo, otError aError)
{
    static_cast<Coap *>(aContext)->HandleResponse(aMessage, aMessageInfo, aError);
}

void Coap::HandleResponse(otMessage *aMessage, const otMessageInfo *aMessageInfo, otError aError)
{
    if (aError != OT_ERROR_NONE)
    {
        OutputLine("coap receive response error %d: %s", aError, otThreadErrorToString(aError));
    }
    else if ((aMessageInfo != nullptr) && (aMessage != nullptr))
    {
#if OPENTHREAD_CONFIG_COAP_OBSERVE_API_ENABLE
        otCoapOptionIterator iterator;
#endif

        OutputFormat("coap response from ");
        OutputIp6Address(aMessageInfo->mPeerAddr);

#if OPENTHREAD_CONFIG_COAP_OBSERVE_API_ENABLE
        if (otCoapOptionIteratorInit(&iterator, aMessage) == OT_ERROR_NONE)
        {
            const otCoapOption *observeOpt =
                otCoapOptionIteratorGetFirstOptionMatching(&iterator, OT_COAP_OPTION_OBSERVE);

            if (observeOpt != nullptr)
            {
                uint64_t observeVal = 0;
                otError  error      = otCoapOptionIteratorGetOptionUintValue(&iterator, &observeVal);

                if (error == OT_ERROR_NONE)
                {
                    OutputFormat(" OBS=");
                    OutputUint64(observeVal);
                }
            }
        }
#endif
        PrintPayload(aMessage);
    }
}

#if OPENTHREAD_CONFIG_COAP_BLOCKWISE_TRANSFER_ENABLE
otError Coap::BlockwiseReceiveHook(void          *aContext,
                                   const uint8_t *aBlock,
                                   uint32_t       aPosition,
                                   uint16_t       aBlockLength,
                                   bool           aMore,
                                   uint32_t       aTotalLength)
{
    return static_cast<Coap *>(aContext)->BlockwiseReceiveHook(aBlock, aPosition, aBlockLength, aMore, aTotalLength);
}

otError Coap::BlockwiseReceiveHook(const uint8_t *aBlock,
                                   uint32_t       aPosition,
                                   uint16_t       aBlockLength,
                                   bool           aMore,
                                   uint32_t       aTotalLength)
{
    OT_UNUSED_VARIABLE(aMore);
    OT_UNUSED_VARIABLE(aTotalLength);

    OutputLine("received block: Num %i Len %i", aPosition / aBlockLength, aBlockLength);

    for (uint16_t i = 0; i < aBlockLength / 16; i++)
    {
        OutputBytesLine(&aBlock[i * 16], 16);
    }

    return OT_ERROR_NONE;
}

otError Coap::BlockwiseTransmitHook(void     *aContext,
                                    uint8_t  *aBlock,
                                    uint32_t  aPosition,
                                    uint16_t *aBlockLength,
                                    bool     *aMore)
{
    return static_cast<Coap *>(aContext)->BlockwiseTransmitHook(aBlock, aPosition, aBlockLength, aMore);
}

otError Coap::BlockwiseTransmitHook(uint8_t *aBlock, uint32_t aPosition, uint16_t *aBlockLength, bool *aMore)
{
    static uint32_t blockCount = 0;
    OT_UNUSED_VARIABLE(aPosition);

    // Send a random payload
    otRandomNonCryptoFillBuffer(aBlock, *aBlockLength);

    OutputLine("send block: Num %i Len %i", blockCount, *aBlockLength);

    for (uint16_t i = 0; i < *aBlockLength / 16; i++)
    {
        OutputBytesLine(&aBlock[i * 16], 16);
    }

    if (blockCount == mBlockCount - 1)
    {
        blockCount = 0;
        *aMore     = false;
    }
    else
    {
        *aMore = true;
        blockCount++;
    }

    return OT_ERROR_NONE;
}
#endif // OPENTHREAD_CONFIG_COAP_BLOCKWISE_TRANSFER_ENABLE

} // namespace Cli
} // namespace ot

#endif // OPENTHREAD_CONFIG_COAP_API_ENABLE
