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

/**
 * @file
 *   This file implements CLI for the History Tracker.
 */

#include "cli_history.hpp"

#if OPENTHREAD_CONFIG_HISTORY_TRACKER_ENABLE

#include <string.h>

#include "cli/cli.hpp"

namespace ot {
namespace Cli {

static const char *const kSimpleEventStrings[] = {
    "Added",  // (0) OT_HISTORY_TRACKER_{NET_DATA_ENTRY/ADDRESS_EVENT}_ADDED
    "Removed" // (1) OT_HISTORY_TRACKER_{NET_DATA_ENTRY/ADDRESS_EVENT}_REMOVED
};

otError History::ParseArgs(Arg aArgs[], bool &aIsList, uint16_t &aNumEntries) const
{
    if (*aArgs == "list")
    {
        aArgs++;
        aIsList = true;
    }
    else
    {
        aIsList = false;
    }

    if (aArgs->ParseAsUint16(aNumEntries) == OT_ERROR_NONE)
    {
        aArgs++;
    }
    else
    {
        aNumEntries = 0;
    }

    return aArgs[0].IsEmpty() ? OT_ERROR_NONE : OT_ERROR_INVALID_ARGS;
}

/**
 * @cli history ipaddr
 * @code
 * history ipaddr
 * | Age                  | Event   | Address / Prefix Length                     | Origin |Scope| P | V | R |
 * +----------------------+---------+---------------------------------------------+--------+-----+---+---+---+
 * |         00:00:04.991 | Removed | 2001:dead:beef:cafe:c4cb:caba:8d55:e30b/64  | slaac  |  14 | Y | Y | N |
 * |         00:00:44.647 | Added   | 2001:dead:beef:cafe:c4cb:caba:8d55:e30b/64  | slaac  |  14 | Y | Y | N |
 * |         00:01:07.199 | Added   | fd00:0:0:0:0:0:0:1/64                       | manual |  14 | Y | Y | N |
 * |         00:02:17.885 | Added   | fdde:ad00:beef:0:0:ff:fe00:fc00/64          | thread |   3 | N | Y | N |
 * |         00:02:17.885 | Added   | fdde:ad00:beef:0:0:ff:fe00:5400/64          | thread |   3 | N | Y | Y |
 * |         00:02:20.107 | Removed | fdde:ad00:beef:0:0:ff:fe00:5400/64          | thread |   3 | N | Y | Y |
 * |         00:02:21.575 | Added   | fdde:ad00:beef:0:0:ff:fe00:5400/64          | thread |   3 | N | Y | Y |
 * |         00:02:21.575 | Added   | fdde:ad00:beef:0:ecea:c4fc:ad96:4655/64     | thread |   3 | N | Y | N |
 * |         00:02:23.904 | Added   | fe80:0:0:0:3c12:a4d2:fbe0:31ad/64           | thread |   2 | Y | Y | N |
 * Done
 * @endcode
 * @code
 * history ipaddr list 5
 * 00:00:20.327 -> event:Removed address:2001:dead:beef:cafe:c4cb:caba:8d55:e30b <!--
 * -->prefixlen:64 origin:slaac scope:14 preferred:yes valid:yes rloc:no
 * 00:00:59.983 -> event:Added address:2001:dead:beef:cafe:c4cb:caba:8d55:e30b <!--
 * -->prefixlen:64 origin:slaac scope:14 preferred:yes valid:yes rloc:no
 * 00:01:22.535 -> event:Added address:fd00:0:0:0:0:0:0:1 prefixlen:64 <!--
 * -->origin:manual scope:14 preferred:yes valid:yes rloc:no
 * 00:02:33.221 -> event:Added address:fdde:ad00:beef:0:0:ff:fe00:fc00 <!--
 * -->prefixlen:64 origin:thread scope:3 preferred:no valid:yes rloc:no
 * 00:02:33.221 -> event:Added address:fdde:ad00:beef:0:0:ff:fe00:5400 <!--
 * -->prefixlen:64 origin:thread scope:3 preferred:no valid:yes rloc:yes
 * Done
 * @endcode
 * @cparam history ipaddr [@ca{list}] [@ca{num-entries}]
 * * Use the `list` option to display the output in list format. Otherwise,
 *   the output is shown in table format.
 * * Use the `num-entries` option to limit the output to the number of
 *   most-recent entries specified. If this option is not used, all stored
 *   entries are shown in the output.
 * @par
 * Displays the unicast IPv6 address history in table or list format.
 * @par
 * Each table or list entry provides:
 * * Age: Time elapsed since the command was issued, and given in the format:
 *        `hours`:`minutes`:`seconds`:`milliseconds`
 * * Event: Possible values are `Added` or `Removed`.
 * * Address/Prefix Length: Unicast address with its prefix length (in bits).
 * * Origin: Possible value are `thread`, `slaac`, `dhcp6`, or `manual`.
 * * Scope: IPv6 address scope.
 * * P: Preferred flag.
 * * V: Valid flag.
 * * RLOC (R): This flag indicates if the IPv6 address is a routing locator.
 * @note
 * All commands under `history` require the `OPENTHREAD_CONFIG_HISTORY_TRACKER_ENABLE`
 * feature to be enabled.
 * @sa otHistoryTrackerEntryAgeToString
 * @sa otHistoryTrackerIterateUnicastAddressHistory
 */
template <> otError History::Process<Cmd("ipaddr")>(Arg aArgs[])
{
    otError                                   error;
    bool                                      isList;
    uint16_t                                  numEntries;
    otHistoryTrackerIterator                  iterator;
    const otHistoryTrackerUnicastAddressInfo *info;
    uint32_t                                  entryAge;
    char                                      ageString[OT_HISTORY_TRACKER_ENTRY_AGE_STRING_SIZE];
    char                                      addressString[OT_IP6_ADDRESS_STRING_SIZE + 4];

    static_assert(0 == OT_HISTORY_TRACKER_ADDRESS_EVENT_ADDED, "ADDRESS_EVENT_ADDED is incorrect");
    static_assert(1 == OT_HISTORY_TRACKER_ADDRESS_EVENT_REMOVED, "ADDRESS_EVENT_REMOVED is incorrect");

    SuccessOrExit(error = ParseArgs(aArgs, isList, numEntries));

    if (!isList)
    {
        // | Age                  | Event   | Address / PrefixLen                  /123   | Origin |Scope| P | V | R |
        // +----------------------+---------+---------------------------------------------+--------+-----+---+---+---+

        static const char *const kUnicastAddrInfoTitles[] = {
            "Age", "Event", "Address / PrefixLength", "Origin", "Scope", "P", "V", "R"};

        static const uint8_t kUnicastAddrInfoColumnWidths[] = {22, 9, 45, 8, 5, 3, 3, 3};

        OutputTableHeader(kUnicastAddrInfoTitles, kUnicastAddrInfoColumnWidths);
    }

    otHistoryTrackerInitIterator(&iterator);

    for (uint16_t index = 0; (numEntries == 0) || (index < numEntries); index++)
    {
        info = otHistoryTrackerIterateUnicastAddressHistory(GetInstancePtr(), &iterator, &entryAge);
        VerifyOrExit(info != nullptr);

        otHistoryTrackerEntryAgeToString(entryAge, ageString, sizeof(ageString));
        otIp6AddressToString(&info->mAddress, addressString, sizeof(addressString));

        if (!isList)
        {
            size_t len = strlen(addressString);

            snprintf(&addressString[len], sizeof(addressString) - len, "/%d", info->mPrefixLength);

            OutputLine("| %20s | %-7s | %-43s | %-6s | %3d | %c | %c | %c |", ageString,
                       Stringify(info->mEvent, kSimpleEventStrings), addressString,
                       Interpreter::AddressOriginToString(info->mAddressOrigin), info->mScope,
                       info->mPreferred ? 'Y' : 'N', info->mValid ? 'Y' : 'N', info->mRloc ? 'Y' : 'N');
        }
        else
        {
            OutputLine("%s -> event:%s address:%s prefixlen:%d origin:%s scope:%d preferred:%s valid:%s rloc:%s",
                       ageString, Stringify(info->mEvent, kSimpleEventStrings), addressString, info->mPrefixLength,
                       Interpreter::AddressOriginToString(info->mAddressOrigin), info->mScope,
                       info->mPreferred ? "yes" : "no", info->mValid ? "yes" : "no", info->mRloc ? "yes" : "no");
        }
    }

exit:
    return error;
}

/**
 * @cli history ipmaddr
 * @code
 * history ipmaddr
 * | Age                  | Event        | Multicast Address                       | Origin |
 * +----------------------+--------------+-----------------------------------------+--------+
 * |         00:00:08.592 | Unsubscribed | ff05:0:0:0:0:0:0:1                      | Manual |
 * |         00:01:25.353 | Subscribed   | ff05:0:0:0:0:0:0:1                      | Manual |
 * |         00:01:54.953 | Subscribed   | ff03:0:0:0:0:0:0:2                      | Thread |
 * |         00:01:54.953 | Subscribed   | ff02:0:0:0:0:0:0:2                      | Thread |
 * |         00:01:59.329 | Subscribed   | ff33:40:fdde:ad00:beef:0:0:1            | Thread |
 * |         00:01:59.329 | Subscribed   | ff32:40:fdde:ad00:beef:0:0:1            | Thread |
 * |         00:02:01.129 | Subscribed   | ff03:0:0:0:0:0:0:fc                     | Thread |
 * |         00:02:01.129 | Subscribed   | ff03:0:0:0:0:0:0:1                      | Thread |
 * |         00:02:01.129 | Subscribed   | ff02:0:0:0:0:0:0:1                      | Thread |
 * Done
 * @endcode
 * @code
 * history ipmaddr list
 * 00:00:25.447 -> event:Unsubscribed address:ff05:0:0:0:0:0:0:1 origin:Manual
 * 00:01:42.208 -> event:Subscribed address:ff05:0:0:0:0:0:0:1 origin:Manual
 * 00:02:11.808 -> event:Subscribed address:ff03:0:0:0:0:0:0:2 origin:Thread
 * 00:02:11.808 -> event:Subscribed address:ff02:0:0:0:0:0:0:2 origin:Thread
 * 00:02:16.184 -> event:Subscribed address:ff33:40:fdde:ad00:beef:0:0:1 origin:Thread
 * 00:02:16.184 -> event:Subscribed address:ff32:40:fdde:ad00:beef:0:0:1 origin:Thread
 * 00:02:17.984 -> event:Subscribed address:ff03:0:0:0:0:0:0:fc origin:Thread
 * 00:02:17.984 -> event:Subscribed address:ff03:0:0:0:0:0:0:1 origin:Thread
 * 00:02:17.984 -> event:Subscribed address:ff02:0:0:0:0:0:0:1 origin:Thread
 * Done
 * @endcode
 * @cparam history ipmaddr [@ca{list}] [@ca{num-entries}]
 * * Use the `list` option to display the output in list format. Otherwise,
 *   the output is shown in table format.
 * * Use the `num-entries` option to limit the output to the number of
 *   most-recent entries specified. If this option is not used, all stored
 *   entries are shown in the output.
 * @par
 * Displays the multicast IPv6 address history in table or list format.
 * @par
 * Each table or list entry provides:
 * * Age: Time elapsed since the command was issued, and given in the format:
 *        `hours`:`minutes`:`seconds`:`milliseconds`
 * * Event: Possible values are `Subscribed` or `Unsubscribed`.
 * * Multicast Address
 * * Origin: Possible values are `Thread` or `Manual`.
 * @sa otHistoryTrackerEntryAgeToString
 * @sa otHistoryTrackerIterateMulticastAddressHistory
 */
template <> otError History::Process<Cmd("ipmaddr")>(Arg aArgs[])
{
    static const char *const kEventStrings[] = {
        "Subscribed",  // (0) OT_HISTORY_TRACKER_ADDRESS_EVENT_ADDED
        "Unsubscribed" // (1) OT_HISTORY_TRACKER_ADDRESS_EVENT_REMOVED
    };

    otError                                     error;
    bool                                        isList;
    uint16_t                                    numEntries;
    otHistoryTrackerIterator                    iterator;
    const otHistoryTrackerMulticastAddressInfo *info;
    uint32_t                                    entryAge;
    char                                        ageString[OT_HISTORY_TRACKER_ENTRY_AGE_STRING_SIZE];
    char                                        addressString[OT_IP6_ADDRESS_STRING_SIZE];

    static_assert(0 == OT_HISTORY_TRACKER_ADDRESS_EVENT_ADDED, "ADDRESS_EVENT_ADDED is incorrect");
    static_assert(1 == OT_HISTORY_TRACKER_ADDRESS_EVENT_REMOVED, "ADDRESS_EVENT_REMOVED is incorrect");

    SuccessOrExit(error = ParseArgs(aArgs, isList, numEntries));

    if (!isList)
    {
        // | Age                  | Event        | Multicast Address                       | Origin |
        // +----------------------+--------------+-----------------------------------------+--------+

        static const char *const kMulticastAddrInfoTitles[] = {
            "Age",
            "Event",
            "Multicast Address",
            "Origin",
        };

        static const uint8_t kMulticastAddrInfoColumnWidths[] = {22, 14, 42, 8};

        OutputTableHeader(kMulticastAddrInfoTitles, kMulticastAddrInfoColumnWidths);
    }

    otHistoryTrackerInitIterator(&iterator);

    for (uint16_t index = 0; (numEntries == 0) || (index < numEntries); index++)
    {
        info = otHistoryTrackerIterateMulticastAddressHistory(GetInstancePtr(), &iterator, &entryAge);
        VerifyOrExit(info != nullptr);

        otHistoryTrackerEntryAgeToString(entryAge, ageString, sizeof(ageString));
        otIp6AddressToString(&info->mAddress, addressString, sizeof(addressString));

        OutputLine(isList ? "%s -> event:%s address:%s origin:%s" : "| %20s | %-12s | %-39s | %-6s |", ageString,
                   Stringify(info->mEvent, kEventStrings), addressString,
                   Interpreter::AddressOriginToString(info->mAddressOrigin));
    }

exit:
    return error;
}

/**
 * @cli history neighbor
 * @code
 * history neighbor
 * | Age                  | Type   | Event     | Extended Address | RLOC16 | Mode | Ave RSS |
 * +----------------------+--------+-----------+------------------+--------+------+---------+
 * |         00:00:29.233 | Child  | Added     | ae5105292f0b9169 | 0x8404 | -    |     -20 |
 * |         00:01:38.368 | Child  | Removed   | ae5105292f0b9169 | 0x8401 | -    |     -20 |
 * |         00:04:27.181 | Child  | Changed   | ae5105292f0b9169 | 0x8401 | -    |     -20 |
 * |         00:04:51.236 | Router | Added     | 865c7ca38a5fa960 | 0x9400 | rdn  |     -20 |
 * |         00:04:51.587 | Child  | Removed   | 865c7ca38a5fa960 | 0x8402 | rdn  |     -20 |
 * |         00:05:22.764 | Child  | Changed   | ae5105292f0b9169 | 0x8401 | rn   |     -20 |
 * |         00:06:40.764 | Child  | Added     | 4ec99efc874a1841 | 0x8403 | r    |     -20 |
 * |         00:06:44.060 | Child  | Added     | 865c7ca38a5fa960 | 0x8402 | rdn  |     -20 |
 * |         00:06:49.515 | Child  | Added     | ae5105292f0b9169 | 0x8401 | -    |     -20 |
 * Done
 * @endcode
 * @code
 * history neighbor list
 * 00:00:34.753 -> type:Child event:Added extaddr:ae5105292f0b9169 rloc16:0x8404 mode:- rss:-20
 * 00:01:43.888 -> type:Child event:Removed extaddr:ae5105292f0b9169 rloc16:0x8401 mode:- rss:-20
 * 00:04:32.701 -> type:Child event:Changed extaddr:ae5105292f0b9169 rloc16:0x8401 mode:- rss:-20
 * 00:04:56.756 -> type:Router event:Added extaddr:865c7ca38a5fa960 rloc16:0x9400 mode:rdn rss:-20
 * 00:04:57.107 -> type:Child event:Removed extaddr:865c7ca38a5fa960 rloc16:0x8402 mode:rdn rss:-20
 * 00:05:28.284 -> type:Child event:Changed extaddr:ae5105292f0b9169 rloc16:0x8401 mode:rn rss:-20
 * 00:06:46.284 -> type:Child event:Added extaddr:4ec99efc874a1841 rloc16:0x8403 mode:r rss:-20
 * 00:06:49.580 -> type:Child event:Added extaddr:865c7ca38a5fa960 rloc16:0x8402 mode:rdn rss:-20
 * 00:06:55.035 -> type:Child event:Added extaddr:ae5105292f0b9169 rloc16:0x8401 mode:- rss:-20
 * Done
 * @endcode
 * @cparam history neighbor [@ca{list}] [@ca{num-entries}]
 * * Use the `list` option to display the output in list format. Otherwise,
 *   the output is shown in table format.
 * * Use the `num-entries` option to limit the output to the number of
 *   most-recent entries specified. If this option is not used, all stored
 *   entries are shown in the output.
 * @par
 * Displays the neighbor history in table or list format.
 * @par
 * Each table or list entry provides:
 * * Age: Time elapsed since the command was issued, and given in the format:
 *        `hours`:`minutes`:`seconds`:`milliseconds`
 * * Type: `Child` or `Router`.
 * * Event: Possible values are `Added`, `Removed`, or `Changed`.
 * * Extended Address
 * * RLOC16
 * * Mode: MLE link mode. Possible values:
 *     * `-`: no flags set (rx-off-when-idle, minimal Thread device,
 *       stable network data).
 *     * `r`: rx-on-when-idle
 *     * `d`: Full Thread Device.
 *     * `n`: Full Network Data
 * * Ave RSS: Average number of frames (in dBm) received from the neighbor at the
 *   time the entry was recorded.
 * @sa otHistoryTrackerIterateNeighborHistory
 */
template <> otError History::Process<Cmd("neighbor")>(Arg aArgs[])
{
    static const char *const kEventString[] = {
        /* (0) OT_HISTORY_TRACKER_NEIGHBOR_EVENT_ADDED     -> */ "Added",
        /* (1) OT_HISTORY_TRACKER_NEIGHBOR_EVENT_REMOVED   -> */ "Removed",
        /* (2) OT_HISTORY_TRACKER_NEIGHBOR_EVENT_CHANGED   -> */ "Changed",
        /* (3) OT_HISTORY_TRACKER_NEIGHBOR_EVENT_RESTORING -> */ "Restoring",
    };

    otError                             error;
    bool                                isList;
    uint16_t                            numEntries;
    otHistoryTrackerIterator            iterator;
    const otHistoryTrackerNeighborInfo *info;
    uint32_t                            entryAge;
    char                                ageString[OT_HISTORY_TRACKER_ENTRY_AGE_STRING_SIZE];
    otLinkModeConfig                    mode;
    char                                linkModeString[Interpreter::kLinkModeStringSize];

    static_assert(0 == OT_HISTORY_TRACKER_NEIGHBOR_EVENT_ADDED, "NEIGHBOR_EVENT_ADDED value is incorrect");
    static_assert(1 == OT_HISTORY_TRACKER_NEIGHBOR_EVENT_REMOVED, "NEIGHBOR_EVENT_REMOVED value is incorrect");
    static_assert(2 == OT_HISTORY_TRACKER_NEIGHBOR_EVENT_CHANGED, "NEIGHBOR_EVENT_CHANGED value is incorrect");
    static_assert(3 == OT_HISTORY_TRACKER_NEIGHBOR_EVENT_RESTORING, "NEIGHBOR_EVENT_RESTORING value is incorrect");

    SuccessOrExit(error = ParseArgs(aArgs, isList, numEntries));

    if (!isList)
    {
        // | Age                  | Type   | Event     | Extended Address | RLOC16 | Mode | Ave RSS |
        // +----------------------+--------+-----------+------------------+--------+------+---------+

        static const char *const kNeighborInfoTitles[] = {
            "Age", "Type", "Event", "Extended Address", "RLOC16", "Mode", "Ave RSS",
        };

        static const uint8_t kNeighborInfoColumnWidths[] = {22, 8, 11, 18, 8, 6, 9};

        OutputTableHeader(kNeighborInfoTitles, kNeighborInfoColumnWidths);
    }

    otHistoryTrackerInitIterator(&iterator);

    for (uint16_t index = 0; (numEntries == 0) || (index < numEntries); index++)
    {
        info = otHistoryTrackerIterateNeighborHistory(GetInstancePtr(), &iterator, &entryAge);
        VerifyOrExit(info != nullptr);

        otHistoryTrackerEntryAgeToString(entryAge, ageString, sizeof(ageString));

        mode.mRxOnWhenIdle = info->mRxOnWhenIdle;
        mode.mDeviceType   = info->mFullThreadDevice;
        mode.mNetworkData  = info->mFullNetworkData;
        Interpreter::LinkModeToString(mode, linkModeString);

        OutputFormat(isList ? "%s -> type:%s event:%s extaddr:" : "| %20s | %-6s | %-9s | ", ageString,
                     info->mIsChild ? "Child" : "Router", kEventString[info->mEvent]);
        OutputExtAddress(info->mExtAddress);
        OutputLine(isList ? " rloc16:0x%04x mode:%s rss:%d" : " | 0x%04x | %-4s | %7d |", info->mRloc16, linkModeString,
                   info->mAverageRssi);
    }

exit:
    return error;
}

/**
 * @cli history router
 * @code
 * history router
 * | Age                  | Event          | ID (RLOC16) | Next Hop    | Path Cost  |
 * +----------------------+----------------+-------------+-------------+------------+
 * |         00:00:05.258 | NextHopChanged |  7 (0x1c00) | 34 (0x8800) | inf ->   3 |
 * |         00:00:08.604 | NextHopChanged | 34 (0x8800) | 34 (0x8800) | inf ->   2 |
 * |         00:00:08.604 | Added          |  7 (0x1c00) |        none | inf -> inf |
 * |         00:00:11.931 | Added          | 34 (0x8800) |        none | inf -> inf |
 * |         00:00:14.948 | Removed        | 59 (0xec00) |        none | inf -> inf |
 * |         00:00:14.948 | Removed        | 54 (0xd800) |        none | inf -> inf |
 * |         00:00:14.948 | Removed        | 34 (0x8800) |        none | inf -> inf |
 * |         00:00:14.948 | Removed        |  7 (0x1c00) |        none | inf -> inf |
 * |         00:00:54.795 | NextHopChanged | 59 (0xec00) | 34 (0x8800) |   1 ->   5 |
 * |         00:02:33.735 | NextHopChanged | 54 (0xd800) |        none |  15 -> inf |
 * |         00:03:10.915 | CostChanged    | 54 (0xd800) | 34 (0x8800) |  13 ->  15 |
 * |         00:03:45.716 | NextHopChanged | 54 (0xd800) | 34 (0x8800) |  15 ->  13 |
 * |         00:03:46.188 | CostChanged    | 54 (0xd800) | 59 (0xec00) |  13 ->  15 |
 * |         00:04:19.124 | CostChanged    | 54 (0xd800) | 59 (0xec00) |  11 ->  13 |
 * |         00:04:52.008 | CostChanged    | 54 (0xd800) | 59 (0xec00) |   9 ->  11 |
 * |         00:05:23.176 | CostChanged    | 54 (0xd800) | 59 (0xec00) |   7 ->   9 |
 * |         00:05:51.081 | CostChanged    | 54 (0xd800) | 59 (0xec00) |   5 ->   7 |
 * |         00:06:48.721 | CostChanged    | 54 (0xd800) | 59 (0xec00) |   3 ->   5 |
 * |         00:07:13.792 | NextHopChanged | 54 (0xd800) | 59 (0xec00) |   1 ->   3 |
 * |         00:09:28.681 | NextHopChanged |  7 (0x1c00) | 34 (0x8800) | inf ->   3 |
 * |         00:09:31.882 | Added          |  7 (0x1c00) |        none | inf -> inf |
 * |         00:09:51.240 | NextHopChanged | 54 (0xd800) | 54 (0xd800) | inf ->   1 |
 * |         00:09:54.204 | Added          | 54 (0xd800) |        none | inf -> inf |
 * |         00:10:20.645 | NextHopChanged | 34 (0x8800) | 34 (0x8800) | inf ->   2 |
 * |         00:10:24.242 | NextHopChanged | 59 (0xec00) | 59 (0xec00) | inf ->   1 |
 * |         00:10:24.242 | Added          | 34 (0x8800) |        none | inf -> inf |
 * |         00:10:41.900 | NextHopChanged | 59 (0xec00) |        none |   1 -> inf |
 * |         00:10:42.480 | Added          |  3 (0x0c00) |  3 (0x0c00) | inf -> inf |
 * |         00:10:43.614 | Added          | 59 (0xec00) | 59 (0xec00) | inf ->   1 |
 * Done
 * @endcode
 * @code
 * history router list 20
 * 00:00:06.959 -> event:NextHopChanged router:7(0x1c00) nexthop:34(0x8800) old-cost:inf new-cost:3
 * 00:00:10.305 -> event:NextHopChanged router:34(0x8800) nexthop:34(0x8800) old-cost:inf new-cost:2
 * 00:00:10.305 -> event:Added router:7(0x1c00) nexthop:none old-cost:inf new-cost:inf
 * 00:00:13.632 -> event:Added router:34(0x8800) nexthop:none old-cost:inf new-cost:inf
 * 00:00:16.649 -> event:Removed router:59(0xec00) nexthop:none old-cost:inf new-cost:inf
 * 00:00:16.649 -> event:Removed router:54(0xd800) nexthop:none old-cost:inf new-cost:inf
 * 00:00:16.649 -> event:Removed router:34(0x8800) nexthop:none old-cost:inf new-cost:inf
 * 00:00:16.649 -> event:Removed router:7(0x1c00) nexthop:none old-cost:inf new-cost:inf
 * 00:00:56.496 -> event:NextHopChanged router:59(0xec00) nexthop:34(0x8800) old-cost:1 new-cost:5
 * 00:02:35.436 -> event:NextHopChanged router:54(0xd800) nexthop:none old-cost:15 new-cost:inf
 * 00:03:12.616 -> event:CostChanged router:54(0xd800) nexthop:34(0x8800) old-cost:13 new-cost:15
 * 00:03:47.417 -> event:NextHopChanged router:54(0xd800) nexthop:34(0x8800) old-cost:15 new-cost:13
 * 00:03:47.889 -> event:CostChanged router:54(0xd800) nexthop:59(0xec00) old-cost:13 new-cost:15
 * 00:04:20.825 -> event:CostChanged router:54(0xd800) nexthop:59(0xec00) old-cost:11 new-cost:13
 * 00:04:53.709 -> event:CostChanged router:54(0xd800) nexthop:59(0xec00) old-cost:9 new-cost:11
 * 00:05:24.877 -> event:CostChanged router:54(0xd800) nexthop:59(0xec00) old-cost:7 new-cost:9
 * 00:05:52.782 -> event:CostChanged router:54(0xd800) nexthop:59(0xec00) old-cost:5 new-cost:7
 * 00:06:50.422 -> event:CostChanged router:54(0xd800) nexthop:59(0xec00) old-cost:3 new-cost:5
 * 00:07:15.493 -> event:NextHopChanged router:54(0xd800) nexthop:59(0xec00) old-cost:1 new-cost:3
 * 00:09:30.382 -> event:NextHopChanged router:7(0x1c00) nexthop:34(0x8800) old-cost:inf new-cost:3
 * Done
 * @endcode
 * @cparam history router [@ca{list}] [@ca{num-entries}]
 * * Use the `list` option to display the output in list format. Otherwise,
 *   the output is shown in table format.
 * * Use the `num-entries` option to limit the output to the number of
 *   most-recent entries specified. If this option is not used, all stored
 *   entries are shown in the output.
 * @par
 * Displays the route-table history in table or list format.
 * @par
 * Each table or list entry provides:
 * * Age: Time elapsed since the command was issued, and given in the format:
 *        `hours`:`minutes`:`seconds`:`milliseconds`
 * * Event: Possible values are `Added`, `Removed`, `NextHopChanged`, or `CostChanged`.
 * * ID (RLOC16): Router ID and RLOC16 of the router.
 * * Next Hop: Router ID and RLOC16 of the next hop. If there is no next hop,
 *             `none` is shown.
 * * Path Cost: old cost `->` new cost. A value of `inf` indicates an infinite
 *      	path cost.
 * @sa otHistoryTrackerIterateRouterHistory
 */
template <> otError History::Process<Cmd("router")>(Arg aArgs[])
{
    static const char *const kEventString[] = {
        /* (0) OT_HISTORY_TRACKER_ROUTER_EVENT_ADDED             -> */ "Added",
        /* (1) OT_HISTORY_TRACKER_ROUTER_EVENT_REMOVED           -> */ "Removed",
        /* (2) OT_HISTORY_TRACKER_ROUTER_EVENT_NEXT_HOP_CHANGED  -> */ "NextHopChanged",
        /* (3) OT_HISTORY_TRACKER_ROUTER_EVENT_COST_CHANGED      -> */ "CostChanged",
    };

    constexpr uint8_t kRouterIdOffset = 10; // Bit offset of Router ID in RLOC16

    otError                           error;
    bool                              isList;
    uint16_t                          numEntries;
    otHistoryTrackerIterator          iterator;
    const otHistoryTrackerRouterInfo *info;
    uint32_t                          entryAge;
    char                              ageString[OT_HISTORY_TRACKER_ENTRY_AGE_STRING_SIZE];

    static_assert(0 == OT_HISTORY_TRACKER_ROUTER_EVENT_ADDED, "EVENT_ADDED is incorrect");
    static_assert(1 == OT_HISTORY_TRACKER_ROUTER_EVENT_REMOVED, "EVENT_REMOVED is incorrect");
    static_assert(2 == OT_HISTORY_TRACKER_ROUTER_EVENT_NEXT_HOP_CHANGED, "EVENT_NEXT_HOP_CHANGED is incorrect");
    static_assert(3 == OT_HISTORY_TRACKER_ROUTER_EVENT_COST_CHANGED, "EVENT_COST_CHANGED is incorrect");

    SuccessOrExit(error = ParseArgs(aArgs, isList, numEntries));

    if (!isList)
    {
        // | Age                  | Event          | ID (RlOC16) | Next Hop   | Path Cost   |
        // +----------------------+----------------+-------------+------------+-------------+

        static const char *const kRouterInfoTitles[] = {
            "Age", "Event", "ID (RLOC16)", "Next Hop", "Path Cost",
        };

        static const uint8_t kRouterInfoColumnWidths[] = {22, 16, 13, 13, 12};

        OutputTableHeader(kRouterInfoTitles, kRouterInfoColumnWidths);
    }

    otHistoryTrackerInitIterator(&iterator);

    for (uint16_t index = 0; (numEntries == 0) || (index < numEntries); index++)
    {
        info = otHistoryTrackerIterateRouterHistory(GetInstancePtr(), &iterator, &entryAge);
        VerifyOrExit(info != nullptr);

        otHistoryTrackerEntryAgeToString(entryAge, ageString, sizeof(ageString));

        OutputFormat(isList ? "%s -> event:%s router:%u(0x%04x) nexthop:" : "| %20s | %-14s | %2u (0x%04x) | ",
                     ageString, kEventString[info->mEvent], info->mRouterId,
                     static_cast<uint16_t>(info->mRouterId) << kRouterIdOffset);

        if (info->mNextHop != OT_HISTORY_TRACKER_NO_NEXT_HOP)
        {
            OutputFormat(isList ? "%u(0x%04x)" : "%2u (0x%04x)", info->mNextHop,
                         static_cast<uint16_t>(info->mNextHop) << kRouterIdOffset);
        }
        else
        {
            OutputFormat(isList ? "%s" : "%11s", "none");
        }

        if (info->mOldPathCost != OT_HISTORY_TRACKER_INFINITE_PATH_COST)
        {
            OutputFormat(isList ? " old-cost:%u" : " | %3u ->", info->mOldPathCost);
        }
        else
        {
            OutputFormat(isList ? " old-cost:inf" : " | inf ->");
        }

        if (info->mPathCost != OT_HISTORY_TRACKER_INFINITE_PATH_COST)
        {
            OutputLine(isList ? " new-cost:%u" : " %3u |", info->mPathCost);
        }
        else
        {
            OutputLine(isList ? " new-cost:inf" : " inf |");
        }
    }

exit:
    return error;
}

/**
 * @cli history netinfo
 * @code
 * history netinfo
 * | Age                  | Role     | Mode | RLOC16 | Partition ID |
 * +----------------------+----------+------+--------+--------------+
 * |         00:00:10.069 | router   | rdn  | 0x6000 |    151029327 |
 * |         00:02:09.337 | child    | rdn  | 0x2001 |    151029327 |
 * |         00:02:09.338 | child    | rdn  | 0x2001 |    151029327 |
 * |         00:07:40.806 | child    | -    | 0x2001 |    151029327 |
 * |         00:07:42.297 | detached | -    | 0x6000 |            0 |
 * |         00:07:42.968 | disabled | -    | 0x6000 |            0 |
 * Done
 * @endcode
 * @code
 * history netinfo list
 * 00:00:59.467 -> role:router mode:rdn rloc16:0x6000 partition-id:151029327
 * 00:02:58.735 -> role:child mode:rdn rloc16:0x2001 partition-id:151029327
 * 00:02:58.736 -> role:child mode:rdn rloc16:0x2001 partition-id:151029327
 * 00:08:30.204 -> role:child mode:- rloc16:0x2001 partition-id:151029327
 * 00:08:31.695 -> role:detached mode:- rloc16:0x6000 partition-id:0
 * 00:08:32.366 -> role:disabled mode:- rloc16:0x6000 partition-id:0
 * Done
 * @endcode
 * @code
 * history netinfo 2
 * | Age                  | Role     | Mode | RLOC16 | Partition ID |
 * +----------------------+----------+------+--------+--------------+
 * |         00:02:05.451 | router   | rdn  | 0x6000 |    151029327 |
 * |         00:04:04.719 | child    | rdn  | 0x2001 |    151029327 |
 * Done
 * @endcode
 * @cparam history netinfo [@ca{list}] [@ca{num-entries}]
 * * Use the `list` option to display the output in list format. Otherwise,
 *   the output is shown in table format.
 * * Use the `num-entries` option to limit the output to the number of
 *   most-recent entries specified. If this option is not used, all stored
 *   entries are shown in the output.
 * @par
 * Displays the network info history in table or list format.
 * @par
 * Each table or list entry provides:
 * * Age: Time elapsed since the command was issued, and given in the format:
 *        `hours`:`minutes`:`seconds`:`milliseconds`
 * * Role: Device role. Possible values are `router`, `child`, `detached`, or `disabled`.
 * * Mode: MLE link mode. Possible values:
 *     * `-`: no flags set (rx-off-when-idle, minimal Thread device,
 *       stable network data).
 *     * `r`: rx-on-when-idle
 *     * `d`: Full Thread Device.
 *     * `n`: Full Network Data
 * * RLOC16
 * * Partition ID.
 * @sa otHistoryTrackerIterateNetInfoHistory
 */
template <> otError History::Process<Cmd("netinfo")>(Arg aArgs[])
{
    otError                            error;
    bool                               isList;
    uint16_t                           numEntries;
    otHistoryTrackerIterator           iterator;
    const otHistoryTrackerNetworkInfo *info;
    uint32_t                           entryAge;
    char                               ageString[OT_HISTORY_TRACKER_ENTRY_AGE_STRING_SIZE];
    char                               linkModeString[Interpreter::kLinkModeStringSize];

    SuccessOrExit(error = ParseArgs(aArgs, isList, numEntries));

    if (!isList)
    {
        // | Age                  | Role     | Mode | RLOC16 | Partition ID |
        // +----------------------+----------+------+--------+--------------+

        static const char *const kNetInfoTitles[]       = {"Age", "Role", "Mode", "RLOC16", "Partition ID"};
        static const uint8_t     kNetInfoColumnWidths[] = {22, 10, 6, 8, 14};

        OutputTableHeader(kNetInfoTitles, kNetInfoColumnWidths);
    }

    otHistoryTrackerInitIterator(&iterator);

    for (uint16_t index = 0; (numEntries == 0) || (index < numEntries); index++)
    {
        info = otHistoryTrackerIterateNetInfoHistory(GetInstancePtr(), &iterator, &entryAge);
        VerifyOrExit(info != nullptr);

        otHistoryTrackerEntryAgeToString(entryAge, ageString, sizeof(ageString));

        OutputLine(
            isList ? "%s -> role:%s mode:%s rloc16:0x%04x partition-id:%lu" : "| %20s | %-8s | %-4s | 0x%04x | %12lu |",
            ageString, otThreadDeviceRoleToString(info->mRole),
            Interpreter::LinkModeToString(info->mMode, linkModeString), info->mRloc16, ToUlong(info->mPartitionId));
    }

exit:
    return error;
}

/**
 * @cli history rx
 * @code
 * history rx
 * | Age                  | Type             | Len   | Chksum | Sec | Prio | RSS  |Dir | Neighb | Radio |
 * +----------------------+------------------+-------+--------+-----+------+------+----+--------+-------+
 * |                      | UDP              |    50 | 0xbd26 |  no |  net |  -20 | RX | 0x4800 |  15.4 |
 * |         00:00:07.640 | src: [fe80:0:0:0:d03d:d3e7:cc5e:7cd7]:19788                                 |
 * |                      | dst: [ff02:0:0:0:0:0:0:1]:19788                                             |
 * +----------------------+------------------+-------+--------+-----+------+------+----+--------+-------+
 * |                      | HopOpts          |    44 | 0x0000 | yes | norm |  -20 | RX | 0x4800 |  15.4 |
 * |         00:00:09.263 | src: [fdde:ad00:beef:0:0:ff:fe00:4800]:0                                    |
 * |                      | dst: [ff03:0:0:0:0:0:0:2]:0                                                 |
 * +----------------------+------------------+-------+--------+-----+------+------+----+--------+-------+
 * |                      | UDP              |    12 | 0x3f7d | yes |  net |  -20 | RX | 0x4800 |  15.4 |
 * |         00:00:09.302 | src: [fdde:ad00:beef:0:0:ff:fe00:4800]:61631                                |
 * |                      | dst: [fdde:ad00:beef:0:0:ff:fe00:4801]:61631                                |
 * +----------------------+------------------+-------+--------+-----+------+------+----+--------+-------+
 * |                      | ICMP6(EchoReqst) |    16 | 0x942c | yes | norm |  -20 | RX | 0x4800 |  15.4 |
 * |         00:00:09.304 | src: [fdde:ad00:beef:0:ac09:a16b:3204:dc09]:0                               |
 * |                      | dst: [fdde:ad00:beef:0:dc0e:d6b3:f180:b75b]:0                               |
 * +----------------------+------------------+-------+--------+-----+------+------+----+--------+-------+
 * |                      | HopOpts          |    44 | 0x0000 | yes | norm |  -20 | RX | 0x4800 |  15.4 |
 * |         00:00:09.304 | src: [fdde:ad00:beef:0:0:ff:fe00:4800]:0                                    |
 * |                      | dst: [ff03:0:0:0:0:0:0:2]:0                                                 |
 * +----------------------+------------------+-------+--------+-----+------+------+----+--------+-------+
 * |                      | UDP              |    50 | 0x2e37 |  no |  net |  -20 | RX | 0x4800 |  15.4 |
 * |         00:00:21.622 | src: [fe80:0:0:0:d03d:d3e7:cc5e:7cd7]:19788                                 |
 * |                      | dst: [ff02:0:0:0:0:0:0:1]:19788                                             |
 * +----------------------+------------------+-------+--------+-----+------+------+----+--------+-------+
 * |                      | UDP              |    50 | 0xe177 |  no |  net |  -20 | RX | 0x4800 |  15.4 |
 * |         00:00:26.640 | src: [fe80:0:0:0:d03d:d3e7:cc5e:7cd7]:19788                                 |
 * |                      | dst: [ff02:0:0:0:0:0:0:1]:19788                                             |
 * +----------------------+------------------+-------+--------+-----+------+------+----+--------+-------+
 * |                      | UDP              |   165 | 0x82ee | yes |  net |  -20 | RX | 0x4800 |  15.4 |
 * |         00:00:30.000 | src: [fe80:0:0:0:d03d:d3e7:cc5e:7cd7]:19788                                 |
 * |                      | dst: [fe80:0:0:0:a4a5:bbac:a8e:bd07]:19788                                  |
 * +----------------------+------------------+-------+--------+-----+------+------+----+--------+-------+
 * |                      | UDP              |    93 | 0x52df |  no |  net |  -20 | RX | unknwn |  15.4 |
 * |         00:00:30.480 | src: [fe80:0:0:0:d03d:d3e7:cc5e:7cd7]:19788                                 |
 * |                      | dst: [fe80:0:0:0:a4a5:bbac:a8e:bd07]:19788                                  |
 * +----------------------+------------------+-------+--------+-----+------+------+----+--------+-------+
 * |                      | UDP              |    50 | 0x5ccf |  no |  net |  -20 | RX | unknwn |  15.4 |
 * |         00:00:30.772 | src: [fe80:0:0:0:d03d:d3e7:cc5e:7cd7]:19788                                 |
 * |                      | dst: [ff02:0:0:0:0:0:0:1]:19788                                             |
 * Done
 * @endcode
 * @code
 * history rx list 4
 * 00:00:13.368
       type:UDP len:50 checksum:0xbd26 sec:no prio:net rss:-20 from:0x4800 radio:15.4
       src:[fe80:0:0:0:d03d:d3e7:cc5e:7cd7]:19788
       dst:[ff02:0:0:0:0:0:0:1]:19788
 * 00:00:14.991
       type:HopOpts len:44 checksum:0x0000 sec:yes prio:norm rss:-20 from:0x4800 radio:15.4
       src:[fdde:ad00:beef:0:0:ff:fe00:4800]:0
       dst:[ff03:0:0:0:0:0:0:2]:0
 * 00:00:15.030
       type:UDP len:12 checksum:0x3f7d sec:yes prio:net rss:-20 from:0x4800 radio:15.4
       src:[fdde:ad00:beef:0:0:ff:fe00:4800]:61631
       dst:[fdde:ad00:beef:0:0:ff:fe00:4801]:61631
 * 00:00:15.032
       type:ICMP6(EchoReqst) len:16 checksum:0x942c sec:yes prio:norm rss:-20 from:0x4800 radio:15.4
       src:[fdde:ad00:beef:0:ac09:a16b:3204:dc09]:0
       dst:[fdde:ad00:beef:0:dc0e:d6b3:f180:b75b]:0
 * Done
 * @endcode
 * @cparam history rx [@ca{list}] [@ca{num-entries}]
 * * Use the `list` option to display the output in list format. Otherwise,
 *   the output is shown in table format.
 * * Use the `num-entries` option to limit the output to the number of
 *   most-recent entries specified. If this option is not used, all stored
 *   entries are shown in the output.
 * @par
 * Displays the IPv6 message RX history in table or list format.
 * @par
 * Each table or list entry provides:
 * * Age: Time elapsed since the command was issued, and given in the format:
 *        `hours`:`minutes`:`seconds`:`milliseconds`
 * * Type:
 *     * IPv6 message type, such as `UDP`, `TCP`, `HopOpts`, and `ICMP6` (and its subtype).
 *     * `src`: Source IPv6 address and port number.
 *     * `dst`: Destination IPv6 address and port number (port number is valid
         for UDP/TCP, otherwise it is 0).
 * * Len: IPv6 payload length (excluding the IPv6 header).
 * * Chksum: Message checksum (valid for UDP, TCP, or ICMP6 messages).
 * * Sec: Indicates if link-layer security was used.
 * * Prio: Message priority. Possible values are `low`, `norm`, `high`, or
 *         `net` (for Thread control messages).
 * * RSS: Received Signal Strength (in dBm), averaged over all received fragment
 *        frames that formed the message. For TX history, `NA` (not applicable)
          is displayed.
 * * Dir: Shows whether the message was sent (`TX`) or received (`RX`). A failed
 *        transmission is indicated with `TX-F` in table format or
 *        `tx-success:no` in list format. Examples of a failed transmission
 *        include a `tx`getting aborted and no `ack` getting sent from the peer for
 *        any of the message fragments.
 * * Neighb: Short address (RLOC16) of the neighbor with whom the message was
 *           sent/received. If the frame was broadcast, it is shown as
 *           `bcast` in table format or `0xffff` in list format. If the short
 *           address of the neighbor is not available, it is shown as `unknwn` in
 *           table format or `0xfffe` in list format.
 * * Radio: Radio link on which the message was sent/received (useful when
            `OPENTHREAD_CONFIG_MULTI_RADIO` is enabled). Can be `15.4`, `trel`,
            or `all` (if sent on all radio links).
 * @sa otHistoryTrackerIterateRxHistory
 */
template <> otError History::Process<Cmd("rx")>(Arg aArgs[]) { return ProcessRxTxHistory(kRx, aArgs); }

/**
 * @cli history rxtx
 * @code
 * history rxtx
 * | Age                  | Type             | Len   | Chksum | Sec | Prio | RSS  |Dir | Neighb | Radio |
 * +----------------------+------------------+-------+--------+-----+------+------+----+--------+-------+
 * |                      | HopOpts          |    44 | 0x0000 | yes | norm |  -20 | RX | 0x0800 |  15.4 |
 * |         00:00:09.267 | src: [fdde:ad00:beef:0:0:ff:fe00:800]:0                                     |
 * |                      | dst: [ff03:0:0:0:0:0:0:2]:0                                                 |
 * +----------------------+------------------+-------+--------+-----+------+------+----+--------+-------+
 * |                      | UDP              |    12 | 0x6c6b | yes |  net |  -20 | RX | 0x0800 |  15.4 |
 * |         00:00:09.290 | src: [fdde:ad00:beef:0:0:ff:fe00:800]:61631                                 |
 * |                      | dst: [fdde:ad00:beef:0:0:ff:fe00:801]:61631                                 |
 * +----------------------+------------------+-------+--------+-----+------+------+----+--------+-------+
 * |                      | ICMP6(EchoReqst) |    16 | 0xc6a2 | yes | norm |  -20 | RX | 0x0800 |  15.4 |
 * |         00:00:09.292 | src: [fdde:ad00:beef:0:efe8:4910:cf95:dee9]:0                               |
 * |                      | dst: [fdde:ad00:beef:0:af4c:3644:882a:3698]:0                               |
 * +----------------------+------------------+-------+--------+-----+------+------+----+--------+-------+
 * |                      | ICMP6(EchoReply) |    16 | 0xc5a2 | yes | norm |  NA  | TX | 0x0800 |  15.4 |
 * |         00:00:09.292 | src: [fdde:ad00:beef:0:af4c:3644:882a:3698]:0                               |
 * |                      | dst: [fdde:ad00:beef:0:efe8:4910:cf95:dee9]:0                               |
 * +----------------------+------------------+-------+--------+-----+------+------+----+--------+-------+
 * |                      | UDP              |    50 | 0xaa0d | yes |  net |  NA  | TX | 0x0800 |  15.4 |
 * |         00:00:09.294 | src: [fdde:ad00:beef:0:0:ff:fe00:801]:61631                                 |
 * |                      | dst: [fdde:ad00:beef:0:0:ff:fe00:800]:61631                                 |
 * +----------------------+------------------+-------+--------+-----+------+------+----+--------+-------+
 * |                      | HopOpts          |    44 | 0x0000 | yes | norm |  -20 | RX | 0x0800 |  15.4 |
 * |         00:00:09.296 | src: [fdde:ad00:beef:0:0:ff:fe00:800]:0                                     |
 * |                      | dst: [ff03:0:0:0:0:0:0:2]:0                                                 |
 * +----------------------+------------------+-------+--------+-----+------+------+----+--------+-------+
 * |                      | UDP              |    50 | 0xc1d8 |  no |  net |  -20 | RX | 0x0800 |  15.4 |
 * |         00:00:09.569 | src: [fe80:0:0:0:54d9:5153:ffc6:df26]:19788                                 |
 * |                      | dst: [ff02:0:0:0:0:0:0:1]:19788                                             |
 * +----------------------+------------------+-------+--------+-----+------+------+----+--------+-------+
 * |                      | UDP              |    50 | 0x3cb1 |  no |  net |  -20 | RX | 0x0800 |  15.4 |
 * |         00:00:16.519 | src: [fe80:0:0:0:54d9:5153:ffc6:df26]:19788                                 |
 * |                      | dst: [ff02:0:0:0:0:0:0:1]:19788                                             |
 * +----------------------+------------------+-------+--------+-----+------+------+----+--------+-------+
 * |                      | UDP              |    50 | 0xeda0 |  no |  net |  -20 | RX | 0x0800 |  15.4 |
 * |         00:00:20.599 | src: [fe80:0:0:0:54d9:5153:ffc6:df26]:19788                                 |
 * |                      | dst: [ff02:0:0:0:0:0:0:1]:19788                                             |
 * +----------------------+------------------+-------+--------+-----+------+------+----+--------+-------+
 * |                      | UDP              |   165 | 0xbdfa | yes |  net |  -20 | RX | 0x0800 |  15.4 |
 * |         00:00:21.059 | src: [fe80:0:0:0:54d9:5153:ffc6:df26]:19788                                 |
 * |                      | dst: [fe80:0:0:0:8893:c2cc:d983:1e1c]:19788                                 |
 * +----------------------+------------------+-------+--------+-----+------+------+----+--------+-------+
 * |                      | UDP              |    64 | 0x1c11 |  no |  net |  NA  | TX | 0x0800 |  15.4 |
 * |         00:00:21.062 | src: [fe80:0:0:0:8893:c2cc:d983:1e1c]:19788                                 |
 * |                      | dst: [fe80:0:0:0:54d9:5153:ffc6:df26]:19788                                 |
 * +----------------------+------------------+-------+--------+-----+------+------+----+--------+-------+
 * |                      | UDP              |    93 | 0xedff |  no |  net |  -20 | RX | unknwn |  15.4 |
 * |         00:00:21.474 | src: [fe80:0:0:0:54d9:5153:ffc6:df26]:19788                                 |
 * |                      | dst: [fe80:0:0:0:8893:c2cc:d983:1e1c]:19788                                 |
 * +----------------------+------------------+-------+--------+-----+------+------+----+--------+-------+
 * |                      | UDP              |    44 | 0xd383 |  no |  net |  NA  | TX | bcast  |  15.4 |
 * |         00:00:21.811 | src: [fe80:0:0:0:8893:c2cc:d983:1e1c]:19788                                 |
 * |                      | dst: [ff02:0:0:0:0:0:0:2]:19788                                             |
 * Done
 * @endcode
 * @code
 * history rxtx list 5
 * 00:00:02.100
       type:UDP len:50 checksum:0xd843 sec:no prio:net rss:-20 from:0x0800 radio:15.4
       src:[fe80:0:0:0:54d9:5153:ffc6:df26]:19788
       dst:[ff02:0:0:0:0:0:0:1]:19788
 * 00:00:15.331
       type:HopOpts len:44 checksum:0x0000 sec:yes prio:norm rss:-20 from:0x0800 radio:15.4
       src:[fdde:ad00:beef:0:0:ff:fe00:800]:0
       dst:[ff03:0:0:0:0:0:0:2]:0
 * 00:00:15.354
       type:UDP len:12 checksum:0x6c6b sec:yes prio:net rss:-20 from:0x0800 radio:15.4
       src:[fdde:ad00:beef:0:0:ff:fe00:800]:61631
       dst:[fdde:ad00:beef:0:0:ff:fe00:801]:61631
 * 00:00:15.356
       type:ICMP6(EchoReqst) len:16 checksum:0xc6a2 sec:yes prio:norm rss:-20 from:0x0800 radio:15.4
       src:[fdde:ad00:beef:0:efe8:4910:cf95:dee9]:0
       dst:[fdde:ad00:beef:0:af4c:3644:882a:3698]:0
 * 00:00:15.356
       type:ICMP6(EchoReply) len:16 checksum:0xc5a2 sec:yes prio:norm tx-success:yes to:0x0800 radio:15.4
       src:[fdde:ad00:beef:0:af4c:3644:882a:3698]:0
       dst:[fdde:ad00:beef:0:efe8:4910:cf95:dee9]:0
 * Done
 * @endcode
 * @cparam history rxtx [@ca{list}] [@ca{num-entries}]
 * * Use the `list` option to display the output in list format. Otherwise,
 *   the output is shown in table format.
 * * Use the `num-entries` option to limit the output to the number of
 *   most-recent entries specified. If this option is not used, all stored
 *   entries are shown in the output.
 * @par
 * Displays the combined IPv6 message RX and TX history in table or list format.
 * @par
 * Each table or list entry provides:
 * * Age: Time elapsed since the command was issued, and given in the format:
 *        `hours`:`minutes`:`seconds`:`milliseconds`
 * * Type:
 *     * IPv6 message type, such as `UDP`, `TCP`, `HopOpts`, and `ICMP6` (and its subtype).
 *     * `src`: Source IPv6 address and port number.
 *     * `dst`: Destination IPv6 address and port number (port number is valid
         for UDP/TCP, otherwise it is 0).
 * * Len: IPv6 payload length (excluding the IPv6 header).
 * * Chksum: Message checksum (valid for UDP, TCP, or ICMP6 messages).
 * * Sec: Indicates if link-layer security was used.
 * * Prio: Message priority. Possible values are `low`, `norm`, `high`, or
 *         `net` (for Thread control messages).
 * * RSS: Received Signal Strength (in dBm), averaged over all received fragment
 *        frames that formed the message. For TX history, `NA` (not applicable)
          is displayed.
 * * Dir: Shows whether the message was sent (`TX`) or received (`RX`). A failed
 *        transmission is indicated with `TX-F` in table format or
 *        `tx-success:no` in list format. Examples of a failed transmission
 *        include a `tx`getting aborted and no `ack` getting sent from the peer for
 *        any of the message fragments.
 * * Neighb: Short address (RLOC16) of the neighbor with whom the message was
 *           sent/received. If the frame was broadcast, it is shown as
 *           `bcast` in table format or `0xffff` in list format. If the short
 *           address of the neighbor is not available, it is shown as `unknwn` in
 *           table format or `0xfffe` in list format.
 * * Radio: Radio link on which the message was sent/received (useful when
            `OPENTHREAD_CONFIG_MULTI_RADIO` is enabled). Can be `15.4`, `trel`,
            or `all` (if sent on all radio links).
 * @sa otHistoryTrackerIterateRxHistory
 * @sa otHistoryTrackerIterateTxHistory
 */
template <> otError History::Process<Cmd("rxtx")>(Arg aArgs[]) { return ProcessRxTxHistory(kRxTx, aArgs); }

/**
 * @cli history tx
 * @code
 * history tx
 * | Age                  | Type             | Len   | Chksum | Sec | Prio | RSS  |Dir | Neighb | Radio |
 * +----------------------+------------------+-------+--------+-----+------+------+----+--------+-------+
 * |                      | ICMP6(EchoReply) |    16 | 0x932c | yes | norm |  NA  | TX | 0x4800 |  15.4 |
 * |         00:00:18.798 | src: [fdde:ad00:beef:0:dc0e:d6b3:f180:b75b]:0                               |
 * |                      | dst: [fdde:ad00:beef:0:ac09:a16b:3204:dc09]:0                               |
 * +----------------------+------------------+-------+--------+-----+------+------+----+--------+-------+
 * |                      | UDP              |    50 | 0xce87 | yes |  net |  NA  | TX | 0x4800 |  15.4 |
 * |         00:00:18.800 | src: [fdde:ad00:beef:0:0:ff:fe00:4801]:61631                                |
 * |                      | dst: [fdde:ad00:beef:0:0:ff:fe00:4800]:61631                                |
 * +----------------------+------------------+-------+--------+-----+------+------+----+--------+-------+
 * |                      | UDP              |    64 | 0xf7ba |  no |  net |  NA  | TX | 0x4800 |  15.4 |
 * |         00:00:39.499 | src: [fe80:0:0:0:a4a5:bbac:a8e:bd07]:19788                                  |
 * |                      | dst: [fe80:0:0:0:d03d:d3e7:cc5e:7cd7]:19788                                 |
 * +----------------------+------------------+-------+--------+-----+------+------+----+--------+-------+
 * |                      | UDP              |    44 | 0x26d4 |  no |  net |  NA  | TX | bcast  |  15.4 |
 * |         00:00:40.256 | src: [fe80:0:0:0:a4a5:bbac:a8e:bd07]:19788                                  |
 * |                      | dst: [ff02:0:0:0:0:0:0:2]:19788                                             |
 * Done
 * @endcode
 * @code
 * history tx list
 * 00:00:23.957
       type:ICMP6(EchoReply) len:16 checksum:0x932c sec:yes prio:norm tx-success:yes to:0x4800 radio:15.4
       src:[fdde:ad00:beef:0:dc0e:d6b3:f180:b75b]:0
       dst:[fdde:ad00:beef:0:ac09:a16b:3204:dc09]:0
 * 00:00:23.959
       type:UDP len:50 checksum:0xce87 sec:yes prio:net tx-success:yes to:0x4800 radio:15.4
       src:[fdde:ad00:beef:0:0:ff:fe00:4801]:61631
       dst:[fdde:ad00:beef:0:0:ff:fe00:4800]:61631
 * 00:00:44.658
       type:UDP len:64 checksum:0xf7ba sec:no prio:net tx-success:yes to:0x4800 radio:15.4
       src:[fe80:0:0:0:a4a5:bbac:a8e:bd07]:19788
       dst:[fe80:0:0:0:d03d:d3e7:cc5e:7cd7]:19788
 * 00:00:45.415
       type:UDP len:44 checksum:0x26d4 sec:no prio:net tx-success:yes to:0xffff radio:15.4
       src:[fe80:0:0:0:a4a5:bbac:a8e:bd07]:19788
       dst:[ff02:0:0:0:0:0:0:2]:19788
 * Done
 * @endcode
 * @cparam history tx [@ca{list}] [@ca{num-entries}]
 * * Use the `list` option to display the output in list format. Otherwise,
 *   the output is shown in table format.
 * * Use the `num-entries` option to limit the output to the number of
 *   most-recent entries specified. If this option is not used, all stored
 *   entries are shown in the output.
 * @par
 * Displays the IPv6 message TX history in table or list format.
 * @par
 * Each table or list entry provides:
 * * Age: Time elapsed since the command was issued, and given in the format:
 *        `hours`:`minutes`:`seconds`:`milliseconds`
 * * Type:
 *     * IPv6 message type, such as `UDP`, `TCP`, `HopOpts`, and `ICMP6` (and its subtype).
 *     * `src`: Source IPv6 address and port number.
 *     * `dst`: Destination IPv6 address and port number (port number is valid
         for UDP/TCP, otherwise it is 0).
 * * Len: IPv6 payload length (excluding the IPv6 header).
 * * Chksum: Message checksum (valid for UDP, TCP, or ICMP6 messages).
 * * Sec: Indicates if link-layer security was used.
 * * Prio: Message priority. Possible values are `low`, `norm`, `high`, or
 *         `net` (for Thread control messages).
 * * RSS: Received Signal Strength (in dBm), averaged over all received fragment
 *        frames that formed the message. For TX history, `NA` (not applicable)
          is displayed.
 * * Dir: Shows whether the message was sent (`TX`) or received (`RX`). A failed
 *        transmission is indicated with `TX-F` in table format or
 *        `tx-success:no` in list format. Examples of a failed transmission
 *        include a `tx`getting aborted and no `ack` getting sent from the peer for
 *        any of the message fragments.
 * * Neighb: Short address (RLOC16) of the neighbor with whom the message was
 *           sent/received. If the frame was broadcast, it is shown as
 *           `bcast` in table format or `0xffff` in list format. If the short
 *           address of the neighbor is not available, it is shown as `unknwn` in
 *           table format or `0xfffe` in list format.
 * * Radio: Radio link on which the message was sent/received (useful when
            `OPENTHREAD_CONFIG_MULTI_RADIO` is enabled). Can be `15.4`, `trel`,
            or `all` (if sent on all radio links).
 * @sa otHistoryTrackerIterateTxHistory
 */
template <> otError History::Process<Cmd("tx")>(Arg aArgs[]) { return ProcessRxTxHistory(kTx, aArgs); }

const char *History::MessagePriorityToString(uint8_t aPriority)
{
    static const char *const kPriorityStrings[] = {
        "low",  // (0) OT_HISTORY_TRACKER_MSG_PRIORITY_LOW
        "norm", // (1) OT_HISTORY_TRACKER_MSG_PRIORITY_NORMAL
        "high", // (2) OT_HISTORY_TRACKER_MSG_PRIORITY_HIGH
        "net",  // (3) OT_HISTORY_TRACKER_MSG_PRIORITY_NET
    };

    static_assert(0 == OT_HISTORY_TRACKER_MSG_PRIORITY_LOW, "MSG_PRIORITY_LOW value is incorrect");
    static_assert(1 == OT_HISTORY_TRACKER_MSG_PRIORITY_NORMAL, "MSG_PRIORITY_NORMAL value is incorrect");
    static_assert(2 == OT_HISTORY_TRACKER_MSG_PRIORITY_HIGH, "MSG_PRIORITY_HIGH value is incorrect");
    static_assert(3 == OT_HISTORY_TRACKER_MSG_PRIORITY_NET, "MSG_PRIORITY_NET value is incorrect");

    return Stringify(aPriority, kPriorityStrings, "unkn");
}

const char *History::RadioTypeToString(const otHistoryTrackerMessageInfo &aInfo)
{
    const char *str = "none";

    if (aInfo.mRadioTrelUdp6 && aInfo.mRadioIeee802154)
    {
        str = "all";
    }
    else if (aInfo.mRadioIeee802154)
    {
        str = "15.4";
    }
    else if (aInfo.mRadioTrelUdp6)
    {
        str = "trel";
    }

    return str;
}

const char *History::MessageTypeToString(const otHistoryTrackerMessageInfo &aInfo)
{
    const char *str = otIp6ProtoToString(aInfo.mIpProto);

    if (aInfo.mIpProto == OT_IP6_PROTO_ICMP6)
    {
        switch (aInfo.mIcmp6Type)
        {
        case OT_ICMP6_TYPE_DST_UNREACH:
            str = "ICMP6(Unreach)";
            break;
        case OT_ICMP6_TYPE_PACKET_TO_BIG:
            str = "ICMP6(TooBig)";
            break;
        case OT_ICMP6_TYPE_ECHO_REQUEST:
            str = "ICMP6(EchoReqst)";
            break;
        case OT_ICMP6_TYPE_ECHO_REPLY:
            str = "ICMP6(EchoReply)";
            break;
        case OT_ICMP6_TYPE_ROUTER_SOLICIT:
            str = "ICMP6(RouterSol)";
            break;
        case OT_ICMP6_TYPE_ROUTER_ADVERT:
            str = "ICMP6(RouterAdv)";
            break;
        default:
            str = "ICMP6(Other)";
            break;
        }
    }

    return str;
}

otError History::ProcessRxTxHistory(RxTx aRxTx, Arg aArgs[])
{
    otError                            error;
    bool                               isList;
    uint16_t                           numEntries;
    otHistoryTrackerIterator           rxIterator;
    otHistoryTrackerIterator           txIterator;
    bool                               isRx   = false;
    const otHistoryTrackerMessageInfo *info   = nullptr;
    const otHistoryTrackerMessageInfo *rxInfo = nullptr;
    const otHistoryTrackerMessageInfo *txInfo = nullptr;
    uint32_t                           entryAge;
    uint32_t                           rxEntryAge;
    uint32_t                           txEntryAge;

    // | Age                  | Type             | Len   | Chksum | Sec | Prio | RSS  |Dir | Neighb | Radio |
    // +----------------------+------------------+-------+--------+-----+------+------+----+--------+-------+

    static const char *const kTableTitles[] = {"Age",  "Type", "Len", "Chksum", "Sec",
                                               "Prio", "RSS",  "Dir", "Neighb", "Radio"};

    static const uint8_t kTableColumnWidths[] = {22, 18, 7, 8, 5, 6, 6, 4, 8, 7};

    SuccessOrExit(error = ParseArgs(aArgs, isList, numEntries));

    if (!isList)
    {
        OutputTableHeader(kTableTitles, kTableColumnWidths);
    }

    otHistoryTrackerInitIterator(&txIterator);
    otHistoryTrackerInitIterator(&rxIterator);

    for (uint16_t index = 0; (numEntries == 0) || (index < numEntries); index++)
    {
        switch (aRxTx)
        {
        case kRx:
            info = otHistoryTrackerIterateRxHistory(GetInstancePtr(), &rxIterator, &entryAge);
            isRx = true;
            break;

        case kTx:
            info = otHistoryTrackerIterateTxHistory(GetInstancePtr(), &txIterator, &entryAge);
            isRx = false;
            break;

        case kRxTx:
            // Iterate through both RX and TX lists and determine the entry
            // with earlier age.

            if (rxInfo == nullptr)
            {
                rxInfo = otHistoryTrackerIterateRxHistory(GetInstancePtr(), &rxIterator, &rxEntryAge);
            }

            if (txInfo == nullptr)
            {
                txInfo = otHistoryTrackerIterateTxHistory(GetInstancePtr(), &txIterator, &txEntryAge);
            }

            if ((rxInfo != nullptr) && ((txInfo == nullptr) || (rxEntryAge <= txEntryAge)))
            {
                info     = rxInfo;
                entryAge = rxEntryAge;
                isRx     = true;
                rxInfo   = nullptr;
            }
            else
            {
                info     = txInfo;
                entryAge = txEntryAge;
                isRx     = false;
                txInfo   = nullptr;
            }

            break;
        }

        VerifyOrExit(info != nullptr);

        if (isList)
        {
            OutputRxTxEntryListFormat(*info, entryAge, isRx);
        }
        else
        {
            if (index != 0)
            {
                OutputTableSeparator(kTableColumnWidths);
            }

            OutputRxTxEntryTableFormat(*info, entryAge, isRx);
        }
    }

exit:
    return error;
}

void History::OutputRxTxEntryListFormat(const otHistoryTrackerMessageInfo &aInfo, uint32_t aEntryAge, bool aIsRx)
{
    constexpr uint8_t kIndentSize = 4;

    char ageString[OT_HISTORY_TRACKER_ENTRY_AGE_STRING_SIZE];

    otHistoryTrackerEntryAgeToString(aEntryAge, ageString, sizeof(ageString));

    OutputLine("%s", ageString);
    OutputFormat(kIndentSize, "type:%s len:%u checksum:0x%04x sec:%s prio:%s ", MessageTypeToString(aInfo),
                 aInfo.mPayloadLength, aInfo.mChecksum, aInfo.mLinkSecurity ? "yes" : "no",
                 MessagePriorityToString(aInfo.mPriority));
    if (aIsRx)
    {
        OutputFormat("rss:%d", aInfo.mAveRxRss);
    }
    else
    {
        OutputFormat("tx-success:%s", aInfo.mTxSuccess ? "yes" : "no");
    }

    OutputLine(" %s:0x%04x radio:%s", aIsRx ? "from" : "to", aInfo.mNeighborRloc16, RadioTypeToString(aInfo));

    OutputFormat(kIndentSize, "src:");
    OutputSockAddrLine(aInfo.mSource);

    OutputFormat(kIndentSize, "dst:");
    OutputSockAddrLine(aInfo.mDestination);
}

void History::OutputRxTxEntryTableFormat(const otHistoryTrackerMessageInfo &aInfo, uint32_t aEntryAge, bool aIsRx)
{
    char ageString[OT_HISTORY_TRACKER_ENTRY_AGE_STRING_SIZE];
    char addrString[OT_IP6_SOCK_ADDR_STRING_SIZE];

    otHistoryTrackerEntryAgeToString(aEntryAge, ageString, sizeof(ageString));

    OutputFormat("| %20s | %-16.16s | %5u | 0x%04x | %3s | %4s | ", "", MessageTypeToString(aInfo),
                 aInfo.mPayloadLength, aInfo.mChecksum, aInfo.mLinkSecurity ? "yes" : "no",
                 MessagePriorityToString(aInfo.mPriority));

    if (aIsRx)
    {
        OutputFormat("%4d | RX ", aInfo.mAveRxRss);
    }
    else
    {
        OutputFormat(" NA  |");
        OutputFormat(aInfo.mTxSuccess ? " TX " : "TX-F");
    }

    if (aInfo.mNeighborRloc16 == kShortAddrBroadcast)
    {
        OutputFormat("| bcast  ");
    }
    else if (aInfo.mNeighborRloc16 == kShortAddrInvalid)
    {
        OutputFormat("| unknwn ");
    }
    else
    {
        OutputFormat("| 0x%04x ", aInfo.mNeighborRloc16);
    }

    OutputLine("| %5.5s |", RadioTypeToString(aInfo));

    otIp6SockAddrToString(&aInfo.mSource, addrString, sizeof(addrString));
    OutputLine("| %20s | src: %-70s |", ageString, addrString);

    otIp6SockAddrToString(&aInfo.mDestination, addrString, sizeof(addrString));
    OutputLine("| %20s | dst: %-70s |", "", addrString);
}

/**
 * @cli history prefix
 * @code
 * history prefix
 * | Age                  | Event   | Prefix                                      | Flags     | Pref | RLOC16 |
 * +----------------------+---------+---------------------------------------------+-----------+------+--------+
 * |         00:00:10.663 | Added   | fd00:1111:2222:3333::/64                    | paro      | med  | 0x5400 |
 * |         00:01:02.054 | Removed | fd00:dead:beef:1::/64                       | paros     | high | 0x5400 |
 * |         00:01:21.136 | Added   | fd00:abba:cddd:0::/64                       | paos      | med  | 0x5400 |
 * |         00:01:45.144 | Added   | fd00:dead:beef:1::/64                       | paros     | high | 0x3c00 |
 * |         00:01:50.944 | Added   | fd00:dead:beef:1::/64                       | paros     | high | 0x5400 |
 * |         00:01:59.887 | Added   | fd00:dead:beef:1::/64                       | paros     | med  | 0x8800 |
 * Done
 * @endcode
 * @code
 * history prefix list
 * 00:04:12.487 -> event:Added prefix:fd00:1111:2222:3333::/64 flags:paro pref:med rloc16:0x5400
 * 00:05:03.878 -> event:Removed prefix:fd00:dead:beef:1::/64 flags:paros pref:high rloc16:0x5400
 * 00:05:22.960 -> event:Added prefix:fd00:abba:cddd:0::/64 flags:paos pref:med rloc16:0x5400
 * 00:05:46.968 -> event:Added prefix:fd00:dead:beef:1::/64 flags:paros pref:high rloc16:0x3c00
 * 00:05:52.768 -> event:Added prefix:fd00:dead:beef:1::/64 flags:paros pref:high rloc16:0x5400
 * 00:06:01.711 -> event:Added prefix:fd00:dead:beef:1::/64 flags:paros pref:med rloc16:0x8800
 * Done
 * @endcode
 * @cparam history prefix [@ca{list}] [@ca{num-entries}]
 * * Use the `list` option to display the output in list format. Otherwise,
 *   the output is shown in table format.
 * * Use the `num-entries` option to limit the output to the number of
 *   most-recent entries specified. If this option is not used, all stored
 *   entries are shown in the output.
 * @par
 * Displays the network data for the mesh prefix history in table or list format.
 * @par
 * Each table or list entry provides:
 * * Age: Time elapsed since the command was issued, and given in the format:
 *        `hours`:`minutes`:`seconds`:`milliseconds`
 * * Event: Possible values are `Added` or `Removed`.
 * * Prefix
 * * Flags/meaning:
 *     * `p`: Preferred flag
 *     * `a`: Stateless IPv6 address auto-configuration 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.
 * * Pref: Preference. Values can be either `high`, `med`, or `low`.
 * * RLOC16
 * @sa otHistoryTrackerIterateOnMeshPrefixHistory
 */
template <> otError History::Process<Cmd("prefix")>(Arg aArgs[])
{
    otError                                 error;
    bool                                    isList;
    uint16_t                                numEntries;
    otHistoryTrackerIterator                iterator;
    const otHistoryTrackerOnMeshPrefixInfo *info;
    uint32_t                                entryAge;
    char                                    ageString[OT_HISTORY_TRACKER_ENTRY_AGE_STRING_SIZE];
    char                                    prefixString[OT_IP6_PREFIX_STRING_SIZE];
    NetworkData::FlagsString                flagsString;

    static_assert(0 == OT_HISTORY_TRACKER_NET_DATA_ENTRY_ADDED, "NET_DATA_ENTRY_ADDED value is incorrect");
    static_assert(1 == OT_HISTORY_TRACKER_NET_DATA_ENTRY_REMOVED, "NET_DATA_ENTRY_REMOVED value is incorrect");

    SuccessOrExit(error = ParseArgs(aArgs, isList, numEntries));

    if (!isList)
    {
        // | Age                  | Event   | Prefix                                      | Flags     | Pref | RLOC16 |
        // +----------------------+---------+---------------------------------------------+-----------+------+--------+

        static const char *const kPrefixTitles[]       = {"Age", "Event", "Prefix", "Flags", "Pref", "RLOC16"};
        static const uint8_t     kPrefixColumnWidths[] = {22, 9, 45, 11, 6, 8};

        OutputTableHeader(kPrefixTitles, kPrefixColumnWidths);
    }

    otHistoryTrackerInitIterator(&iterator);

    for (uint16_t index = 0; (numEntries == 0) || (index < numEntries); index++)
    {
        info = otHistoryTrackerIterateOnMeshPrefixHistory(GetInstancePtr(), &iterator, &entryAge);
        VerifyOrExit(info != nullptr);

        otHistoryTrackerEntryAgeToString(entryAge, ageString, sizeof(ageString));

        otIp6PrefixToString(&info->mPrefix.mPrefix, prefixString, sizeof(prefixString));
        NetworkData::PrefixFlagsToString(info->mPrefix, flagsString);

        OutputLine(isList ? "%s -> event:%s prefix:%s flags:%s pref:%s rloc16:0x%04x"
                          : "| %20s | %-7s | %-43s | %-9s | %-4s | 0x%04x |",
                   ageString, Stringify(info->mEvent, kSimpleEventStrings), prefixString, flagsString,
                   Interpreter::PreferenceToString(info->mPrefix.mPreference), info->mPrefix.mRloc16);
    }

exit:
    return error;
}

/**
 * @cli history route
 * @code
 * history route
 * | Age                  | Event   | Route                                       | Flags     | Pref | RLOC16 |
 * +----------------------+---------+---------------------------------------------+-----------+------+--------+
 * |         00:00:05.456 | Removed | fd00:1111:0::/48                            | s         | med  | 0x3c00 |
 * |         00:00:29.310 | Added   | fd00:1111:0::/48                            | s         | med  | 0x3c00 |
 * |         00:00:42.822 | Added   | fd00:1111:0::/48                            | s         | med  | 0x5400 |
 * |         00:01:27.688 | Added   | fd00:aaaa:bbbb:cccc::/64                    | s         | med  | 0x8800 |
 * Done
 * @endcode
 * @code
 * history route list 2
 * 00:00:48.704 -> event:Removed route:fd00:1111:0::/48 flags:s pref:med rloc16:0x3c00
 * 00:01:12.558 -> event:Added route:fd00:1111:0::/48 flags:s pref:med rloc16:0x3c00
 * Done
 * @endcode
 * @cparam history route [@ca{list}] [@ca{num-entries}]
 * * Use the `list` option to display the output in list format. Otherwise,
 *   the output is shown in table format.
 * * Use the `num-entries` option to limit the output to the number of
 *   most-recent entries specified. If this option is not used, all stored
 *   entries are shown in the output.
 * @par
 * Displays the network data external-route history in table or list format.
 * @par
 * Each table or list entry provides:
 * * Age: Time elapsed since the command was issued, and given in the format:
 *        `hours`:`minutes`:`seconds`:`milliseconds`
 * * Event: Possible values are `Added` or `Removed`.
 * * Route
 * * Flags/meaning:
 *     * `s`: Stable flag.
 *     * `n`: NAT64 flag.
 * * Pref: Preference. Values can be either `high`, `med`, or `low`.
 * * RLOC16
 * @sa otHistoryTrackerIterateExternalRouteHistory
 */
template <> otError History::Process<Cmd("route")>(Arg aArgs[])
{
    otError                                  error;
    bool                                     isList;
    uint16_t                                 numEntries;
    otHistoryTrackerIterator                 iterator;
    const otHistoryTrackerExternalRouteInfo *info;
    uint32_t                                 entryAge;
    char                                     ageString[OT_HISTORY_TRACKER_ENTRY_AGE_STRING_SIZE];
    char                                     prefixString[OT_IP6_PREFIX_STRING_SIZE];
    NetworkData::FlagsString                 flagsString;

    static_assert(0 == OT_HISTORY_TRACKER_NET_DATA_ENTRY_ADDED, "NET_DATA_ENTRY_ADDED value is incorrect");
    static_assert(1 == OT_HISTORY_TRACKER_NET_DATA_ENTRY_REMOVED, "NET_DATA_ENTRY_REMOVED value is incorrect");

    SuccessOrExit(error = ParseArgs(aArgs, isList, numEntries));

    if (!isList)
    {
        // | Age                  | Event   | Route                                       | Flags     | Pref | RLOC16 |
        // +----------------------+---------+---------------------------------------------+-----------+------+--------+

        static const char *const kRouteTitles[]       = {"Age", "Event", "Route", "Flags", "Pref", "RLOC16"};
        static const uint8_t     kRouteColumnWidths[] = {22, 9, 45, 11, 6, 8};

        OutputTableHeader(kRouteTitles, kRouteColumnWidths);
    }

    otHistoryTrackerInitIterator(&iterator);

    for (uint16_t index = 0; (numEntries == 0) || (index < numEntries); index++)
    {
        info = otHistoryTrackerIterateExternalRouteHistory(GetInstancePtr(), &iterator, &entryAge);
        VerifyOrExit(info != nullptr);

        otHistoryTrackerEntryAgeToString(entryAge, ageString, sizeof(ageString));

        otIp6PrefixToString(&info->mRoute.mPrefix, prefixString, sizeof(prefixString));
        NetworkData::RouteFlagsToString(info->mRoute, flagsString);

        OutputLine(isList ? "%s -> event:%s route:%s flags:%s pref:%s rloc16:0x%04x"
                          : "| %20s | %-7s | %-43s | %-9s | %-4s | 0x%04x |",
                   ageString, Stringify(info->mEvent, kSimpleEventStrings), prefixString, flagsString,
                   Interpreter::PreferenceToString(info->mRoute.mPreference), info->mRoute.mRloc16);
    }

exit:
    return error;
}

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

    static constexpr Command kCommands[] = {
        CmdEntry("ipaddr"), CmdEntry("ipmaddr"), CmdEntry("neighbor"), CmdEntry("netinfo"), CmdEntry("prefix"),
        CmdEntry("route"),  CmdEntry("router"),  CmdEntry("rx"),       CmdEntry("rxtx"),    CmdEntry("tx"),
    };

#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() ? 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

#endif // OPENTHREAD_CONFIG_HISTORY_TRACKER_ENABLE
