/*
 *    Copyright (c) 2016-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 full thread device specified Spinel interface to the OpenThread stack.
 */

#include "ncp_base.hpp"
#include <openthread/config.h>

#if OPENTHREAD_CONFIG_CHANNEL_MANAGER_ENABLE
#include <openthread/channel_manager.h>
#endif
#if OPENTHREAD_CONFIG_CHILD_SUPERVISION_ENABLE
#include <openthread/child_supervision.h>
#endif
#include <openthread/dataset.h>
#include <openthread/dataset_ftd.h>
#include <openthread/diag.h>
#include <openthread/icmp6.h>
#include <openthread/ncp.h>
#include <openthread/thread_ftd.h>
#include <openthread/platform/misc.h>

#include "common/code_utils.hpp"
#include "common/debug.hpp"
#include "common/instance.hpp"
#if OPENTHREAD_CONFIG_COMMISSIONER_ENABLE
#include "meshcop/commissioner.hpp"
#endif

#if OPENTHREAD_FTD
namespace ot {
namespace Ncp {

otError NcpBase::EncodeChildInfo(const otChildInfo &aChildInfo)
{
    otError error = OT_ERROR_NONE;
    uint8_t modeFlags;

    modeFlags = LinkFlagsToFlagByte(aChildInfo.mRxOnWhenIdle, aChildInfo.mSecureDataRequest,
                                    aChildInfo.mFullThreadDevice, aChildInfo.mFullNetworkData);

    SuccessOrExit(error = mEncoder.WriteEui64(aChildInfo.mExtAddress));
    SuccessOrExit(error = mEncoder.WriteUint16(aChildInfo.mRloc16));
    SuccessOrExit(error = mEncoder.WriteUint32(aChildInfo.mTimeout));
    SuccessOrExit(error = mEncoder.WriteUint32(aChildInfo.mAge));
    SuccessOrExit(error = mEncoder.WriteUint8(aChildInfo.mNetworkDataVersion));
    SuccessOrExit(error = mEncoder.WriteUint8(aChildInfo.mLinkQualityIn));
    SuccessOrExit(error = mEncoder.WriteInt8(aChildInfo.mAverageRssi));
    SuccessOrExit(error = mEncoder.WriteUint8(modeFlags));
    SuccessOrExit(error = mEncoder.WriteInt8(aChildInfo.mLastRssi));

exit:
    return error;
}

// ----------------------------------------------------------------------------
// MARK: Property/Status Changed
// ----------------------------------------------------------------------------

void NcpBase::HandleParentResponseInfo(otThreadParentResponseInfo *aInfo, void *aContext)
{
    VerifyOrExit(aInfo && aContext);

    static_cast<NcpBase *>(aContext)->HandleParentResponseInfo(*aInfo);

exit:
    return;
}

void NcpBase::HandleParentResponseInfo(const otThreadParentResponseInfo &aInfo)
{
    VerifyOrExit(!mChangedPropsSet.IsPropertyFiltered(SPINEL_PROP_PARENT_RESPONSE_INFO));

    SuccessOrExit(mEncoder.BeginFrame(SPINEL_HEADER_FLAG | SPINEL_HEADER_IID_0, SPINEL_CMD_PROP_VALUE_IS,
                                      SPINEL_PROP_PARENT_RESPONSE_INFO));

    SuccessOrExit(mEncoder.WriteEui64(aInfo.mExtAddr));
    SuccessOrExit(mEncoder.WriteUint16(aInfo.mRloc16));
    SuccessOrExit(mEncoder.WriteInt8(aInfo.mRssi));
    SuccessOrExit(mEncoder.WriteInt8(aInfo.mPriority));
    SuccessOrExit(mEncoder.WriteUint8(aInfo.mLinkQuality3));
    SuccessOrExit(mEncoder.WriteUint8(aInfo.mLinkQuality2));
    SuccessOrExit(mEncoder.WriteUint8(aInfo.mLinkQuality1));
    SuccessOrExit(mEncoder.WriteBool(aInfo.mIsAttached));

    SuccessOrExit(mEncoder.EndFrame());

exit:
    return;
}

void NcpBase::HandleNeighborTableChanged(otNeighborTableEvent aEvent, const otNeighborTableEntryInfo *aEntry)
{
    GetNcpInstance()->HandleNeighborTableChanged(aEvent, *aEntry);
}

void NcpBase::HandleNeighborTableChanged(otNeighborTableEvent aEvent, const otNeighborTableEntryInfo &aEntry)
{
    otError           error   = OT_ERROR_NONE;
    unsigned int      command = SPINEL_CMD_PROP_VALUE_REMOVED;
    spinel_prop_key_t property;

    switch (aEvent)
    {
    case OT_NEIGHBOR_TABLE_EVENT_CHILD_ADDED:
        command = SPINEL_CMD_PROP_VALUE_INSERTED;
        // Fall through
    case OT_NEIGHBOR_TABLE_EVENT_CHILD_REMOVED:
        property = SPINEL_PROP_THREAD_CHILD_TABLE;
        VerifyOrExit(!aEntry.mInfo.mChild.mIsStateRestoring);
        break;

    case OT_NEIGHBOR_TABLE_EVENT_ROUTER_ADDED:
        command = SPINEL_CMD_PROP_VALUE_INSERTED;
        // Fall through
    case OT_NEIGHBOR_TABLE_EVENT_ROUTER_REMOVED:
        property = SPINEL_PROP_THREAD_NEIGHBOR_TABLE;
        break;

    default:
        ExitNow();
    }

    VerifyOrExit(!mChangedPropsSet.IsPropertyFiltered(property));

    SuccessOrExit(error = mEncoder.BeginFrame(SPINEL_HEADER_FLAG | SPINEL_HEADER_IID_0, command, property));

    if (property == SPINEL_PROP_THREAD_CHILD_TABLE)
    {
        SuccessOrExit(error = EncodeChildInfo(aEntry.mInfo.mChild));
    }
    else
    {
        SuccessOrExit(error = EncodeNeighborInfo(aEntry.mInfo.mRouter));
    }

    SuccessOrExit(error = mEncoder.EndFrame());

exit:

    // If the frame can not be added (out of NCP buffer space), we remember
    // to send an async `LAST_STATUS(NOMEM)` when buffer space becomes
    // available. Also `mShouldEmitChildTableUpdate` flag is set to `true` so
    // that the entire child table is later emitted as `VALUE_IS` spinel frame
    // update from `ProcessThreadChangedFlags()`.

    if (error != OT_ERROR_NONE)
    {
        if (property == SPINEL_PROP_THREAD_CHILD_TABLE)
        {
            mShouldEmitChildTableUpdate = true;
        }

        mChangedPropsSet.AddLastStatus(SPINEL_STATUS_NOMEM);
        mUpdateChangedPropsTask.Post();
    }
}

// ----------------------------------------------------------------------------
// MARK: Individual Property Handlers
// ----------------------------------------------------------------------------

template <> otError NcpBase::HandlePropertyGet<SPINEL_PROP_THREAD_LOCAL_LEADER_WEIGHT>(void)
{
    return mEncoder.WriteUint8(otThreadGetLocalLeaderWeight(mInstance));
}

template <> otError NcpBase::HandlePropertyGet<SPINEL_PROP_THREAD_LEADER_WEIGHT>(void)
{
    return mEncoder.WriteUint8(otThreadGetLeaderWeight(mInstance));
}

template <> otError NcpBase::HandlePropertyGet<SPINEL_PROP_THREAD_CHILD_TABLE>(void)
{
    otError     error = OT_ERROR_NONE;
    otChildInfo childInfo;
    uint16_t    maxChildren;

    maxChildren = otThreadGetMaxAllowedChildren(mInstance);

    for (uint16_t index = 0; index < maxChildren; index++)
    {
        if ((otThreadGetChildInfoByIndex(mInstance, index, &childInfo) != OT_ERROR_NONE) || childInfo.mIsStateRestoring)
        {
            continue;
        }

        SuccessOrExit(error = mEncoder.OpenStruct());
        SuccessOrExit(error = EncodeChildInfo(childInfo));
        SuccessOrExit(error = mEncoder.CloseStruct());
    }

exit:
    return error;
}

template <> otError NcpBase::HandlePropertyGet<SPINEL_PROP_THREAD_ROUTER_TABLE>(void)
{
    otError      error = OT_ERROR_NONE;
    otRouterInfo routerInfo;
    uint8_t      maxRouterId;

    maxRouterId = otThreadGetMaxRouterId(mInstance);

    for (uint8_t routerId = 0; routerId <= maxRouterId; routerId++)
    {
        if ((otThreadGetRouterInfo(mInstance, routerId, &routerInfo) != OT_ERROR_NONE) || !routerInfo.mAllocated)
        {
            continue;
        }

        SuccessOrExit(error = mEncoder.OpenStruct());

        SuccessOrExit(error = mEncoder.WriteEui64(routerInfo.mExtAddress));
        SuccessOrExit(error = mEncoder.WriteUint16(routerInfo.mRloc16));
        SuccessOrExit(error = mEncoder.WriteUint8(routerInfo.mRouterId));
        SuccessOrExit(error = mEncoder.WriteUint8(routerInfo.mNextHop));
        SuccessOrExit(error = mEncoder.WriteUint8(routerInfo.mPathCost));
        SuccessOrExit(error = mEncoder.WriteUint8(routerInfo.mLinkQualityIn));
        SuccessOrExit(error = mEncoder.WriteUint8(routerInfo.mLinkQualityOut));
        SuccessOrExit(error = mEncoder.WriteUint8(routerInfo.mAge));
        SuccessOrExit(error = mEncoder.WriteBool(routerInfo.mLinkEstablished));

        SuccessOrExit(error = mEncoder.CloseStruct());
    }

exit:
    return error;
}

template <> otError NcpBase::HandlePropertyGet<SPINEL_PROP_THREAD_CHILD_TABLE_ADDRESSES>(void)
{
    otError                   error = OT_ERROR_NONE;
    otChildInfo               childInfo;
    uint16_t                  maxChildren;
    otIp6Address              ip6Address;
    otChildIp6AddressIterator iterator = OT_CHILD_IP6_ADDRESS_ITERATOR_INIT;

    maxChildren = otThreadGetMaxAllowedChildren(mInstance);

    for (uint16_t childIndex = 0; childIndex < maxChildren; childIndex++)
    {
        if ((otThreadGetChildInfoByIndex(mInstance, childIndex, &childInfo) != OT_ERROR_NONE) ||
            childInfo.mIsStateRestoring)
        {
            continue;
        }

        SuccessOrExit(error = mEncoder.OpenStruct());

        SuccessOrExit(error = mEncoder.WriteEui64(childInfo.mExtAddress));
        SuccessOrExit(error = mEncoder.WriteUint16(childInfo.mRloc16));

        iterator = OT_CHILD_IP6_ADDRESS_ITERATOR_INIT;

        while (otThreadGetChildNextIp6Address(mInstance, childIndex, &iterator, &ip6Address) == OT_ERROR_NONE)
        {
            SuccessOrExit(error = mEncoder.WriteIp6Address(ip6Address));
        }

        SuccessOrExit(error = mEncoder.CloseStruct());
    }

exit:
    return error;
}

template <> otError NcpBase::HandlePropertyGet<SPINEL_PROP_THREAD_ROUTER_ROLE_ENABLED>(void)
{
    return mEncoder.WriteBool(otThreadIsRouterRoleEnabled(mInstance));
}

template <> otError NcpBase::HandlePropertySet<SPINEL_PROP_THREAD_ROUTER_ROLE_ENABLED>(void)
{
    bool    enabled;
    otError error = OT_ERROR_NONE;

    SuccessOrExit(error = mDecoder.ReadBool(enabled));

    otThreadSetRouterRoleEnabled(mInstance, enabled);

exit:
    return error;
}

template <> otError NcpBase::HandlePropertyGet<SPINEL_PROP_MAC_MAX_RETRY_NUMBER_INDIRECT>(void)
{
    return mEncoder.WriteUint8(otLinkGetMaxFrameRetriesIndirect(mInstance));
}

template <> otError NcpBase::HandlePropertySet<SPINEL_PROP_MAC_MAX_RETRY_NUMBER_INDIRECT>(void)
{
    uint8_t maxFrameRetriesIndirect;
    otError error = OT_ERROR_NONE;

    SuccessOrExit(error = mDecoder.ReadUint8(maxFrameRetriesIndirect));
    otLinkSetMaxFrameRetriesIndirect(mInstance, maxFrameRetriesIndirect);

exit:
    return error;
}

template <> otError NcpBase::HandlePropertyGet<SPINEL_PROP_NET_PSKC>(void)
{
    return mEncoder.WriteData(otThreadGetPskc(mInstance)->m8, sizeof(spinel_net_pskc_t));
}

template <> otError NcpBase::HandlePropertySet<SPINEL_PROP_NET_PSKC>(void)
{
    const uint8_t *ptr = NULL;
    uint16_t       len;
    otError        error = OT_ERROR_NONE;

    SuccessOrExit(error = mDecoder.ReadData(ptr, len));

    VerifyOrExit(len == sizeof(spinel_net_pskc_t), error = OT_ERROR_PARSE);

    error = otThreadSetPskc(mInstance, reinterpret_cast<const otPskc *>(ptr));

exit:
    return error;
}

template <> otError NcpBase::HandlePropertySet<SPINEL_PROP_NET_PARTITION_ID>(void)
{
    uint32_t partitionId = 0;
    otError  error       = OT_ERROR_NONE;

    SuccessOrExit(error = mDecoder.ReadUint32(partitionId));

    otThreadSetLocalLeaderPartitionId(mInstance, partitionId);

exit:
    return error;
}

template <> otError NcpBase::HandlePropertyGet<SPINEL_PROP_THREAD_CHILD_COUNT_MAX>(void)
{
    return mEncoder.WriteUint8(static_cast<uint8_t>(otThreadGetMaxAllowedChildren(mInstance)));
}

template <> otError NcpBase::HandlePropertySet<SPINEL_PROP_THREAD_CHILD_COUNT_MAX>(void)
{
    uint8_t maxChildren = 0;
    otError error       = OT_ERROR_NONE;

    SuccessOrExit(error = mDecoder.ReadUint8(maxChildren));

    error = otThreadSetMaxAllowedChildren(mInstance, maxChildren);

exit:
    return error;
}

template <> otError NcpBase::HandlePropertyGet<SPINEL_PROP_THREAD_ROUTER_UPGRADE_THRESHOLD>(void)
{
    return mEncoder.WriteUint8(otThreadGetRouterUpgradeThreshold(mInstance));
}

template <> otError NcpBase::HandlePropertySet<SPINEL_PROP_THREAD_ROUTER_UPGRADE_THRESHOLD>(void)
{
    uint8_t threshold = 0;
    otError error     = OT_ERROR_NONE;

    SuccessOrExit(error = mDecoder.ReadUint8(threshold));

    otThreadSetRouterUpgradeThreshold(mInstance, threshold);

exit:
    return error;
}

template <> otError NcpBase::HandlePropertyGet<SPINEL_PROP_THREAD_ROUTER_DOWNGRADE_THRESHOLD>(void)
{
    return mEncoder.WriteUint8(otThreadGetRouterDowngradeThreshold(mInstance));
}

template <> otError NcpBase::HandlePropertySet<SPINEL_PROP_THREAD_ROUTER_DOWNGRADE_THRESHOLD>(void)
{
    uint8_t threshold = 0;
    otError error     = OT_ERROR_NONE;

    SuccessOrExit(error = mDecoder.ReadUint8(threshold));

    otThreadSetRouterDowngradeThreshold(mInstance, threshold);

exit:
    return error;
}

template <> otError NcpBase::HandlePropertyGet<SPINEL_PROP_THREAD_ROUTER_SELECTION_JITTER>(void)
{
    return mEncoder.WriteUint8(otThreadGetRouterSelectionJitter(mInstance));
}

template <> otError NcpBase::HandlePropertySet<SPINEL_PROP_THREAD_ROUTER_SELECTION_JITTER>(void)
{
    uint8_t jitter = 0;
    otError error  = OT_ERROR_NONE;

    SuccessOrExit(error = mDecoder.ReadUint8(jitter));

    otThreadSetRouterSelectionJitter(mInstance, jitter);

exit:
    return error;
}

template <> otError NcpBase::HandlePropertyGet<SPINEL_PROP_THREAD_CONTEXT_REUSE_DELAY>(void)
{
    return mEncoder.WriteUint32(otThreadGetContextIdReuseDelay(mInstance));
}

template <> otError NcpBase::HandlePropertySet<SPINEL_PROP_THREAD_CONTEXT_REUSE_DELAY>(void)
{
    uint32_t delay = 0;
    otError  error = OT_ERROR_NONE;

    SuccessOrExit(error = mDecoder.ReadUint32(delay));

    otThreadSetContextIdReuseDelay(mInstance, delay);

exit:
    return error;
}

template <> otError NcpBase::HandlePropertyGet<SPINEL_PROP_THREAD_NETWORK_ID_TIMEOUT>(void)
{
    return mEncoder.WriteUint8(otThreadGetNetworkIdTimeout(mInstance));
}

template <> otError NcpBase::HandlePropertySet<SPINEL_PROP_THREAD_NETWORK_ID_TIMEOUT>(void)
{
    uint8_t timeout = 0;
    otError error   = OT_ERROR_NONE;

    SuccessOrExit(error = mDecoder.ReadUint8(timeout));

    otThreadSetNetworkIdTimeout(mInstance, timeout);

exit:
    return error;
}

template <> otError NcpBase::HandlePropertyGet<SPINEL_PROP_THREAD_NEW_DATASET>(void)
{
    otError              error;
    otOperationalDataset dataset;

    error = otDatasetCreateNewNetwork(mInstance, &dataset);

    if (error == OT_ERROR_NONE)
    {
        error = EncodeOperationalDataset(dataset);
    }
    else
    {
        error = mEncoder.OverwriteWithLastStatusError(ThreadErrorToSpinelStatus(error));
    }

    return error;
}

#if OPENTHREAD_CONFIG_COMMISSIONER_ENABLE

template <> otError NcpBase::HandlePropertyGet<SPINEL_PROP_MESHCOP_COMMISSIONER_STATE>(void)
{
    uint8_t state = SPINEL_MESHCOP_COMMISSIONER_STATE_DISABLED;

    switch (otCommissionerGetState(mInstance))
    {
    case OT_COMMISSIONER_STATE_DISABLED:
        state = SPINEL_MESHCOP_COMMISSIONER_STATE_DISABLED;
        break;

    case OT_COMMISSIONER_STATE_PETITION:
        state = SPINEL_MESHCOP_COMMISSIONER_STATE_PETITION;
        break;

    case OT_COMMISSIONER_STATE_ACTIVE:
        state = SPINEL_MESHCOP_COMMISSIONER_STATE_ACTIVE;
        break;
    }

    return mEncoder.WriteUint8(state);
}

template <> otError NcpBase::HandlePropertySet<SPINEL_PROP_MESHCOP_COMMISSIONER_STATE>(void)
{
    uint8_t state;
    otError error = OT_ERROR_NONE;

    SuccessOrExit(error = mDecoder.ReadUint8(state));

    switch (state)
    {
    case SPINEL_MESHCOP_COMMISSIONER_STATE_DISABLED:
        error = otCommissionerStop(mInstance);
        break;

    case SPINEL_MESHCOP_COMMISSIONER_STATE_ACTIVE:
        error = otCommissionerStart(mInstance, NULL, NULL, NULL);
        break;

    default:
        error = OT_ERROR_INVALID_ARGS;
        break;
    }

exit:
    return error;
}

template <> otError NcpBase::HandlePropertyInsert<SPINEL_PROP_MESHCOP_COMMISSIONER_JOINERS>(void)
{
    otError             error = OT_ERROR_NONE;
    const otExtAddress *eui64;
    uint32_t            timeout;
    const char *        psk;

    SuccessOrExit(error = mDecoder.OpenStruct());

    if (!mDecoder.IsAllReadInStruct())
    {
        SuccessOrExit(error = mDecoder.ReadEui64(eui64));
    }
    else
    {
        // Empty struct indicates any Joiner (no EUI64 is given so NULL is used.).
        eui64 = NULL;
    }

    SuccessOrExit(error = mDecoder.CloseStruct());

    SuccessOrExit(error = mDecoder.ReadUint32(timeout));
    SuccessOrExit(error = mDecoder.ReadUtf8(psk));

    error = otCommissionerAddJoiner(mInstance, eui64, psk, timeout);

exit:
    return error;
}

template <> otError NcpBase::HandlePropertyRemove<SPINEL_PROP_MESHCOP_COMMISSIONER_JOINERS>(void)
{
    otError             error = OT_ERROR_NONE;
    const otExtAddress *eui64;

    SuccessOrExit(error = mDecoder.OpenStruct());

    if (!mDecoder.IsAllReadInStruct())
    {
        SuccessOrExit(error = mDecoder.ReadEui64(eui64));
    }
    else
    {
        // Empty struct indicates any Joiner (no EUI64 is given so NULL is used.).
        eui64 = NULL;
    }

    SuccessOrExit(error = mDecoder.CloseStruct());

    error = otCommissionerRemoveJoiner(mInstance, eui64);

exit:
    return error;
}

template <> otError NcpBase::HandlePropertyGet<SPINEL_PROP_MESHCOP_COMMISSIONER_PROVISIONING_URL>(void)
{
    return mEncoder.WriteUtf8(otCommissionerGetProvisioningUrl(mInstance));
}

template <> otError NcpBase::HandlePropertySet<SPINEL_PROP_MESHCOP_COMMISSIONER_PROVISIONING_URL>(void)
{
    otError     error = OT_ERROR_NONE;
    const char *url;

    SuccessOrExit(error = mDecoder.ReadUtf8(url));

    error = otCommissionerSetProvisioningUrl(mInstance, url);

exit:
    return error;
}

template <> otError NcpBase::HandlePropertyGet<SPINEL_PROP_MESHCOP_COMMISSIONER_SESSION_ID>(void)
{
    return mEncoder.WriteUint16(otCommissionerGetSessionId(mInstance));
}

template <> otError NcpBase::HandlePropertySet<SPINEL_PROP_MESHCOP_COMMISSIONER_ANNOUNCE_BEGIN>(void)
{
    otError             error = OT_ERROR_NONE;
    uint32_t            channelMask;
    uint8_t             count;
    uint16_t            period;
    const otIp6Address *address;

    SuccessOrExit(error = mDecoder.ReadUint32(channelMask));
    SuccessOrExit(error = mDecoder.ReadUint8(count));
    SuccessOrExit(error = mDecoder.ReadUint16(period));
    SuccessOrExit(error = mDecoder.ReadIp6Address(address));

    error = otCommissionerAnnounceBegin(mInstance, channelMask, count, period, address);

exit:
    return error;
}

template <> otError NcpBase::HandlePropertySet<SPINEL_PROP_MESHCOP_COMMISSIONER_ENERGY_SCAN>(void)
{
    otError             error = OT_ERROR_NONE;
    uint32_t            channelMask;
    uint8_t             count;
    uint16_t            period;
    uint16_t            scanDuration;
    const otIp6Address *address;

    SuccessOrExit(error = mDecoder.ReadUint32(channelMask));
    SuccessOrExit(error = mDecoder.ReadUint8(count));
    SuccessOrExit(error = mDecoder.ReadUint16(period));
    SuccessOrExit(error = mDecoder.ReadUint16(scanDuration));
    SuccessOrExit(error = mDecoder.ReadIp6Address(address));

    error = otCommissionerEnergyScan(mInstance, channelMask, count, period, scanDuration, address,
                                     &NcpBase::HandleCommissionerEnergyReport_Jump, this);

exit:
    return error;
}

void NcpBase::HandleCommissionerEnergyReport_Jump(uint32_t       aChannelMask,
                                                  const uint8_t *aEnergyData,
                                                  uint8_t        aLength,
                                                  void *         aContext)
{
    static_cast<NcpBase *>(aContext)->HandleCommissionerEnergyReport(aChannelMask, aEnergyData, aLength);
}

void NcpBase::HandleCommissionerEnergyReport(uint32_t aChannelMask, const uint8_t *aEnergyData, uint8_t aLength)
{
    otError error = OT_ERROR_NONE;

    SuccessOrExit(error = mEncoder.BeginFrame(SPINEL_HEADER_FLAG | SPINEL_HEADER_IID_0, SPINEL_CMD_PROP_VALUE_INSERTED,
                                              SPINEL_PROP_MESHCOP_COMMISSIONER_ENERGY_SCAN_RESULT));
    SuccessOrExit(error = mEncoder.WriteUint32(aChannelMask));
    SuccessOrExit(error = mEncoder.WriteDataWithLen(aEnergyData, aLength));
    SuccessOrExit(error = mEncoder.EndFrame());

exit:

    if (error != OT_ERROR_NONE)
    {
        mChangedPropsSet.AddLastStatus(SPINEL_STATUS_NOMEM);
        mUpdateChangedPropsTask.Post();
    }
}

template <> otError NcpBase::HandlePropertySet<SPINEL_PROP_MESHCOP_COMMISSIONER_PAN_ID_QUERY>(void)
{
    otError             error = OT_ERROR_NONE;
    uint16_t            panId;
    uint32_t            channelMask;
    const otIp6Address *address;

    SuccessOrExit(error = mDecoder.ReadUint16(panId));
    SuccessOrExit(error = mDecoder.ReadUint32(channelMask));
    SuccessOrExit(error = mDecoder.ReadIp6Address(address));

    error = otCommissionerPanIdQuery(mInstance, panId, channelMask, address,
                                     &NcpBase::HandleCommissionerPanIdConflict_Jump, this);

exit:
    return error;
}

void NcpBase::HandleCommissionerPanIdConflict_Jump(uint16_t aPanId, uint32_t aChannelMask, void *aContext)
{
    static_cast<NcpBase *>(aContext)->HandleCommissionerPanIdConflict(aPanId, aChannelMask);
}

void NcpBase::HandleCommissionerPanIdConflict(uint16_t aPanId, uint32_t aChannelMask)
{
    otError error = OT_ERROR_NONE;

    SuccessOrExit(error = mEncoder.BeginFrame(SPINEL_HEADER_FLAG | SPINEL_HEADER_IID_0, SPINEL_CMD_PROP_VALUE_INSERTED,
                                              SPINEL_PROP_MESHCOP_COMMISSIONER_PAN_ID_CONFLICT_RESULT));

    SuccessOrExit(error = mEncoder.WriteUint16(aPanId));
    SuccessOrExit(error = mEncoder.WriteUint32(aChannelMask));
    SuccessOrExit(error = mEncoder.EndFrame());

exit:

    if (error != OT_ERROR_NONE)
    {
        mChangedPropsSet.AddLastStatus(SPINEL_STATUS_NOMEM);
        mUpdateChangedPropsTask.Post();
    }
}

template <> otError NcpBase::HandlePropertySet<SPINEL_PROP_MESHCOP_COMMISSIONER_MGMT_GET>(void)
{
    otError        error = OT_ERROR_NONE;
    const uint8_t *tlvs;
    uint16_t       length;

    SuccessOrExit(error = mDecoder.ReadDataWithLen(tlvs, length));
    VerifyOrExit(length <= 255, error = OT_ERROR_INVALID_ARGS);

    error = otCommissionerSendMgmtGet(mInstance, tlvs, static_cast<uint8_t>(length));

exit:
    return error;
}

template <> otError NcpBase::HandlePropertySet<SPINEL_PROP_MESHCOP_COMMISSIONER_MGMT_SET>(void)
{
    otError                error = OT_ERROR_NONE;
    const uint8_t *        tlvs;
    uint16_t               length;
    otCommissioningDataset dataset;

    SuccessOrExit(error = mDecoder.ReadDataWithLen(tlvs, length));
    VerifyOrExit(length <= 255, error = OT_ERROR_INVALID_ARGS);

    memset(&dataset, 0, sizeof(otCommissioningDataset));
    error = otCommissionerSendMgmtSet(mInstance, &dataset, tlvs, static_cast<uint8_t>(length));

exit:
    return error;
}

otError NcpBase::HandlePropertySet_SPINEL_PROP_MESHCOP_COMMISSIONER_GENERATE_PSKC(uint8_t aHeader)
{
    otError        error = OT_ERROR_NONE;
    const char *   passPhrase;
    const char *   networkName;
    const uint8_t *extPanIdData;
    uint16_t       length;
    otPskc         pskc;

    SuccessOrExit(error = mDecoder.ReadUtf8(passPhrase));
    SuccessOrExit(error = mDecoder.ReadUtf8(networkName));
    SuccessOrExit(error = mDecoder.ReadDataWithLen(extPanIdData, length));
    VerifyOrExit(length == sizeof(spinel_net_xpanid_t), error = OT_ERROR_PARSE);

    SuccessOrExit(error = otCommissionerGeneratePskc(passPhrase, networkName,
                                                     reinterpret_cast<const otExtendedPanId *>(extPanIdData), &pskc));

    SuccessOrExit(
        error = mEncoder.BeginFrame(aHeader, SPINEL_CMD_PROP_VALUE_IS, SPINEL_PROP_MESHCOP_COMMISSIONER_GENERATE_PSKC));
    SuccessOrExit(error = mEncoder.WriteData(pskc.m8, sizeof(pskc)));
    SuccessOrExit(error = mEncoder.EndFrame());

exit:
    return error;
}

// SPINEL_PROP_THREAD_COMMISSIONER_ENABLED is replaced by SPINEL_PROP_MESHCOP_COMMISSIONER_STATE. Please use the new
// property. The old property/implementation remains for backward compatibility.

template <> otError NcpBase::HandlePropertyGet<SPINEL_PROP_THREAD_COMMISSIONER_ENABLED>(void)
{
    return mEncoder.WriteBool(otCommissionerGetState(mInstance) == OT_COMMISSIONER_STATE_ACTIVE);
}

otError NcpBase::HandlePropertySet_SPINEL_PROP_THREAD_COMMISSIONER_ENABLED(uint8_t aHeader)
{
    bool    enabled = false;
    otError error   = OT_ERROR_NONE;

    SuccessOrExit(error = mDecoder.ReadBool(enabled));

    if (!enabled)
    {
        error = otCommissionerStop(mInstance);
    }
    else
    {
        error = otCommissionerStart(mInstance, NULL, NULL, NULL);
    }

exit:
    return PrepareLastStatusResponse(aHeader, ThreadErrorToSpinelStatus(error));
}

// SPINEL_PROP_THREAD_JOINERS is replaced by SPINEL_PROP_MESHCOP_COMMISSIONER_JOINERS. Please us the new property.
// The old property/implementation remains for backward compatibility.

template <> otError NcpBase::HandlePropertyInsert<SPINEL_PROP_THREAD_JOINERS>(void)
{
    otError             error         = OT_ERROR_NONE;
    const otExtAddress *eui64         = NULL;
    const char *        pskd          = NULL;
    uint32_t            joinerTimeout = 0;

    SuccessOrExit(error = mDecoder.ReadUtf8(pskd));
    SuccessOrExit(error = mDecoder.ReadUint32(joinerTimeout));

    if (mDecoder.ReadEui64(eui64) != OT_ERROR_NONE)
    {
        eui64 = NULL;
    }

    error = otCommissionerAddJoiner(mInstance, eui64, pskd, joinerTimeout);

exit:
    return error;
}
#endif // OPENTHREAD_CONFIG_COMMISSIONER_ENABLE

template <> otError NcpBase::HandlePropertySet<SPINEL_PROP_THREAD_LOCAL_LEADER_WEIGHT>(void)
{
    uint8_t weight;
    otError error = OT_ERROR_NONE;

    SuccessOrExit(error = mDecoder.ReadUint8(weight));

    otThreadSetLocalLeaderWeight(mInstance, weight);

exit:
    return error;
}

#if OPENTHREAD_CONFIG_MLE_STEERING_DATA_SET_OOB_ENABLE

template <> otError NcpBase::HandlePropertyGet<SPINEL_PROP_THREAD_STEERING_DATA>(void)
{
    return mEncoder.WriteEui64(mSteeringDataAddress);
}

template <> otError NcpBase::HandlePropertySet<SPINEL_PROP_THREAD_STEERING_DATA>(void)
{
    otError error = OT_ERROR_NONE;

    SuccessOrExit(error = mDecoder.ReadEui64(mSteeringDataAddress));

    otThreadSetSteeringData(mInstance, &mSteeringDataAddress);

exit:
    return error;
}
#endif // #if OPENTHREAD_CONFIG_MLE_STEERING_DATA_SET_OOB_ENABLE

template <> otError NcpBase::HandlePropertyGet<SPINEL_PROP_THREAD_PREFERRED_ROUTER_ID>(void)
{
    return mEncoder.WriteUint8(mPreferredRouteId);
}

template <> otError NcpBase::HandlePropertySet<SPINEL_PROP_THREAD_PREFERRED_ROUTER_ID>(void)
{
    otError error = OT_ERROR_NONE;

    SuccessOrExit(error = mDecoder.ReadUint8(mPreferredRouteId));

    SuccessOrExit(error = otThreadSetPreferredRouterId(mInstance, mPreferredRouteId));

exit:
    return error;
}

template <> otError NcpBase::HandlePropertyRemove<SPINEL_PROP_THREAD_ACTIVE_ROUTER_IDS>(void)
{
    otError error = OT_ERROR_NONE;
    uint8_t routerId;

    SuccessOrExit(error = mDecoder.ReadUint8(routerId));

    error = otThreadReleaseRouterId(mInstance, routerId);

    // `INVALID_STATE` is returned when router ID was not allocated (i.e. not in the list)
    // in such a case, the "remove" operation can be considered successful.

    if (error == OT_ERROR_INVALID_STATE)
    {
        error = OT_ERROR_NONE;
    }

exit:
    return error;
}

template <> otError NcpBase::HandlePropertyGet<SPINEL_PROP_THREAD_ADDRESS_CACHE_TABLE>(void)
{
    otError         error = OT_ERROR_NONE;
    otEidCacheEntry entry;

    for (uint8_t index = 0;; index++)
    {
        SuccessOrExit(otThreadGetEidCacheEntry(mInstance, index, &entry));

        if (!entry.mValid)
        {
            continue;
        }

        SuccessOrExit(error = mEncoder.OpenStruct());
        SuccessOrExit(error = mEncoder.WriteIp6Address(entry.mTarget));
        SuccessOrExit(error = mEncoder.WriteUint16(entry.mRloc16));
        SuccessOrExit(error = mEncoder.WriteUint8(entry.mAge));
        SuccessOrExit(error = mEncoder.CloseStruct());
    }

exit:
    return error;
}

#if OPENTHREAD_CONFIG_CHILD_SUPERVISION_ENABLE

template <> otError NcpBase::HandlePropertyGet<SPINEL_PROP_CHILD_SUPERVISION_INTERVAL>(void)
{
    return mEncoder.WriteUint16(otChildSupervisionGetInterval(mInstance));
}

template <> otError NcpBase::HandlePropertySet<SPINEL_PROP_CHILD_SUPERVISION_INTERVAL>(void)
{
    otError  error = OT_ERROR_NONE;
    uint16_t interval;

    SuccessOrExit(error = mDecoder.ReadUint16(interval));
    otChildSupervisionSetInterval(mInstance, interval);

exit:
    return error;
}

#endif // OPENTHREAD_CONFIG_CHILD_SUPERVISION_ENABLE

#if OPENTHREAD_CONFIG_CHANNEL_MANAGER_ENABLE

template <> otError NcpBase::HandlePropertyGet<SPINEL_PROP_CHANNEL_MANAGER_NEW_CHANNEL>(void)
{
    return mEncoder.WriteUint8(otChannelManagerGetRequestedChannel(mInstance));
}

template <> otError NcpBase::HandlePropertySet<SPINEL_PROP_CHANNEL_MANAGER_NEW_CHANNEL>(void)
{
    uint8_t channel;
    otError error = OT_ERROR_NONE;

    SuccessOrExit(error = mDecoder.ReadUint8(channel));

    otChannelManagerRequestChannelChange(mInstance, channel);

exit:
    return error;
}

template <> otError NcpBase::HandlePropertyGet<SPINEL_PROP_CHANNEL_MANAGER_DELAY>(void)
{
    return mEncoder.WriteUint16(otChannelManagerGetDelay(mInstance));
}

template <> otError NcpBase::HandlePropertySet<SPINEL_PROP_CHANNEL_MANAGER_DELAY>(void)
{
    uint16_t delay;
    otError  error = OT_ERROR_NONE;

    SuccessOrExit(error = mDecoder.ReadUint16(delay));

    error = otChannelManagerSetDelay(mInstance, delay);

exit:
    return error;
}

template <> otError NcpBase::HandlePropertyGet<SPINEL_PROP_CHANNEL_MANAGER_SUPPORTED_CHANNELS>(void)
{
    return EncodeChannelMask(otChannelManagerGetSupportedChannels(mInstance));
}

template <> otError NcpBase::HandlePropertySet<SPINEL_PROP_CHANNEL_MANAGER_SUPPORTED_CHANNELS>(void)
{
    uint32_t channelMask = 0;
    otError  error       = OT_ERROR_NONE;

    SuccessOrExit(error = DecodeChannelMask(channelMask));
    otChannelManagerSetSupportedChannels(mInstance, channelMask);

exit:
    return error;
}

template <> otError NcpBase::HandlePropertyGet<SPINEL_PROP_CHANNEL_MANAGER_FAVORED_CHANNELS>(void)
{
    return EncodeChannelMask(otChannelManagerGetFavoredChannels(mInstance));
}

template <> otError NcpBase::HandlePropertySet<SPINEL_PROP_CHANNEL_MANAGER_FAVORED_CHANNELS>(void)
{
    uint32_t channelMask = 0;
    otError  error       = OT_ERROR_NONE;

    SuccessOrExit(error = DecodeChannelMask(channelMask));
    otChannelManagerSetFavoredChannels(mInstance, channelMask);

exit:
    return error;
}

template <> otError NcpBase::HandlePropertyGet<SPINEL_PROP_CHANNEL_MANAGER_CHANNEL_SELECT>(void)
{
    return mEncoder.WriteBool(false);
}

template <> otError NcpBase::HandlePropertySet<SPINEL_PROP_CHANNEL_MANAGER_CHANNEL_SELECT>(void)
{
    bool    skipQualityCheck = false;
    otError error            = OT_ERROR_NONE;

    SuccessOrExit(error = mDecoder.ReadBool(skipQualityCheck));
    error = otChannelManagerRequestChannelSelect(mInstance, skipQualityCheck);

exit:
    return error;
}

template <> otError NcpBase::HandlePropertyGet<SPINEL_PROP_CHANNEL_MANAGER_AUTO_SELECT_ENABLED>(void)
{
    return mEncoder.WriteBool(otChannelManagerGetAutoChannelSelectionEnabled(mInstance));
}

template <> otError NcpBase::HandlePropertySet<SPINEL_PROP_CHANNEL_MANAGER_AUTO_SELECT_ENABLED>(void)
{
    bool    enabled = false;
    otError error   = OT_ERROR_NONE;

    SuccessOrExit(error = mDecoder.ReadBool(enabled));
    otChannelManagerSetAutoChannelSelectionEnabled(mInstance, enabled);

exit:
    return error;
}

template <> otError NcpBase::HandlePropertyGet<SPINEL_PROP_CHANNEL_MANAGER_AUTO_SELECT_INTERVAL>(void)
{
    return mEncoder.WriteUint32(otChannelManagerGetAutoChannelSelectionInterval(mInstance));
}

template <> otError NcpBase::HandlePropertySet<SPINEL_PROP_CHANNEL_MANAGER_AUTO_SELECT_INTERVAL>(void)
{
    uint32_t interval;
    otError  error = OT_ERROR_NONE;

    SuccessOrExit(error = mDecoder.ReadUint32(interval));
    error = otChannelManagerSetAutoChannelSelectionInterval(mInstance, interval);

exit:
    return error;
}

#endif // OPENTHREAD_CONFIG_CHANNEL_MANAGER_ENABLE

#if OPENTHREAD_CONFIG_TIME_SYNC_ENABLE
template <> otError NcpBase::HandlePropertyGet<SPINEL_PROP_TIME_SYNC_PERIOD>(void)
{
    return mEncoder.WriteUint16(otNetworkTimeGetSyncPeriod(mInstance));
}

template <> otError NcpBase::HandlePropertySet<SPINEL_PROP_TIME_SYNC_PERIOD>(void)
{
    otError  error = OT_ERROR_NONE;
    uint16_t timeSyncPeriod;

    SuccessOrExit(error = mDecoder.ReadUint16(timeSyncPeriod));

    SuccessOrExit(error = otNetworkTimeSetSyncPeriod(mInstance, timeSyncPeriod));

exit:
    return error;
}

template <> otError NcpBase::HandlePropertyGet<SPINEL_PROP_TIME_SYNC_XTAL_THRESHOLD>(void)
{
    return mEncoder.WriteUint16(otNetworkTimeGetXtalThreshold(mInstance));
}

template <> otError NcpBase::HandlePropertySet<SPINEL_PROP_TIME_SYNC_XTAL_THRESHOLD>(void)
{
    otError  error = OT_ERROR_NONE;
    uint16_t xtalThreshold;

    SuccessOrExit(error = mDecoder.ReadUint16(xtalThreshold));

    SuccessOrExit(error = otNetworkTimeSetXtalThreshold(mInstance, xtalThreshold));

exit:
    return error;
}
#endif // OPENTHREAD_CONFIG_TIME_SYNC_ENABLE

} // namespace Ncp
} // namespace ot

#endif // OPENTHREAD_FTD
