/*
 *  Copyright (c) 2020, 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 CLI commands for Network Data.
 */

#include "cli_network_data.hpp"

#include <openthread/border_router.h>
#include <openthread/netdata_publisher.h>
#include <openthread/server.h>

#include "cli/cli.hpp"
#include "common/encoding.hpp"

namespace ot {
namespace Cli {

NetworkData::NetworkData(otInstance *aInstance, OutputImplementer &aOutputImplementer)
    : Output(aInstance, aOutputImplementer)
{
#if OPENTHREAD_CONFIG_BORDER_ROUTER_SIGNAL_NETWORK_DATA_FULL
    mFullCallbackWasCalled = false;
    otBorderRouterSetNetDataFullCallback(aInstance, HandleNetdataFull, this);
#endif
}

void NetworkData::PrefixFlagsToString(const otBorderRouterConfig &aConfig, FlagsString &aString)
{
    char *flagsPtr = &aString[0];

    if (aConfig.mPreferred)
    {
        *flagsPtr++ = 'p';
    }

    if (aConfig.mSlaac)
    {
        *flagsPtr++ = 'a';
    }

    if (aConfig.mDhcp)
    {
        *flagsPtr++ = 'd';
    }

    if (aConfig.mConfigure)
    {
        *flagsPtr++ = 'c';
    }

    if (aConfig.mDefaultRoute)
    {
        *flagsPtr++ = 'r';
    }

    if (aConfig.mOnMesh)
    {
        *flagsPtr++ = 'o';
    }

    if (aConfig.mStable)
    {
        *flagsPtr++ = 's';
    }

    if (aConfig.mNdDns)
    {
        *flagsPtr++ = 'n';
    }

    if (aConfig.mDp)
    {
        *flagsPtr++ = 'D';
    }

    *flagsPtr = '\0';
}

void NetworkData::OutputPrefix(const otBorderRouterConfig &aConfig)
{
    FlagsString flagsString;

    OutputIp6Prefix(aConfig.mPrefix);

    PrefixFlagsToString(aConfig, flagsString);

    if (flagsString[0] != '\0')
    {
        OutputFormat(" %s", flagsString);
    }

    OutputLine(" %s %04x", Interpreter::PreferenceToString(aConfig.mPreference), aConfig.mRloc16);
}

void NetworkData::RouteFlagsToString(const otExternalRouteConfig &aConfig, FlagsString &aString)
{
    char *flagsPtr = &aString[0];

    if (aConfig.mStable)
    {
        *flagsPtr++ = 's';
    }

    if (aConfig.mNat64)
    {
        *flagsPtr++ = 'n';
    }

    if (aConfig.mAdvPio)
    {
        *flagsPtr++ = 'a';
    }

    *flagsPtr = '\0';
}

void NetworkData::OutputRoute(const otExternalRouteConfig &aConfig)
{
    FlagsString flagsString;

    OutputIp6Prefix(aConfig.mPrefix);

    RouteFlagsToString(aConfig, flagsString);

    if (flagsString[0] != '\0')
    {
        OutputFormat(" %s", flagsString);
    }

    OutputLine(" %s %04x", Interpreter::PreferenceToString(aConfig.mPreference), aConfig.mRloc16);
}

void NetworkData::OutputService(const otServiceConfig &aConfig)
{
    OutputFormat("%lu ", ToUlong(aConfig.mEnterpriseNumber));
    OutputBytes(aConfig.mServiceData, aConfig.mServiceDataLength);
    OutputFormat(" ");
    OutputBytes(aConfig.mServerConfig.mServerData, aConfig.mServerConfig.mServerDataLength);

    if (aConfig.mServerConfig.mStable)
    {
        OutputFormat(" s");
    }

    OutputLine(" %04x", aConfig.mServerConfig.mRloc16);
}

/**
 * @cli netdata length
 * @code
 * netdata length
 * 23
 * Done
 * @endcode
 * @par api_copy
 * #otNetDataGetLength
 */
template <> otError NetworkData::Process<Cmd("length")>(Arg aArgs[])
{
    otError error = OT_ERROR_NONE;

    VerifyOrExit(aArgs[0].IsEmpty(), error = OT_ERROR_INVALID_ARGS);
    OutputLine("%u", otNetDataGetLength(GetInstancePtr()));

exit:
    return error;
}

template <> otError NetworkData::Process<Cmd("maxlength")>(Arg aArgs[])
{
    otError error = OT_ERROR_NONE;

    /**
     * @cli netdata maxlength
     * @code
     * netdata maxlength
     * 40
     * Done
     * @endcode
     * @par api_copy
     * #otNetDataGetMaxLength
     */
    if (aArgs[0].IsEmpty())
    {
        OutputLine("%u", otNetDataGetMaxLength(GetInstancePtr()));
    }
    /**
     * @cli netdata maxlength reset
     * @code
     * netdata maxlength reset
     * Done
     * @endcode
     * @par api_copy
     * #otNetDataResetMaxLength
     */
    else if (aArgs[0] == "reset")
    {
        otNetDataResetMaxLength(GetInstancePtr());
    }
    else
    {
        error = OT_ERROR_INVALID_ARGS;
    }

    return error;
}

#if OPENTHREAD_CONFIG_NETDATA_PUBLISHER_ENABLE
template <> otError NetworkData::Process<Cmd("publish")>(Arg aArgs[])
{
    otError error = OT_ERROR_NONE;

#if OPENTHREAD_CONFIG_TMF_NETDATA_SERVICE_ENABLE
    if (aArgs[0] == "dnssrp")
    {
        /**
         * @cli netdata publish dnssrp anycast
         * @code
         * netdata publish dnssrp anycast 1
         * Done
         * @endcode
         * @cparam netdata publish dnssrp anycast @ca{seq-num}
         * @par
         * Publishes a DNS/SRP Service Anycast Address with a sequence number. Any current
         * DNS/SRP Service entry being published from a previous `publish dnssrp{anycast|unicast}`
         * command is removed and replaced with the new arguments.
         * @par
         * `OPENTHREAD_CONFIG_TMF_NETDATA_SERVICE_ENABLE` must be enabled.
         * @csa{netdata publish dnssrp unicast (addr,port)}
         * @csa{netdata publish dnssrp unicast (mle)}
         * @sa otNetDataPublishDnsSrpServiceAnycast
         * @endcli
         */
        if (aArgs[1] == "anycast")
        {
            uint8_t sequenceNumber;

            SuccessOrExit(error = aArgs[2].ParseAsUint8(sequenceNumber));
            otNetDataPublishDnsSrpServiceAnycast(GetInstancePtr(), sequenceNumber);
            ExitNow();
        }

        if (aArgs[1] == "unicast")
        {
            otIp6Address address;
            uint16_t     port;

            /**
             * @cli netdata publish dnssrp unicast (mle)
             * @code
             * netdata publish dnssrp unicast 50152
             * Done
             * @endcode
             * @cparam netdata publish dnssrp unicast @ca{port}
             * @par
             * Publishes the device's Mesh-Local EID with a port number. MLE and port information is
             * included in the Server TLV data. To use a different Unicast address, use the
             * `netdata publish dnssrp unicast (addr,port)` command.
             * @par
             * Any current DNS/SRP Service entry being published from a previous
             * `publish dnssrp{anycast|unicast}` command is removed and replaced with the new arguments.
             * @par
             * `OPENTHREAD_CONFIG_TMF_NETDATA_SERVICE_ENABLE` must be enabled.
             * @csa{netdata publish dnssrp unicast (addr,port)}
             * @csa{netdata publish dnssrp anycast}
             * @sa otNetDataPublishDnsSrpServiceUnicastMeshLocalEid
             */
            if (aArgs[3].IsEmpty())
            {
                SuccessOrExit(error = aArgs[2].ParseAsUint16(port));
                otNetDataPublishDnsSrpServiceUnicastMeshLocalEid(GetInstancePtr(), port);
                ExitNow();
            }

            /**
             * @cli netdata publish dnssrp unicast (addr,port)
             * @code
             * netdata publish dnssrp unicast fd00::1234 51525
             * Done
             * @endcode
             * @cparam netdata publish dnssrp unicast @ca{address} @ca{port}
             * @par
             * Publishes a DNS/SRP Service Unicast Address with an address and port number. The address
             * and port information is included in Service TLV data. Any current DNS/SRP Service entry being
             * published from a previous `publish dnssrp{anycast|unicast}` command is removed and replaced
             * with the new arguments.
             * @par
             * `OPENTHREAD_CONFIG_TMF_NETDATA_SERVICE_ENABLE` must be enabled.
             * @csa{netdata publish dnssrp unicast (mle)}
             * @csa{netdata publish dnssrp anycast}
             * @sa otNetDataPublishDnsSrpServiceUnicast
             */
            SuccessOrExit(error = aArgs[2].ParseAsIp6Address(address));
            SuccessOrExit(error = aArgs[3].ParseAsUint16(port));
            otNetDataPublishDnsSrpServiceUnicast(GetInstancePtr(), &address, port);
            ExitNow();
        }
    }
#endif // OPENTHREAD_CONFIG_TMF_NETDATA_SERVICE_ENABLE

#if OPENTHREAD_CONFIG_BORDER_ROUTER_ENABLE
    /**
     * @cli netdata publish prefix
     * @code
     * netdata publish prefix fd00:1234:5678::/64 paos med
     * Done
     * @endcode
     * @cparam netdata publish prefix @ca{prefix} [@ca{padcrosnD}] [@ca{high}|@ca{med}|@ca{low}]
     * OT CLI uses mapped arguments to configure #otBorderRouterConfig values. @moreinfo{the @overview}.
     * @par
     * Publish an on-mesh prefix entry. @moreinfo{@netdata}.
     * @sa otNetDataPublishOnMeshPrefix
     */
    if (aArgs[0] == "prefix")
    {
        otBorderRouterConfig config;

        SuccessOrExit(error = Interpreter::ParsePrefix(aArgs + 1, config));
        error = otNetDataPublishOnMeshPrefix(GetInstancePtr(), &config);
        ExitNow();
    }

    /**
     * @cli netdata publish route
     * @code
     * netdata publish route fd00:1234:5678::/64 s high
     * Done
     * @endcode
     * @cparam publish route @ca{prefix} [@ca{sn}] [@ca{high}|@ca{med}|@ca{low}]
     * OT CLI uses mapped arguments to configure #otExternalRouteConfig values. @moreinfo{the @overview}.
     * @par
     * Publish an external route entry. @moreinfo{@netdata}.
     * @sa otNetDataPublishExternalRoute
     */
    if (aArgs[0] == "route")
    {
        otExternalRouteConfig config;

        SuccessOrExit(error = Interpreter::ParseRoute(aArgs + 1, config));
        error = otNetDataPublishExternalRoute(GetInstancePtr(), &config);
        ExitNow();
    }

    /**
     * @cli netdata publish replace
     * @code
     * netdata publish replace ::/0 fd00:1234:5678::/64 s high
     * Done
     * @endcode
     * @cparam netdata publish replace @ca{oldprefix} @ca{prefix} [@ca{sn}] [@ca{high}|@ca{med}|@ca{low}]
     * OT CLI uses mapped arguments to configure #otExternalRouteConfig values. @moreinfo{the @overview}.
     * @par
     * Replaces a previously published external route entry. @moreinfo{@netdata}.
     * @sa otNetDataReplacePublishedExternalRoute
     */
    if (aArgs[0] == "replace")
    {
        otIp6Prefix           prefix;
        otExternalRouteConfig config;

        SuccessOrExit(error = aArgs[1].ParseAsIp6Prefix(prefix));
        SuccessOrExit(error = Interpreter::ParseRoute(aArgs + 2, config));
        error = otNetDataReplacePublishedExternalRoute(GetInstancePtr(), &prefix, &config);
        ExitNow();
    }
#endif // OPENTHREAD_CONFIG_BORDER_ROUTER_ENABLE

    error = OT_ERROR_INVALID_ARGS;

exit:
    return error;
}

template <> otError NetworkData::Process<Cmd("unpublish")>(Arg aArgs[])
{
    otError error = OT_ERROR_NONE;

/**
 * @cli netdata unpublish dnssrp
 * @code
 * netdata unpublish dnssrp
 * Done
 * @endcode
 * @par api_copy
 * #otNetDataUnpublishDnsSrpService
 */
#if OPENTHREAD_CONFIG_TMF_NETDATA_SERVICE_ENABLE
    if (aArgs[0] == "dnssrp")
    {
        otNetDataUnpublishDnsSrpService(GetInstancePtr());
        ExitNow();
    }
#endif

/**
 * @cli netdata unpublish (prefix)
 * @code
 * netdata unpublish fd00:1234:5678::/64
 * Done
 * @endcode
 * @cparam netdata unpublish @ca{prefix}
 * @par api_copy
 * #otNetDataUnpublishPrefix
 * @par
 * @moreinfo{@netdata}.
 */
#if OPENTHREAD_CONFIG_BORDER_ROUTER_ENABLE
    {
        otIp6Prefix prefix;

        if (aArgs[0].ParseAsIp6Prefix(prefix) == OT_ERROR_NONE)
        {
            error = otNetDataUnpublishPrefix(GetInstancePtr(), &prefix);
            ExitNow();
        }
    }
#endif

    error = OT_ERROR_INVALID_ARGS;

exit:
    return error;
}
#endif // OPENTHREAD_CONFIG_NETDATA_PUBLISHER_ENABLE

#if OPENTHREAD_CONFIG_BORDER_ROUTER_ENABLE || OPENTHREAD_CONFIG_TMF_NETDATA_SERVICE_ENABLE
/**
 * @cli netdata register
 * @code
 * netdata register
 * Done
 * @endcode
 * @par
 * Register configured prefixes, routes, and services with the Leader.
 * @par
 * OT CLI checks for `OPENTHREAD_CONFIG_BORDER_ROUTER_ENABLE`. If OTBR is enabled, it
 * registers local Network Data with the Leader. Otherwise, it calls the CLI function `otServerRegister`.
 * @moreinfo{@netdata}.
 * @csa{prefix add}
 * @sa otBorderRouterRegister
 * @sa otServerAddService
 */
template <> otError NetworkData::Process<Cmd("register")>(Arg aArgs[])
{
    OT_UNUSED_VARIABLE(aArgs);

    otError error = OT_ERROR_NONE;

#if OPENTHREAD_CONFIG_BORDER_ROUTER_ENABLE
    SuccessOrExit(error = otBorderRouterRegister(GetInstancePtr()));
#else
    SuccessOrExit(error = otServerRegister(GetInstancePtr()));
#endif

exit:
    return error;
}
#endif

template <> otError NetworkData::Process<Cmd("steeringdata")>(Arg aArgs[])
{
    otError           error;
    otExtAddress      addr;
    otJoinerDiscerner discerner;

    VerifyOrExit(aArgs[0] == "check", error = OT_ERROR_INVALID_ARGS);

    error = Interpreter::ParseJoinerDiscerner(aArgs[1], discerner);

    if (error == OT_ERROR_NOT_FOUND)
    {
        discerner.mLength = 0;
        error             = aArgs[1].ParseAsHexString(addr.m8);
    }

    SuccessOrExit(error);

    /**
     * @cli netdata steeringdata check (discerner)
     * @code
     * netdata steeringdata check 0xabc/12
     * Done
     * @endcode
     * @code
     * netdata steeringdata check 0xdef/12
     * Error 23: NotFound
     * @endcode
     * @cparam netdata steeringdata check @ca{discerner}
     * *   `discerner`: The %Joiner discerner in format `{number}/{length}`.
     * @par api_copy
     * #otNetDataSteeringDataCheckJoinerWithDiscerner
     * @csa{joiner discerner}
     */
    if (discerner.mLength)
    {
        error = otNetDataSteeringDataCheckJoinerWithDiscerner(GetInstancePtr(), &discerner);
    }
    /**
     * @cli netdata steeringdata check (eui64)
     * @code
     * netdata steeringdata check d45e64fa83f81cf7
     * Done
     * @endcode
     * @cparam netdata steeringdata check @ca{eui64}
     * *   `eui64`: The IEEE EUI-64 of the %Joiner.
     * @par api_copy
     * #otNetDataSteeringDataCheckJoiner
     * @csa{eui64}
     */
    else
    {
        error = otNetDataSteeringDataCheckJoiner(GetInstancePtr(), &addr);
    }

exit:
    return error;
}

otError NetworkData::GetNextPrefix(otNetworkDataIterator *aIterator, otBorderRouterConfig *aConfig, bool aLocal)
{
    otError error;

    if (aLocal)
    {
#if OPENTHREAD_CONFIG_BORDER_ROUTER_ENABLE
        error = otBorderRouterGetNextOnMeshPrefix(GetInstancePtr(), aIterator, aConfig);
#else
        error = OT_ERROR_NOT_FOUND;
#endif
    }
    else
    {
        error = otNetDataGetNextOnMeshPrefix(GetInstancePtr(), aIterator, aConfig);
    }

    return error;
}

void NetworkData::OutputPrefixes(bool aLocal)
{
    otNetworkDataIterator iterator = OT_NETWORK_DATA_ITERATOR_INIT;
    otBorderRouterConfig  config;

    OutputLine("Prefixes:");

    while (GetNextPrefix(&iterator, &config, aLocal) == OT_ERROR_NONE)
    {
        OutputPrefix(config);
    }
}

otError NetworkData::GetNextRoute(otNetworkDataIterator *aIterator, otExternalRouteConfig *aConfig, bool aLocal)
{
    otError error;

    if (aLocal)
    {
#if OPENTHREAD_CONFIG_BORDER_ROUTER_ENABLE
        error = otBorderRouterGetNextRoute(GetInstancePtr(), aIterator, aConfig);
#else
        error = OT_ERROR_NOT_FOUND;
#endif
    }
    else
    {
        error = otNetDataGetNextRoute(GetInstancePtr(), aIterator, aConfig);
    }

    return error;
}

void NetworkData::OutputRoutes(bool aLocal)
{
    otNetworkDataIterator iterator = OT_NETWORK_DATA_ITERATOR_INIT;
    otExternalRouteConfig config;

    OutputLine("Routes:");

    while (GetNextRoute(&iterator, &config, aLocal) == OT_ERROR_NONE)
    {
        OutputRoute(config);
    }
}

otError NetworkData::GetNextService(otNetworkDataIterator *aIterator, otServiceConfig *aConfig, bool aLocal)
{
    otError error;

    if (aLocal)
    {
#if OPENTHREAD_CONFIG_TMF_NETDATA_SERVICE_ENABLE
        error = otServerGetNextService(GetInstancePtr(), aIterator, aConfig);
#else
        error = OT_ERROR_NOT_FOUND;
#endif
    }
    else
    {
        error = otNetDataGetNextService(GetInstancePtr(), aIterator, aConfig);
    }

    return error;
}

void NetworkData::OutputServices(bool aLocal)
{
    otNetworkDataIterator iterator = OT_NETWORK_DATA_ITERATOR_INIT;
    otServiceConfig       config;

    OutputLine("Services:");

    while (GetNextService(&iterator, &config, aLocal) == OT_ERROR_NONE)
    {
        OutputService(config);
    }
}

void NetworkData::OutputLowpanContexts(bool aLocal)
{
    otNetworkDataIterator iterator = OT_NETWORK_DATA_ITERATOR_INIT;
    otLowpanContextInfo   info;

    VerifyOrExit(!aLocal);

    OutputLine("Contexts:");

    while (otNetDataGetNextLowpanContextInfo(GetInstancePtr(), &iterator, &info) == OT_ERROR_NONE)
    {
        OutputIp6Prefix(info.mPrefix);
        OutputLine(" %u %c", info.mContextId, info.mCompressFlag ? 'c' : '-');
    }

exit:
    return;
}

otError NetworkData::OutputBinary(bool aLocal)
{
    otError error;
    uint8_t data[255];
    uint8_t len = sizeof(data);

    if (aLocal)
    {
#if OPENTHREAD_CONFIG_BORDER_ROUTER_ENABLE
        error = otBorderRouterGetNetData(GetInstancePtr(), false, data, &len);
#else
        error = OT_ERROR_NOT_IMPLEMENTED;
#endif
    }
    else
    {
        error = otNetDataGet(GetInstancePtr(), false, data, &len);
    }
    SuccessOrExit(error);

    OutputBytesLine(data, static_cast<uint8_t>(len));

exit:
    return error;
}

/**
 * @cli netdata show
 * @code
 * netdata show
 * Prefixes:
 * fd00:dead:beef:cafe::/64 paros med dc00
 * Routes:
 * fd49:7770:7fc5:0::/64 s med 4000
 * Services:
 * 44970 5d c000 s 4000
 * 44970 01 9a04b000000e10 s 4000
 * Contexts:
 * fd00:dead:beef:cafe::/64 1 c
 * Done
 * @endcode
 * @code
 * netdata show -x
 * 08040b02174703140040fd00deadbeefcafe0504dc00330007021140
 * Done
 * @endcode
 * @cparam netdata show [@ca{-x}]
 * *   The optional `-x` argument gets Network Data as hex-encoded TLVs.
 * @par
 * `netdata show` from OT CLI gets full Network Data received from the Leader. This command uses several
 * API functions to combine prefixes, routes, and services, including #otNetDataGetNextOnMeshPrefix,
 * #otNetDataGetNextRoute, #otNetDataGetNextService and #otNetDataGetNextLowpanContextInfo.
 * @par
 * On-mesh prefixes are listed under `Prefixes` header:
 * * The on-mesh prefix
 * * Flags
 *   * p: Preferred flag
 *   * a: Stateless IPv6 Address Autoconfiguration flag
 *   * d: DHCPv6 IPv6 Address Configuration flag
 *   * c: DHCPv6 Other Configuration flag
 *   * r: Default Route flag
 *   * o: On Mesh flag
 *   * s: Stable flag
 *   * n: Nd Dns flag
 *   * D: Domain Prefix flag (only available for Thread 1.2).
 * * Preference `high`, `med`, or `low`
 * * RLOC16 of device which added the on-mesh prefix
 * @par
 * External Routes are listed under `Routes` header:
 * * The route prefix
 * * Flags
 *   * s: Stable flag
 *   * n: NAT64 flag
 * * Preference `high`, `med`, or `low`
 * * RLOC16 of device which added the route prefix
 * @par
 * Service entries are listed under `Services` header:
 * * Enterprise number
 * * Service data (as hex bytes)
 * * Server data (as hex bytes)
 * * Flags
 *   * s: Stable flag
 * * RLOC16 of devices which added the service entry
 * @par
 * 6LoWPAN Context IDs are listed under `Contexts` header:
 * * The prefix
 * * Context ID
 * * Compress flag (`c` if marked or `-` otherwise).
 * @par
 * @moreinfo{@netdata}.
 * @csa{br omrprefix}
 * @csa{br onlinkprefix}
 * @sa otBorderRouterGetNetData
 */
template <> otError NetworkData::Process<Cmd("show")>(Arg aArgs[])
{
    otError error  = OT_ERROR_INVALID_ARGS;
    bool    local  = false;
    bool    binary = false;

    for (uint8_t i = 0; !aArgs[i].IsEmpty(); i++)
    {
        /**
         * @cli netdata show local
         * @code
         * netdata show local
         * Prefixes:
         * fd00:dead:beef:cafe::/64 paros med dc00
         * Routes:
         * Services:
         * Done
         * @endcode
         * @code
         * netdata show local -x
         * 08040b02174703140040fd00deadbeefcafe0504dc00330007021140
         * Done
         * @endcode
         * @cparam netdata show local [@ca{-x}]
         * *   The optional `-x` argument gets local Network Data as hex-encoded TLVs.
         * @par
         * Print local Network Data to sync with the Leader.
         * @csa{netdata show}
         */
        if (aArgs[i] == "local")
        {
            local = true;
        }
        else if (aArgs[i] == "-x")
        {
            binary = true;
        }
        else
        {
            ExitNow(error = OT_ERROR_INVALID_ARGS);
        }
    }

    if (binary)
    {
        error = OutputBinary(local);
    }
    else
    {
        OutputPrefixes(local);
        OutputRoutes(local);
        OutputServices(local);
        OutputLowpanContexts(local);
        error = OT_ERROR_NONE;
    }

exit:
    return error;
}

#if OPENTHREAD_CONFIG_BORDER_ROUTER_SIGNAL_NETWORK_DATA_FULL
template <> otError NetworkData::Process<Cmd("full")>(Arg aArgs[])
{
    otError error = OT_ERROR_NONE;

    /**
     * @cli netdata full
     * @code
     * netdata full
     * no
     * Done
     * @endcode
     * @par
     * Print "yes" or "no" indicating whether or not the "net data full" callback has been invoked since start of
     * Thread operation or since the last time `netdata full reset` was used to reset the flag.
     * This command requires `OPENTHREAD_CONFIG_BORDER_ROUTER_SIGNAL_NETWORK_DATA_FULL`.
     * The "net data full" callback is invoked whenever:
     * - The device is acting as a leader and receives a Network Data registration from a Border Router (BR) that it
     *   cannot add to Network Data (running out of space).
     * - The device is acting as a BR and new entries cannot be added to its local Network Data.
     * - The device is acting as a BR and tries to register its local Network Data entries with the leader, but
     *   determines that its local entries will not fit.
     * @sa otBorderRouterSetNetDataFullCallback
     */
    if (aArgs[0].IsEmpty())
    {
        OutputLine(mFullCallbackWasCalled ? "yes" : "no");
    }
    /**
     * @cli netdata full reset
     * @code
     * netdata full reset
     * Done
     * @endcode
     * @par
     * Reset the flag tracking whether "net data full" callback was invoked.
     */
    else if (aArgs[0] == "reset")
    {
        VerifyOrExit(aArgs[1].IsEmpty(), error = OT_ERROR_INVALID_ARGS);
        mFullCallbackWasCalled = false;
    }
    else
    {
        error = OT_ERROR_INVALID_ARGS;
    }

exit:
    return error;
}
#endif // OPENTHREAD_CONFIG_BORDER_ROUTER_SIGNAL_NETWORK_DATA_FULL

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

    static constexpr Command kCommands[] = {
#if OPENTHREAD_CONFIG_BORDER_ROUTER_SIGNAL_NETWORK_DATA_FULL
        CmdEntry("full"),
#endif
        CmdEntry("length"),
        CmdEntry("maxlength"),
#if OPENTHREAD_CONFIG_NETDATA_PUBLISHER_ENABLE
        CmdEntry("publish"),
#endif
#if OPENTHREAD_CONFIG_BORDER_ROUTER_ENABLE || OPENTHREAD_CONFIG_TMF_NETDATA_SERVICE_ENABLE
        CmdEntry("register"),
#endif
        CmdEntry("show"),
        CmdEntry("steeringdata"),
#if OPENTHREAD_CONFIG_NETDATA_PUBLISHER_ENABLE
        CmdEntry("unpublish"),
#endif
    };

#undef CmdEntry

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

    otError        error = OT_ERROR_INVALID_COMMAND;
    const Command *command;

    /**
     * @cli netdata help
     * @code
     * netdata help
     * length
     * maxlength
     * publish
     * register
     * show
     * steeringdata
     * unpublish
     * Done
     * @endcode
     * @par
     * Gets a list of `netdata` CLI commands.
     * @sa @netdata
     */
    if (aArgs[0].IsEmpty() || (aArgs[0] == "help"))
    {
        OutputCommandTable(kCommands);
        ExitNow(error = aArgs[0].IsEmpty() ? error : OT_ERROR_NONE);
    }

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

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

exit:
    return error;
}

} // namespace Cli
} // namespace ot
