/*
 * SPDX-FileCopyrightText: Copyright (c) 2023-2024 NVIDIA CORPORATION &
 * AFFILIATES. All rights reserved. SPDX-License-Identifier: Apache-2.0
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

// NSM: Nvidia Message type
//           - Network Ports            [Type 1]
//           - PCI links                [Type 2]
//           - Platform environments    [Type 3]
//           - Diagnostics              [Type 4]
//           - Device configuration     [Type 5]

#include "nsm_telemetry_cmd.hpp"

#include "base.h"
#include "network-ports.h"
#include "pci-links.h"
#include "platform-environmental.h"

#include "cmd_helper.hpp"
#include "gpm_metrics_list.hpp"
#include "utils.hpp"

#include <CLI/CLI.hpp>

#include <cstdint>
#include <ctime>

namespace nsmtool
{

namespace telemetry
{

namespace
{

using namespace nsmtool::helper;
std::vector<std::unique_ptr<CommandInterface>> commands;

} // namespace

class GetPortTelemetryCounter : public CommandInterface
{
  public:
    ~GetPortTelemetryCounter() = default;
    GetPortTelemetryCounter() = delete;
    GetPortTelemetryCounter(const GetPortTelemetryCounter&) = delete;
    GetPortTelemetryCounter(GetPortTelemetryCounter&&) = default;
    GetPortTelemetryCounter& operator=(const GetPortTelemetryCounter&) = delete;
    GetPortTelemetryCounter& operator=(GetPortTelemetryCounter&&) = default;

    using CommandInterface::CommandInterface;

    explicit GetPortTelemetryCounter(const char* type, const char* name,
                                     CLI::App* app) :
        CommandInterface(type, name, app)
    {
        auto portTeleOptionGroup = app->add_option_group(
            "Required",
            "Port number for which counter value is to be retrieved.");

        portNumber = 00;
        portTeleOptionGroup->add_option(
            "-p, --portNum", portNumber,
            "retrieve counter values for Port number");
        portTeleOptionGroup->require_option(1);
    }

    std::pair<int, std::vector<uint8_t>> createRequestMsg() override
    {
        std::vector<uint8_t> requestMsg(
            sizeof(nsm_msg_hdr) + sizeof(nsm_get_port_telemetry_counter_req));
        auto request = reinterpret_cast<nsm_msg*>(requestMsg.data());
        auto rc = encode_get_port_telemetry_counter_req(instanceId, portNumber,
                                                        request);
        return {rc, requestMsg};
    }

    void parseResponseMsg(nsm_msg* responsePtr, size_t payloadLength) override
    {
        uint8_t cc = NSM_SUCCESS;
        uint16_t reason_code = ERR_NULL;
        uint16_t dataLen = 0;
        struct nsm_port_counter_data portTeleData = {};

        auto rc = decode_get_port_telemetry_counter_resp(
            responsePtr, payloadLength, &cc, &reason_code, &dataLen,
            &portTeleData);

        if (rc == NSM_SW_SUCCESS && cc == NSM_SUCCESS)
        {
            printPortTeleInfo(dataLen, &portTeleData);
        }
        else
        {
            std::cerr
                << "Response message error: decode_get_port_telemetry_resp fail "
                << "rc=" << rc << ", cc=" << (int)cc
                << ", reasonCode=" << (int)reason_code << "\n";
            return;
        }
        return;
    }

    void printPortTeleInfo(uint16_t dataLen,
                           const struct nsm_port_counter_data* portData)
    {
        if (portData == NULL)
        {
            std::cerr << "Failed to get port counter information" << std::endl;
            return;
        }

        ordered_json result;
        result["Port Number"] = portNumber;
        result["Data Length"] = dataLen;
        std::string key("Supported Counters");

        ordered_json countersResult;
        if (portData->supported_counter.port_rcv_pkts)
        {
            result[key].push_back(0);
            countersResult["Port Rcv Pkt"] =
                static_cast<uint64_t>(portData->port_rcv_pkts);
        }

        if (portData->supported_counter.port_rcv_data)
        {
            result[key].push_back(1);
            countersResult["Port Rcv Data"] =
                static_cast<uint64_t>(portData->port_rcv_data);
        }

        if (portData->supported_counter.port_multicast_rcv_pkts)
        {
            result[key].push_back(2);
            countersResult["Port Multicast Rcv Pkt"] =
                static_cast<uint64_t>(portData->port_multicast_rcv_pkts);
        }

        if (portData->supported_counter.port_unicast_rcv_pkts)
        {
            result[key].push_back(3);
            countersResult["Port Unicast Rcv Pkt"] =
                static_cast<uint64_t>(portData->port_unicast_rcv_pkts);
        }

        if (portData->supported_counter.port_malformed_pkts)
        {
            result[key].push_back(4);
            countersResult["Port Malformed Pkt"] =
                static_cast<uint64_t>(portData->port_malformed_pkts);
        }

        if (portData->supported_counter.vl15_dropped)
        {
            result[key].push_back(5);
            countersResult["Vl15 Dropped"] =
                static_cast<uint64_t>(portData->vl15_dropped);
        }

        if (portData->supported_counter.port_rcv_errors)
        {
            result[key].push_back(6);
            countersResult["Port Rcv Error"] =
                static_cast<uint64_t>(portData->port_rcv_errors);
        }

        if (portData->supported_counter.port_xmit_pkts)
        {
            result[key].push_back(7);
            countersResult["Port Tx Pkt"] =
                static_cast<uint64_t>(portData->port_xmit_pkts);
        }

        if (portData->supported_counter.port_xmit_pkts_vl15)
        {
            result[key].push_back(8);
            countersResult["Port Tx Pkt Vl15"] =
                static_cast<uint64_t>(portData->port_xmit_pkts_vl15);
        }

        if (portData->supported_counter.port_xmit_data)
        {
            result[key].push_back(9);
            countersResult["Port Tx Data"] =
                static_cast<uint64_t>(portData->port_xmit_data);
        }

        if (portData->supported_counter.port_xmit_data_vl15)
        {
            result[key].push_back(10);
            countersResult["Port Tx Data Vl15"] =
                static_cast<uint64_t>(portData->port_xmit_data_vl15);
        }

        if (portData->supported_counter.port_unicast_xmit_pkts)
        {
            result[key].push_back(11);
            countersResult["Port Unicast Tx Pkt"] =
                static_cast<uint64_t>(portData->port_unicast_xmit_pkts);
        }

        if (portData->supported_counter.port_multicast_xmit_pkts)
        {
            result[key].push_back(12);
            countersResult["Port Multicast Tx Pkt"] =
                static_cast<uint64_t>(portData->port_multicast_xmit_pkts);
        }

        if (portData->supported_counter.port_bcast_xmit_pkts)
        {
            result[key].push_back(13);
            countersResult["Port Broadcast Tx Pkt"] =
                static_cast<uint64_t>(portData->port_bcast_xmit_pkts);
        }

        if (portData->supported_counter.port_xmit_discard)
        {
            result[key].push_back(14);
            countersResult["Port Tx Discard"] =
                static_cast<uint64_t>(portData->port_xmit_discard);
        }

        if (portData->supported_counter.port_neighbor_mtu_discards)
        {
            result[key].push_back(15);
            countersResult["Port Neighbour MTU Discard"] =
                static_cast<uint64_t>(portData->port_neighbor_mtu_discards);
        }

        if (portData->supported_counter.port_rcv_ibg2_pkts)
        {
            result[key].push_back(16);
            countersResult["Port Rcv IBG2 Pkt"] =
                static_cast<uint64_t>(portData->port_rcv_ibg2_pkts);
        }

        if (portData->supported_counter.port_xmit_ibg2_pkts)
        {
            result[key].push_back(17);
            countersResult["Port Tx IBG2 Pkt"] =
                static_cast<uint64_t>(portData->port_xmit_ibg2_pkts);
        }

        if (portData->supported_counter.symbol_ber)
        {
            result[key].push_back(18);
            countersResult["Symbol BER"] =
                static_cast<uint64_t>(portData->symbol_ber);
        }

        if (portData->supported_counter.link_error_recovery_counter)
        {
            result[key].push_back(19);
            countersResult["Link Error Recovery Counter"] =
                static_cast<uint64_t>(portData->link_error_recovery_counter);
        }

        if (portData->supported_counter.link_downed_counter)
        {
            result[key].push_back(20);
            countersResult["Link Downed Counter"] =
                static_cast<uint64_t>(portData->link_downed_counter);
        }

        if (portData->supported_counter.port_rcv_remote_physical_errors)
        {
            result[key].push_back(21);
            countersResult["Port Rcv Remote Physical Error"] =
                static_cast<uint64_t>(
                    portData->port_rcv_remote_physical_errors);
        }

        if (portData->supported_counter.port_rcv_switch_relay_errors)
        {
            result[key].push_back(22);
            countersResult["Port Rcv Switch Relay Error"] =
                static_cast<uint64_t>(portData->port_rcv_switch_relay_errors);
        }

        if (portData->supported_counter.QP1_dropped)
        {
            result[key].push_back(23);
            countersResult["QP1 Dropped"] =
                static_cast<uint64_t>(portData->QP1_dropped);
        }

        if (portData->supported_counter.xmit_wait)
        {
            result[key].push_back(24);
            countersResult["Tx Wait"] =
                static_cast<uint64_t>(portData->xmit_wait);
        }

        if (portData->supported_counter.effective_ber)
        {
            result[key].push_back(25);
            countersResult["Effective BER"] =
                static_cast<uint64_t>(portData->effective_ber);
        }

        if (portData->supported_counter.total_raw_error)
        {
            result[key].push_back(26);
            countersResult["Total Raw Error"] =
                static_cast<uint64_t>(portData->total_raw_error);
        }

        if (portData->supported_counter.effective_error)
        {
            result[key].push_back(27);
            countersResult["Effective Error"] =
                static_cast<uint64_t>(portData->effective_error);
        }

        if (portData->supported_counter.symbol_error)
        {
            result[key].push_back(28);
            countersResult["Symbol Errors"] =
                static_cast<uint64_t>(portData->symbol_error);
        }

        if (portData->supported_counter.total_raw_ber)
        {
            result[key].push_back(29);
            countersResult["Total Raw BER"] =
                static_cast<uint64_t>(portData->total_raw_ber);
        }

        if (portData->supported_counter.unintentional_link_down_count)
        {
            result[key].push_back(31);
            countersResult["Unintentional Link Down Count"] =
                static_cast<uint64_t>(portData->unintentional_link_down_count);
        }

        if (portData->supported_counter.intentional_link_down_count)
        {
            result[key].push_back(32);
            countersResult["Intentional Link Down Count"] =
                static_cast<uint64_t>(portData->intentional_link_down_count);
        }
        result["Port Counter Information"] = countersResult;

        nsmtool::helper::DisplayInJson(result);
    }

  private:
    uint8_t portNumber;
};

class QueryPortCharacteristics : public CommandInterface
{
  public:
    ~QueryPortCharacteristics() = default;
    QueryPortCharacteristics() = delete;
    QueryPortCharacteristics(const QueryPortCharacteristics&) = delete;
    QueryPortCharacteristics(QueryPortCharacteristics&&) = default;
    QueryPortCharacteristics&
        operator=(const QueryPortCharacteristics&) = delete;
    QueryPortCharacteristics& operator=(QueryPortCharacteristics&&) = default;

    using CommandInterface::CommandInterface;

    explicit QueryPortCharacteristics(const char* type, const char* name,
                                      CLI::App* app) :
        CommandInterface(type, name, app)
    {
        auto portTeleOptionGroup = app->add_option_group(
            "Required",
            "Port number for which counter value is to be retrieved.");

        portNumber = 00;
        portTeleOptionGroup->add_option(
            "-p, --portNum", portNumber,
            "retrieve counter values for Port number");
        portTeleOptionGroup->require_option(1);
    }

    std::pair<int, std::vector<uint8_t>> createRequestMsg() override
    {
        std::vector<uint8_t> requestMsg(
            sizeof(nsm_msg_hdr) + sizeof(nsm_query_port_characteristics_req));
        auto request = reinterpret_cast<nsm_msg*>(requestMsg.data());
        auto rc = encode_query_port_characteristics_req(instanceId, portNumber,
                                                        request);
        return {rc, requestMsg};
    }

    void parseResponseMsg(nsm_msg* responsePtr, size_t payloadLength) override
    {
        uint8_t cc = NSM_SUCCESS;
        uint16_t reasonCode = ERR_NULL;
        uint16_t dataLen = 0;
        struct nsm_port_characteristics_data portCharData;

        auto rc = decode_query_port_characteristics_resp(
            responsePtr, payloadLength, &cc, &reasonCode, &dataLen,
            &portCharData);

        if (rc == NSM_SW_SUCCESS && cc == NSM_SUCCESS)
        {
            ordered_json result;
            result["Port Number"] = portNumber;
            result["Data Length"] = dataLen;
            result["Link State"] =
                static_cast<uint32_t>(portCharData.port_status.link_state);
            result["Sub Link State"] =
                static_cast<uint32_t>(portCharData.port_status.sub_link_state);
            result["RX Detect State"] =
                static_cast<uint32_t>(portCharData.port_status.rx_detect_state);
            result["Link Down Reason Code"] = static_cast<uint32_t>(
                portCharData.port_status.port_down_reason_code);
            result["NV Port Line Rate Mbps"] =
                static_cast<uint32_t>(portCharData.nv_port_line_rate_mbps);
            result["NV Port Data Rate Kbps"] =
                static_cast<uint32_t>(portCharData.nv_port_data_rate_kbps);
            result["Lane Info Status"] =
                static_cast<uint32_t>(portCharData.status_lane_info);
            nsmtool::helper::DisplayInJson(result);
        }
        else
        {
            std::cerr
                << "Response message error: decode_query_port_characteristics_resp fail "
                << "rc=" << rc << ", cc=" << (int)cc
                << ", reasonCode=" << (int)reasonCode << "\n";
            return;
        }
        return;
    }

  private:
    uint8_t portNumber;
};

class QueryPortStatus : public CommandInterface
{
  public:
    ~QueryPortStatus() = default;
    QueryPortStatus() = delete;
    QueryPortStatus(const QueryPortStatus&) = delete;
    QueryPortStatus(QueryPortStatus&&) = default;
    QueryPortStatus& operator=(const QueryPortStatus&) = delete;
    QueryPortStatus& operator=(QueryPortStatus&&) = default;

    using CommandInterface::CommandInterface;

    explicit QueryPortStatus(const char* type, const char* name,
                             CLI::App* app) : CommandInterface(type, name, app)
    {
        auto portStatusOptionGroup = app->add_option_group(
            "Required",
            "Port number for which counter value is to be retrieved.");

        portNumber = 00;
        portStatusOptionGroup->add_option(
            "-p, --portNum", portNumber,
            "retrieve counter values for Port number");
        portStatusOptionGroup->require_option(1);
    }

    std::pair<int, std::vector<uint8_t>> createRequestMsg() override
    {
        std::vector<uint8_t> requestMsg(sizeof(nsm_msg_hdr) +
                                        sizeof(nsm_query_port_status_req));
        auto request = reinterpret_cast<nsm_msg*>(requestMsg.data());
        auto rc = encode_query_port_status_req(instanceId, portNumber, request);
        return {rc, requestMsg};
    }

    void parseResponseMsg(nsm_msg* responsePtr, size_t payloadLength) override
    {
        uint8_t cc = NSM_SUCCESS;
        uint16_t reasonCode = ERR_NULL;
        uint16_t dataLen = 0;
        uint8_t portState = NSM_PORTSTATE_UP;
        uint8_t portStatus = NSM_PORTSTATUS_ENABLED;

        auto rc = decode_query_port_status_resp(responsePtr, payloadLength, &cc,
                                                &reasonCode, &dataLen,
                                                &portState, &portStatus);

        if (rc == NSM_SW_SUCCESS && cc == NSM_SUCCESS)
        {
            ordered_json result;
            result["Port Number"] = portNumber;
            result["Data Length"] = dataLen;
            result["Port State"] = portState;
            result["Port Status"] = portStatus;
            nsmtool::helper::DisplayInJson(result);
        }
        else
        {
            std::cerr
                << "Response message error: decode_query_port_status_resp fail "
                << "rc=" << rc << ", cc=" << (int)cc
                << ", reasonCode=" << (int)reasonCode << "\n";
            return;
        }
        return;
    }

  private:
    uint8_t portNumber;
};

class QueryPortsAvailable : public CommandInterface
{
  public:
    ~QueryPortsAvailable() = default;
    QueryPortsAvailable() = delete;
    QueryPortsAvailable(const QueryPortsAvailable&) = delete;
    QueryPortsAvailable(QueryPortsAvailable&&) = default;
    QueryPortsAvailable& operator=(const QueryPortsAvailable&) = delete;
    QueryPortsAvailable& operator=(QueryPortsAvailable&&) = default;

    using CommandInterface::CommandInterface;

    std::pair<int, std::vector<uint8_t>> createRequestMsg() override
    {
        std::vector<uint8_t> requestMsg(sizeof(nsm_msg_hdr) +
                                        sizeof(nsm_query_ports_available_req));
        auto request = reinterpret_cast<nsm_msg*>(requestMsg.data());
        auto rc = encode_query_ports_available_req(instanceId, request);
        return {rc, requestMsg};
    }

    void parseResponseMsg(nsm_msg* responsePtr, size_t payloadLength) override
    {
        uint8_t cc = NSM_SUCCESS;
        uint16_t reason_code = ERR_NULL;
        uint16_t dataLen = 0;
        uint8_t number_of_ports = 0;

        auto rc = decode_query_ports_available_resp(responsePtr, payloadLength,
                                                    &cc, &reason_code, &dataLen,
                                                    &number_of_ports);

        if (rc == NSM_SW_SUCCESS && cc == NSM_SUCCESS)
        {
            ordered_json result;
            result["Number of Ports"] = number_of_ports;
            nsmtool::helper::DisplayInJson(result);
        }
        else
        {
            std::cerr
                << "Response message error: decode_query_ports_available_resp fail"
                << "rc=" << rc << ", cc=" << (int)cc
                << ", reasonCode=" << (int)reason_code << "\n";
            return;
        }
        return;
    }
};

class SetPortDisableFuture : public CommandInterface
{
  public:
    ~SetPortDisableFuture() = default;
    SetPortDisableFuture() = delete;
    SetPortDisableFuture(const SetPortDisableFuture&) = delete;
    SetPortDisableFuture(SetPortDisableFuture&&) = default;
    SetPortDisableFuture& operator=(const SetPortDisableFuture&) = delete;
    SetPortDisableFuture& operator=(SetPortDisableFuture&&) = default;

    using CommandInterface::CommandInterface;

    explicit SetPortDisableFuture(const char* type, const char* name,
                                  CLI::App* app) :
        CommandInterface(type, name, app)
    {
        auto setPortDisableFutureOptionGroup =
            app->add_option_group("Required", "Port mask [32 bytes].");

        portMask = {};
        setPortDisableFutureOptionGroup->add_option(
            "-p, --portMask", portMask, "Port mask from next reset");
        setPortDisableFutureOptionGroup->require_option(1);
    }

    std::pair<int, std::vector<uint8_t>> createRequestMsg() override
    {
        std::vector<uint8_t> requestMsg(
            sizeof(nsm_msg_hdr) + sizeof(nsm_set_port_disable_future_req));
        auto request = reinterpret_cast<nsm_msg*>(requestMsg.data());
        std::vector<bitfield8_t> portMaskBitfield;
        for (const auto& value : portMask)
        {
            portMaskBitfield.emplace_back(value);
        }
        auto rc = encode_set_port_disable_future_req(
            instanceId, portMaskBitfield.data(), request);
        return {rc, requestMsg};
    }

    void parseResponseMsg(nsm_msg* responsePtr, size_t payloadLength) override
    {
        uint8_t cc = NSM_SUCCESS;
        uint16_t reason_code = ERR_NULL;

        auto rc = decode_set_port_disable_future_resp(
            responsePtr, payloadLength, &cc, &reason_code);

        if (rc == NSM_SW_SUCCESS && cc == NSM_SUCCESS)
        {
            ordered_json result;
            result["Completion Code"] = cc;
            nsmtool::helper::DisplayInJson(result);
        }
        else
        {
            std::cerr
                << "Response message error: decode_query_ports_available_resp fail"
                << "rc=" << rc << ", cc=" << (int)cc
                << ", reasonCode=" << (int)reason_code << "\n";
            return;
        }
        return;
    }

  private:
    std::vector<uint8_t> portMask;
};

class GetFabricManagerState : public CommandInterface
{
  public:
    ~GetFabricManagerState() = default;
    GetFabricManagerState() = delete;
    GetFabricManagerState(const GetFabricManagerState&) = delete;
    GetFabricManagerState(GetFabricManagerState&&) = default;
    GetFabricManagerState& operator=(const GetFabricManagerState&) = delete;
    GetFabricManagerState& operator=(GetFabricManagerState&&) = default;

    using CommandInterface::CommandInterface;

    std::pair<int, std::vector<uint8_t>> createRequestMsg() override
    {
        std::vector<uint8_t> requestMsg(
            sizeof(nsm_msg_hdr) + sizeof(nsm_get_fabric_manager_state_req));
        auto request = reinterpret_cast<nsm_msg*>(requestMsg.data());
        auto rc = encode_get_fabric_manager_state_req(instanceId, request);
        return {rc, requestMsg};
    }

    void parseResponseMsg(nsm_msg* responsePtr, size_t payloadLength) override
    {
        uint8_t cc = NSM_SUCCESS;
        uint16_t reason_code = ERR_NULL;
        uint16_t dataLen = 0;
        struct nsm_fabric_manager_state_data fmStateData;

        auto rc = decode_get_fabric_manager_state_resp(
            responsePtr, payloadLength, &cc, &reason_code, &dataLen,
            &fmStateData);

        if (rc == NSM_SW_SUCCESS && cc == NSM_SUCCESS)
        {
            ordered_json result;
            result["FM State"] = fmStateData.fm_state;
            result["Report Status"] = fmStateData.report_status;
            result["Last Restart Timestamp (Epoch time in Sec)"] =
                static_cast<uint64_t>(fmStateData.last_restart_timestamp);
            result["Duration Since Last Restart (Sec)"] = static_cast<uint64_t>(
                fmStateData.duration_since_last_restart_sec);
            nsmtool::helper::DisplayInJson(result);
        }
        else
        {
            std::cerr
                << "Response message error: decode_get_fabric_manager_state_resp fail"
                << " rc=" << rc << ", cc=" << (int)cc
                << ", reasonCode=" << (int)reason_code << "\n";
            return;
        }
        return;
    }
};

class GetPortDisableFuture : public CommandInterface
{
  public:
    ~GetPortDisableFuture() = default;
    GetPortDisableFuture() = delete;
    GetPortDisableFuture(const GetPortDisableFuture&) = delete;
    GetPortDisableFuture(GetPortDisableFuture&&) = default;
    GetPortDisableFuture& operator=(const GetPortDisableFuture&) = delete;
    GetPortDisableFuture& operator=(GetPortDisableFuture&&) = default;

    using CommandInterface::CommandInterface;

    std::pair<int, std::vector<uint8_t>> createRequestMsg() override
    {
        std::vector<uint8_t> requestMsg(
            sizeof(nsm_msg_hdr) + sizeof(nsm_get_port_disable_future_req));
        auto request = reinterpret_cast<nsm_msg*>(requestMsg.data());
        auto rc = encode_get_port_disable_future_req(instanceId, request);
        return {rc, requestMsg};
    }

    void parseResponseMsg(nsm_msg* responsePtr, size_t payloadLength) override
    {
        uint8_t cc = NSM_SUCCESS;
        uint16_t reason_code = ERR_NULL;
        bitfield8_t portMask[PORT_MASK_DATA_SIZE];

        auto rc = decode_get_port_disable_future_resp(
            responsePtr, payloadLength, &cc, &reason_code, &portMask[0]);

        if (rc == NSM_SW_SUCCESS && cc == NSM_SUCCESS)
        {
            ordered_json result;
            result["Completion Code"] = cc;
            std::string key("Port Mask Disable Future");

            parseBitfieldVar(result, key, &portMask[0], PORT_MASK_DATA_SIZE);
            nsmtool::helper::DisplayInJson(result);
        }
        else
        {
            std::cerr
                << "Response message error: decode_get_port_disable_future_resp fail"
                << "rc=" << rc << ", cc=" << (int)cc
                << ", reasonCode=" << (int)reason_code << "\n";
            return;
        }
        return;
    }
};

class GetPowerMode : public CommandInterface
{
  public:
    ~GetPowerMode() = default;
    GetPowerMode() = delete;
    GetPowerMode(const GetPowerMode&) = delete;
    GetPowerMode(GetPowerMode&&) = default;
    GetPowerMode& operator=(const GetPowerMode&) = delete;
    GetPowerMode& operator=(GetPowerMode&&) = default;

    using CommandInterface::CommandInterface;

    std::pair<int, std::vector<uint8_t>> createRequestMsg() override
    {
        std::vector<uint8_t> requestMsg(sizeof(nsm_msg_hdr) +
                                        sizeof(nsm_get_power_mode_req));
        auto request = reinterpret_cast<nsm_msg*>(requestMsg.data());
        auto rc = encode_get_power_mode_req(instanceId, request);
        return {rc, requestMsg};
    }

    void parseResponseMsg(nsm_msg* responsePtr, size_t payloadLength) override
    {
        uint8_t cc = NSM_SUCCESS;
        uint16_t reasonCode = ERR_NULL;
        uint16_t dataLen = 0;
        struct nsm_power_mode_data powerModeData;

        auto rc = decode_get_power_mode_resp(responsePtr, payloadLength, &cc,
                                             &reasonCode, &dataLen,
                                             &powerModeData);

        if (rc == NSM_SW_SUCCESS && cc == NSM_SUCCESS)
        {
            ordered_json result;
            result["Completion Code"] = cc;
            result["Data Length"] = dataLen;
            result["L1 HW Mode Control"] =
                static_cast<uint8_t>(powerModeData.l1_hw_mode_control);
            result["L1 HW Mode Threshold"] =
                static_cast<uint32_t>(powerModeData.l1_hw_mode_threshold);
            result["L1 FW Throttling Mode"] =
                static_cast<uint8_t>(powerModeData.l1_fw_throttling_mode);
            result["L1 Prediction Mode"] =
                static_cast<uint8_t>(powerModeData.l1_prediction_mode);
            result["L1 HW Active Time"] =
                static_cast<uint16_t>(powerModeData.l1_hw_active_time);
            result["L1 HW Inactive Time"] =
                static_cast<uint16_t>(powerModeData.l1_hw_inactive_time);
            result["L1 Prediction Inactive Time"] = static_cast<uint16_t>(
                powerModeData.l1_prediction_inactive_time);
            nsmtool::helper::DisplayInJson(result);
        }
        else
        {
            std::cerr
                << "Response message error: decode_get_power_mode_resp fail "
                << "rc=" << rc << ", cc=" << (int)cc
                << ", reasonCode=" << (int)reasonCode << "\n";
            return;
        }
        return;
    }
};

class SetPowerMode : public CommandInterface
{
  public:
    ~SetPowerMode() = default;
    SetPowerMode() = delete;
    SetPowerMode(const SetPowerMode&) = delete;
    SetPowerMode(SetPowerMode&&) = default;
    SetPowerMode& operator=(const SetPowerMode&) = delete;
    SetPowerMode& operator=(SetPowerMode&&) = default;

    using CommandInterface::CommandInterface;

    explicit SetPowerMode(const char* type, const char* name, CLI::App* app) :
        CommandInterface(type, name, app)
    {
        auto powerModeOptionGroup = app->add_option_group(
            "Required",
            "Port number for which counter value is to be retrieved.");

        l1HWModeControl = false;
        l1HWThreshold = 0;
        l1FWThrottlingMode = false;
        l1PredictionMode = false;
        l1HWActiveTime = 0;
        l1HWInactiveTime = 0;
        l1HWPredictionInactiveTime = 0;

        powerModeOptionGroup->add_option("-C, --modeControl", l1HWModeControl,
                                         "L1 hardware control mode");

        powerModeOptionGroup->add_option("-T, --modeThrottle",
                                         l1FWThrottlingMode,
                                         "L1 firmware throttling mode");

        powerModeOptionGroup->add_option("-P, --modePrediction",
                                         l1PredictionMode,
                                         "L1 prediction mechanism mode");

        powerModeOptionGroup->add_option("-t, --threshold", l1HWThreshold,
                                         "L1 state threshold bytes");

        powerModeOptionGroup->add_option("-a, --activeTime", l1HWActiveTime,
                                         "L1 state active time");

        powerModeOptionGroup->add_option("-i, --inactiveTime", l1HWInactiveTime,
                                         "L1 state inactive time");

        powerModeOptionGroup->add_option("-p, --predictionInactiveTime",
                                         l1HWPredictionInactiveTime,
                                         "L1 state prediction inactive time");

        powerModeOptionGroup->require_option(7);
    }

    std::pair<int, std::vector<uint8_t>> createRequestMsg() override
    {
        struct nsm_power_mode_data powerModeData;
        powerModeData.l1_hw_mode_control = l1HWModeControl;
        powerModeData.l1_hw_mode_threshold = l1HWThreshold;
        powerModeData.l1_fw_throttling_mode = l1FWThrottlingMode;
        powerModeData.l1_prediction_mode = l1PredictionMode;
        powerModeData.l1_hw_active_time = l1HWActiveTime;
        powerModeData.l1_hw_inactive_time = l1HWInactiveTime;
        powerModeData.l1_prediction_inactive_time = l1HWPredictionInactiveTime;

        std::vector<uint8_t> requestMsg(sizeof(nsm_msg_hdr) +
                                        sizeof(nsm_set_power_mode_req));
        auto request = reinterpret_cast<nsm_msg*>(requestMsg.data());
        auto rc = encode_set_power_mode_req(instanceId, request, powerModeData);
        return {rc, requestMsg};
    }

    void parseResponseMsg(nsm_msg* responsePtr, size_t payloadLength) override
    {
        uint8_t cc = NSM_SUCCESS;
        uint16_t reasonCode = ERR_NULL;

        auto rc = decode_set_power_mode_resp(responsePtr, payloadLength, &cc,
                                             &reasonCode);

        if (rc == NSM_SW_SUCCESS && cc == NSM_SUCCESS)
        {
            ordered_json result;
            result["Completion Code"] = cc;
            nsmtool::helper::DisplayInJson(result);
        }
        else
        {
            std::cerr
                << "Response message error: decode_set_power_mode_resp fail "
                << "rc=" << rc << ", cc=" << (int)cc
                << ", reasonCode=" << (int)reasonCode << "\n";
            return;
        }
        return;
    }

  private:
    bool l1HWModeControl;
    uint32_t l1HWThreshold;
    bool l1FWThrottlingMode;
    bool l1PredictionMode;
    uint16_t l1HWActiveTime;
    uint16_t l1HWInactiveTime;
    uint16_t l1HWPredictionInactiveTime;
};

class GetSwitchIsolationMode : public CommandInterface
{
  public:
    ~GetSwitchIsolationMode() = default;
    GetSwitchIsolationMode() = delete;
    GetSwitchIsolationMode(const GetSwitchIsolationMode&) = delete;
    GetSwitchIsolationMode(GetSwitchIsolationMode&&) = default;
    GetSwitchIsolationMode& operator=(const GetSwitchIsolationMode&) = delete;
    GetSwitchIsolationMode& operator=(GetSwitchIsolationMode&&) = default;

    using CommandInterface::CommandInterface;

    std::pair<int, std::vector<uint8_t>> createRequestMsg() override
    {
        std::vector<uint8_t> requestMsg(sizeof(nsm_msg_hdr) +
                                        sizeof(nsm_common_req));
        auto request = reinterpret_cast<nsm_msg*>(requestMsg.data());
        auto rc = encode_get_switch_isolation_mode_req(instanceId, request);
        return {rc, requestMsg};
    }

    void parseResponseMsg(nsm_msg* responsePtr, size_t payloadLength) override
    {
        uint8_t cc = NSM_SUCCESS;
        uint16_t reasonCode = ERR_NULL;
        uint8_t isolationMode;

        auto rc = decode_get_switch_isolation_mode_resp(
            responsePtr, payloadLength, &cc, &reasonCode, &isolationMode);

        if (rc == NSM_SW_SUCCESS && cc == NSM_SUCCESS)
        {
            ordered_json result;
            result["Completion Code"] = cc;
            result["Isolation Mode"] = isolationMode;
            nsmtool::helper::DisplayInJson(result);
        }
        else
        {
            std::cerr
                << "Response message error: decode_get_switch_isolation_mode_resp "
                << "rc=" << rc << ", cc=" << (int)cc
                << ", reasonCode=" << (int)reasonCode << "\n";
            return;
        }
        return;
    }
};

class SetSwitchIsolationMode : public CommandInterface
{
  public:
    ~SetSwitchIsolationMode() = default;
    SetSwitchIsolationMode() = delete;
    SetSwitchIsolationMode(const SetSwitchIsolationMode&) = delete;
    SetSwitchIsolationMode(SetSwitchIsolationMode&&) = default;
    SetSwitchIsolationMode& operator=(const SetSwitchIsolationMode&) = delete;
    SetSwitchIsolationMode& operator=(SetSwitchIsolationMode&&) = default;

    using CommandInterface::CommandInterface;

    explicit SetSwitchIsolationMode(const char* type, const char* name,
                                    CLI::App* app) :
        CommandInterface(type, name, app)
    {
        auto requestedMode = app->add_option_group(
            "Required",
            "Requested Switch Isolation Mode 0(Enabled)/1(Disabled)");

        requestedMode->add_option("-i, --isolation_mode", isolation_mode,
                                  "Isolation Mode of Switch");

        requestedMode->require_option(1);
    }

    std::pair<int, std::vector<uint8_t>> createRequestMsg() override
    {
        std::vector<uint8_t> requestMsg(sizeof(nsm_msg_hdr) +
                                        sizeof(nsm_set_MIG_mode_req));
        auto request = reinterpret_cast<nsm_msg*>(requestMsg.data());
        auto rc = encode_set_switch_isolation_mode_req(instanceId,
                                                       isolation_mode, request);
        return {rc, requestMsg};
    }

    void parseResponseMsg(nsm_msg* responsePtr, size_t payloadLength) override
    {
        uint8_t cc = NSM_ERROR;
        uint16_t reason_code = ERR_NULL;
        auto rc = decode_set_switch_isolation_mode_resp(
            responsePtr, payloadLength, &cc, &reason_code);
        if (rc != NSM_SW_SUCCESS || cc != NSM_SUCCESS)
        {
            std::cerr << "Response message error: "
                      << "rc=" << rc << ", cc=" << (int)cc
                      << ", reasonCode=" << (int)reason_code << "\n"
                      << payloadLength << "...."
                      << (sizeof(struct nsm_msg_hdr) +
                          sizeof(struct nsm_common_resp));
            return;
        }

        ordered_json result;
        result["Completion Code"] = cc;
        nsmtool::helper::DisplayInJson(result);
    }

    uint8_t isolation_mode;
};

class GetInventoryInformation : public CommandInterface
{
  public:
    ~GetInventoryInformation() = default;
    GetInventoryInformation() = delete;
    GetInventoryInformation(const GetInventoryInformation&) = delete;
    GetInventoryInformation(GetInventoryInformation&&) = default;
    GetInventoryInformation& operator=(const GetInventoryInformation&) = delete;
    GetInventoryInformation& operator=(GetInventoryInformation&&) = default;

    using CommandInterface::CommandInterface;

    explicit GetInventoryInformation(const char* type, const char* name,
                                     CLI::App* app) :
        CommandInterface(type, name, app)
    {
        auto getInventoryInformationOptionGroup = app->add_option_group(
            "Required",
            "Property Id for which Inventory Information is to be retrieved.");

        propertyId = 0;
        getInventoryInformationOptionGroup->add_option(
            "-p, --propertyId", propertyId,
            "retrieve inventory information for propertyId");
        getInventoryInformationOptionGroup->require_option(1);
    }

    std::pair<int, std::vector<uint8_t>> createRequestMsg() override
    {
        std::vector<uint8_t> requestMsg(
            sizeof(nsm_msg_hdr) + sizeof(nsm_get_inventory_information_req));
        auto request = reinterpret_cast<nsm_msg*>(requestMsg.data());
        auto rc = encode_get_inventory_information_req(instanceId, propertyId,
                                                       request);
        return {rc, requestMsg};
    }

    void parseResponseMsg(nsm_msg* responsePtr, size_t payloadLength) override
    {
        uint8_t cc = NSM_SUCCESS;
        uint16_t reason_code = ERR_NULL;
        uint16_t dataSize = 0;
        std::vector<uint8_t> data(65535, 0);

        auto rc = decode_get_inventory_information_resp(
            responsePtr, payloadLength, &cc, &reason_code, &dataSize,
            data.data());
        if (rc != NSM_SW_SUCCESS || cc != NSM_SUCCESS)
        {
            std::cerr << "Response message error: "
                      << "rc=" << rc << ", cc=" << (int)cc
                      << ", reasonCode=" << (int)reason_code << "\n";
            return;
        }

        printInventoryInfo(propertyId, dataSize, data);
    }

    void printInventoryInfo(uint8_t& propertyIdentifier,
                            const uint16_t dataSize,
                            const std::vector<uint8_t>& data)
    {
        ordered_json result;
        ordered_json propRecordResult;
        propRecordResult["Property ID"] = propertyIdentifier;
        propRecordResult["Data Length"] = static_cast<uint16_t>(dataSize);
        std::stringstream iss;
        std::string firmwareVersion;

        std::unordered_map<uint8_t, uint16_t> inventoryLengthMap = {
            // identifier, expected length
            {MAXIMUM_MEMORY_CAPACITY, sizeof(uint32_t)},
            {PRODUCT_LENGTH, sizeof(uint32_t)},
            {PRODUCT_WIDTH, sizeof(uint32_t)},
            {PRODUCT_HEIGHT, sizeof(uint32_t)},
            {RATED_DEVICE_POWER_LIMIT, sizeof(uint32_t)},
            {MINIMUM_DEVICE_POWER_LIMIT, sizeof(uint32_t)},
            {MAXIMUM_DEVICE_POWER_LIMIT, sizeof(uint32_t)},
            {MINIMUM_MODULE_POWER_LIMIT, sizeof(uint32_t)},
            {MAXIMUM_MODULE_POWER_LIMIT, sizeof(uint32_t)},
            {RATED_MODULE_POWER_LIMIT, sizeof(uint32_t)},
            {DEFAULT_BOOST_CLOCKS, sizeof(uint32_t)},
            {DEFAULT_BASE_CLOCKS, sizeof(uint32_t)},
            {TRAY_SLOT_NUMBER, sizeof(uint32_t)},
            {TRAY_SLOT_INDEX, sizeof(uint32_t)},
            {GPU_HOST_ID, sizeof(uint32_t)},
            {GPU_MODULE_ID, sizeof(uint32_t)},
            {DEVICE_GUID, UUID_INT_SIZE},
            {GPU_NVLINK_PEER_TYPE, sizeof(uint32_t)},
            {GPU_IBGUID, sizeof(uint64_t)},
            {MINIMUM_MEMORY_CLOCK_LIMIT, sizeof(uint32_t)},
            {MAXIMUM_MEMORY_CLOCK_LIMIT, sizeof(uint32_t)},
            {MINIMUM_GRAPHICS_CLOCK_LIMIT, sizeof(uint32_t)},
            {MAXIMUM_GRAPHICS_CLOCK_LIMIT, sizeof(uint32_t)},
            {MINIMUM_EDPP_SCALING_FACTOR, sizeof(uint8_t)},
            {MAXIMUM_EDPP_SCALING_FACTOR, sizeof(uint8_t)},
            {PCIERETIMER_0_EEPROM_VERSION, sizeof(uint64_t)},
            {PCIERETIMER_1_EEPROM_VERSION, sizeof(uint64_t)},
            {PCIERETIMER_2_EEPROM_VERSION, sizeof(uint64_t)},
            {PCIERETIMER_3_EEPROM_VERSION, sizeof(uint64_t)},
            {PCIERETIMER_4_EEPROM_VERSION, sizeof(uint64_t)},
            {PCIERETIMER_5_EEPROM_VERSION, sizeof(uint64_t)},
            {PCIERETIMER_6_EEPROM_VERSION, sizeof(uint64_t)},
            {PCIERETIMER_7_EEPROM_VERSION, sizeof(uint64_t)}};

        if (inventoryLengthMap.contains(propertyIdentifier))
        {
            // help do length check
            if (inventoryLengthMap[propertyIdentifier] != dataSize)
            {
                std::cerr << "the response length was unexpected. expected: "
                          << inventoryLengthMap[propertyIdentifier]
                          << ", but got: " << dataSize << std::endl;
                return;
            }
        }

        // todo: display aggregate data
        switch (propertyIdentifier)
        {
            case MAXIMUM_MEMORY_CAPACITY:
            case PRODUCT_LENGTH:
            case PRODUCT_WIDTH:
            case PRODUCT_HEIGHT:
            case RATED_DEVICE_POWER_LIMIT:
            case MINIMUM_DEVICE_POWER_LIMIT:
            case MAXIMUM_DEVICE_POWER_LIMIT:
            case MINIMUM_MODULE_POWER_LIMIT:
                propRecordResult["Data"] = le32toh(*(uint32_t*)data.data());
                break;
            case MAXIMUM_MODULE_POWER_LIMIT:
                propRecordResult["Data"] = le32toh(*(uint32_t*)data.data());
                break;
            case RATED_MODULE_POWER_LIMIT:
            case DEFAULT_BOOST_CLOCKS:
            case DEFAULT_BASE_CLOCKS:
            case TRAY_SLOT_NUMBER:
            case TRAY_SLOT_INDEX:
                propRecordResult["Data"] = le32toh(*(uint32_t*)data.data());
                break;
            case GPU_HOST_ID:
            case GPU_MODULE_ID:
                propRecordResult["Data"] = le32toh(*(uint32_t*)data.data()) + 1;
                break;
            case BOARD_PART_NUMBER:
            case SERIAL_NUMBER:
            case MARKETING_NAME:
            case DEVICE_PART_NUMBER:
            case FRU_PART_NUMBER:
            case MEMORY_VENDOR:
            case MEMORY_PART_NUMBER:
            case BUILD_DATE:
            case FIRMWARE_VERSION:
            case INFO_ROM_VERSION:
            case FPGA_FIRMWARE_VERSION:
            case ASSET_TAG:
                propRecordResult["Data"] = std::string((char*)data.data(),
                                                       dataSize);
                break;
            case DEVICE_GUID:
            {
                std::vector<uint8_t> nvu8ArrVal(UUID_INT_SIZE, 0);
                memcpy(nvu8ArrVal.data(), data.data(), dataSize);
                propRecordResult["Data"] =
                    utils::convertUUIDToString(nvu8ArrVal);
                break;
            }
            case GPU_NVLINK_PEER_TYPE:
            {
                auto peerTypeNvU32 = le32toh(*(uint32_t*)data.data());
                if (peerTypeNvU32 == NSM_PEER_TYPE_DIRECT)
                {
                    propRecordResult["Data"] = std::string("Direct");
                }
                else
                {
                    propRecordResult["Data"] = std::string("Bridge");
                }
                break;
            }
            case CHASSIS_SERIAL_NUMBER:
            {
                propRecordResult["Data"] = std::string(
                    std::bit_cast<const char*>(data.data()), dataSize);
                break;
            }
            case GPU_IBGUID:
                propRecordResult["Data"] = utils::convertHexToString(data,
                                                                     dataSize);
                break;
            case MINIMUM_MEMORY_CLOCK_LIMIT:
                propRecordResult["Data"] = le32toh(*(uint32_t*)data.data());
                break;
            case MAXIMUM_MEMORY_CLOCK_LIMIT:
                propRecordResult["Data"] = le32toh(*(uint32_t*)data.data());
                break;
            case MINIMUM_GRAPHICS_CLOCK_LIMIT:
                propRecordResult["Data"] = le32toh(*(uint32_t*)data.data());
                break;
            case MAXIMUM_GRAPHICS_CLOCK_LIMIT:
                propRecordResult["Data"] = le32toh(*(uint32_t*)data.data());
                break;
            case MINIMUM_EDPP_SCALING_FACTOR:
                propRecordResult["Data"] = *(uint8_t*)data.data();
                break;
            case MAXIMUM_EDPP_SCALING_FACTOR:
                propRecordResult["Data"] = *(uint8_t*)data.data();
                break;
            case PCIERETIMER_0_EEPROM_VERSION:
            case PCIERETIMER_1_EEPROM_VERSION:
            case PCIERETIMER_2_EEPROM_VERSION:
            case PCIERETIMER_3_EEPROM_VERSION:
            case PCIERETIMER_4_EEPROM_VERSION:
            case PCIERETIMER_5_EEPROM_VERSION:
            case PCIERETIMER_6_EEPROM_VERSION:
            case PCIERETIMER_7_EEPROM_VERSION:
                iss << int(data[0]);        // Major version number
                iss << '.' << int(data[2]); // Minor version number
                iss << '.' << int((data[4] << 8) | data[6]); // Patch number

                firmwareVersion = iss.str();
                propRecordResult["Data"] = firmwareVersion;
                break;
            default:
                std::cerr
                    << "Incorrect data type recieved in get inventory information"
                    << std::endl;
                return;
        }

        result["Inventory Information"] = propRecordResult;
        nsmtool::helper::DisplayInJson(result);
    }

  private:
    uint8_t propertyId;
};

class GetDriverInfo : public CommandInterface
{
  public:
    ~GetDriverInfo() = default;
    GetDriverInfo() = delete;
    GetDriverInfo(const GetDriverInfo&) = delete;
    GetDriverInfo(GetDriverInfo&&) = default;
    GetDriverInfo& operator=(const GetDriverInfo&) = delete;
    GetDriverInfo& operator=(GetDriverInfo&&) = default;

    using CommandInterface::CommandInterface;

    std::pair<int, std::vector<uint8_t>> createRequestMsg() override
    {
        std::vector<uint8_t> requestMsg(sizeof(nsm_msg_hdr) +
                                        sizeof(nsm_common_req));
        auto request = reinterpret_cast<nsm_msg*>(requestMsg.data());
        auto rc = encode_get_driver_info_req(instanceId, request);
        return {rc, requestMsg};
    }

    void parseResponseMsg(nsm_msg* responsePtr, size_t payloadLength) override
    {
        uint8_t cc = NSM_ERROR;
        uint16_t reasonCode = ERR_NULL;
        enum8 driverState = 0;
        char driverVersion[MAX_VERSION_STRING_SIZE] = {0};

        auto rc = decode_get_driver_info_resp(responsePtr, payloadLength, &cc,
                                              &reasonCode, &driverState,
                                              driverVersion);

        std::string version(driverVersion);

        if (rc != NSM_SW_SUCCESS || cc != NSM_SUCCESS)
        {
            std::cerr << "Response message error: "
                      << "rc=" << rc << ", cc=" << static_cast<int>(cc)
                      << ", reasonCode=" << static_cast<int>(reasonCode) << "\n"
                      << payloadLength << "...."
                      << (sizeof(struct nsm_msg_hdr) + sizeof(driverState) +
                          version.length());
            return;
        }

        ordered_json result;
        result["Completion Code"] = cc;
        result["Driver State"] = static_cast<int>(driverState);
        result["Driver Version"] = version;
        nsmtool::helper::DisplayInJson(result);
    }
};

class AggregateResponseParser
{
  private:
    virtual int handleSampleData(uint8_t tag, const uint8_t* data,
                                 size_t data_len,
                                 ordered_json& sample_json) = 0;

  public:
    virtual ~AggregateResponseParser() = default;

    void parseAggregateResponse(nsm_msg* responsePtr, size_t payloadLength)
    {
        uint8_t cc{};
        uint16_t telemetry_count{};
        size_t consumed_len{};
        size_t msg_len = payloadLength + sizeof(nsm_msg_hdr);
        auto response_data = reinterpret_cast<const uint8_t*>(responsePtr);

        auto rc = decode_aggregate_resp(responsePtr, msg_len, &consumed_len,
                                        &cc, &telemetry_count);

        if (rc != NSM_SW_SUCCESS)
        {
            std::cerr << "Response message error: "
                      << "rc=" << rc << ", cc=" << (int)cc << "\n";

            return;
        }

        ordered_json result;
        result["Completion Code"] = cc;
        result["Sample Count"] = telemetry_count;

        uint64_t timestamp{};
        constexpr size_t time_size{100};
        char time[time_size];
        bool has_timestamp{false};

        std::vector<ordered_json> samples;
        while (telemetry_count--)
        {
            uint8_t tag{};
            bool valid;
            const uint8_t* data;
            size_t data_len;

            msg_len -= consumed_len;

            response_data += consumed_len;

            auto sample = reinterpret_cast<const nsm_aggregate_resp_sample*>(
                response_data);

            rc = decode_aggregate_resp_sample(sample, msg_len, &consumed_len,
                                              &tag, &valid, &data, &data_len);

            if (rc != NSM_SW_SUCCESS || !valid)
            {
                std::cerr
                    << "Response message error while parsing sample header: "
                    << "tag=" << static_cast<int>(tag) << ", rc=" << rc << "\n";

                continue;
            }

            if (tag == 0xFF)
            {
                if (data_len != 8)
                {
                    std::cerr
                        << "Response message error while parsing timestamp sample : "
                        << "tag=" << static_cast<int>(tag) << ", rc=" << rc
                        << "\n";

                    continue;
                }

                rc = decode_aggregate_timestamp_data(data, data_len,
                                                     &timestamp);
                if (rc != NSM_SW_SUCCESS)
                {
                    std::cerr
                        << "Response message error while parsing timestamp sample data : "
                        << "tag=" << static_cast<int>(tag) << ", rc=" << rc
                        << "\n";

                    continue;
                }

                has_timestamp = true;
                auto stime = static_cast<std::time_t>(timestamp);
                std::strftime(time, time_size, "%F %T %Z",
                              std::localtime(&stime));
            }
            else if (tag < 0xF0)
            {
                ordered_json sample_json;

                rc = handleSampleData(tag, data, data_len, sample_json);

                if (rc != NSM_SW_SUCCESS)
                {
                    std::cerr
                        << "Response message error while parsing sample data: "
                        << "tag=" << static_cast<int>(tag) << ", rc=" << rc
                        << "\n";

                    continue;
                }

                if (has_timestamp)
                {
                    sample_json["Timestamp"] = time;
                }

                samples.push_back(std::move(sample_json));
            }
        }

        result["Samples"] = std::move(samples);
        nsmtool::helper::DisplayInJson(result);
    }
};

class GetTemperatureReading : public CommandInterface
{
  public:
    ~GetTemperatureReading() = default;
    GetTemperatureReading() = delete;
    GetTemperatureReading(const GetTemperatureReading&) = delete;
    GetTemperatureReading(GetTemperatureReading&&) = default;
    GetTemperatureReading& operator=(const GetTemperatureReading&) = delete;
    GetTemperatureReading& operator=(GetTemperatureReading&&) = delete;

    using CommandInterface::CommandInterface;

    explicit GetTemperatureReading(const char* type, const char* name,
                                   CLI::App* app) :
        CommandInterface(type, name, app)
    {
        app->add_option("-s, --sensorId", sensorId, "sensor Id")->required();
    }

  private:
    void parseRegularResponse(nsm_msg* responsePtr, size_t payloadLength)
    {
        uint8_t cc = NSM_SUCCESS;
        uint16_t reason_code = ERR_NULL;
        double temperatureReading = 0;

        auto rc = decode_get_temperature_reading_resp(
            responsePtr, payloadLength, &cc, &reason_code, &temperatureReading);
        if (rc != NSM_SW_SUCCESS || cc != NSM_SUCCESS)
        {
            std::cerr << "Response message error: "
                      << "rc=" << rc << ", cc=" << (int)cc
                      << ", reasonCode=" << (int)reason_code << "\n"
                      << payloadLength << "...."
                      << (sizeof(struct nsm_msg_hdr) +
                          sizeof(struct nsm_get_temperature_reading_resp));
            return;
        }

        ordered_json result;
        result["Completion Code"] = cc;
        result["Sensor Id"] = sensorId;
        result["Temperature Reading"] = temperatureReading;
        nsmtool::helper::DisplayInJson(result);
    }

    class GetTemperatureAggregateResponseParser : public AggregateResponseParser
    {
      private:
        int handleSampleData(uint8_t tag, const uint8_t* data, size_t data_len,
                             ordered_json& sample_json) final
        {
            double reading{};
            auto rc = decode_aggregate_temperature_reading_data(data, data_len,
                                                                &reading);

            if (rc == NSM_SUCCESS)
            {
                sample_json["Sensor Id"] = tag;
                sample_json["Temperature Reading"] = reading;
            }

            return rc;
        }
    };

  public:
    std::pair<int, std::vector<uint8_t>> createRequestMsg() override
    {
        std::vector<uint8_t> requestMsg(
            sizeof(nsm_msg_hdr) + sizeof(nsm_get_temperature_reading_req));
        auto request = reinterpret_cast<nsm_msg*>(requestMsg.data());
        auto rc = encode_get_temperature_reading_req(instanceId, sensorId,
                                                     request);
        return {rc, requestMsg};
    }

    void parseResponseMsg(nsm_msg* responsePtr, size_t payloadLength) override
    {
        if (sensorId == AggregateSensorId)
        {
            GetTemperatureAggregateResponseParser{}.parseAggregateResponse(
                responsePtr, payloadLength);
        }
        else
        {
            parseRegularResponse(responsePtr, payloadLength);
        }
    }

  private:
    uint8_t sensorId;
    static constexpr uint8_t AggregateSensorId{255};
};

class ReadThermalParameter : public CommandInterface
{
  public:
    ReadThermalParameter() = delete;
    ReadThermalParameter(const ReadThermalParameter&) = delete;
    ReadThermalParameter(ReadThermalParameter&&) = default;
    ReadThermalParameter& operator=(const ReadThermalParameter&) = delete;
    ReadThermalParameter& operator=(ReadThermalParameter&&) = delete;

    explicit ReadThermalParameter(const char* type, const char* name,
                                  CLI::App* app) :
        CommandInterface(type, name, app)
    {
        app->add_option("-s, --sensorId", sensorId, "sensor Id")->required();
    }

  private:
    void parseRegularResponse(nsm_msg* responsePtr, size_t payloadLength)
    {
        const size_t msg_len = payloadLength + sizeof(nsm_msg_hdr);
        uint8_t cc;
        uint16_t reason_code;
        int32_t threshold;

        auto rc = decode_read_thermal_parameter_resp(responsePtr, msg_len, &cc,
                                                     &reason_code, &threshold);
        if (rc != NSM_SUCCESS || cc != NSM_SUCCESS)
        {
            std::cerr << "Response message error: "
                      << "rc=" << rc << ", cc=" << (int)cc
                      << ", reasonCode=" << (int)reason_code << "\n"
                      << payloadLength << "...."
                      << (sizeof(struct nsm_msg_hdr) +
                          sizeof(nsm_get_current_power_draw_resp));

            return;
        }

        ordered_json result;
        result["Completion Code"] = cc;
        result["Sensor Id"] = sensorId;
        result["Thermal Parameter"] = threshold;

        nsmtool::helper::DisplayInJson(result);
    }

    class ReadThermalParameterAggregateResponseParser :
        public AggregateResponseParser
    {
      private:
        int handleSampleData(uint8_t tag, const uint8_t* data, size_t data_len,
                             ordered_json& sample_json) final
        {
            int32_t threshold;
            auto rc = decode_aggregate_thermal_parameter_data(data, data_len,
                                                              &threshold);
            if (rc == NSM_SUCCESS)
            {
                sample_json["Sensor Id"] = tag;
                sample_json["Thermal Parameter"] = threshold;
            }

            return rc;
        }
    };

  public:
    std::pair<int, std::vector<uint8_t>> createRequestMsg() override
    {
        std::vector<uint8_t> requestMsg(sizeof(nsm_msg_hdr) +
                                        sizeof(nsm_read_thermal_parameter_req));
        auto request = reinterpret_cast<nsm_msg*>(requestMsg.data());
        auto rc = encode_read_thermal_parameter_req(instanceId, sensorId,
                                                    request);
        return {rc, requestMsg};
    }

    void parseResponseMsg(nsm_msg* responsePtr, size_t payloadLength) override
    {
        if (sensorId == AggregateSensorId)
        {
            ReadThermalParameterAggregateResponseParser{}
                .parseAggregateResponse(responsePtr, payloadLength);
        }
        else
        {
            parseRegularResponse(responsePtr, payloadLength);
        }
    }

  private:
    uint8_t sensorId;
    static constexpr uint8_t AggregateSensorId{255};
};

class GetCurrentPowerDraw : public CommandInterface
{
  public:
    GetCurrentPowerDraw() = delete;
    GetCurrentPowerDraw(const GetCurrentPowerDraw&) = delete;
    GetCurrentPowerDraw(GetCurrentPowerDraw&&) = default;
    GetCurrentPowerDraw& operator=(const GetCurrentPowerDraw&) = delete;
    GetCurrentPowerDraw& operator=(GetCurrentPowerDraw&&) = delete;

    explicit GetCurrentPowerDraw(const char* type, const char* name,
                                 CLI::App* app) :
        CommandInterface(type, name, app)
    {
        app->add_option("-s, --sensorId", sensorId, "sensor Id")->required();

        app->add_option("-a, --averagingInterval", averagingInterval,
                        "averaging interval of current power draw reading")
            ->required();
    }

  private:
    void parseRegularResponse(nsm_msg* responsePtr, size_t payloadLength)
    {
        const size_t msg_len = payloadLength + sizeof(nsm_msg_hdr);
        uint8_t cc;
        uint16_t reason_code;
        uint32_t reading;

        auto rc = decode_get_current_power_draw_resp(responsePtr, msg_len, &cc,
                                                     &reason_code, &reading);
        if (rc != NSM_SUCCESS || cc != NSM_SUCCESS)
        {
            std::cerr << "Response message error: "
                      << "rc=" << rc << ", cc=" << (int)cc
                      << ", reasonCode=" << (int)reason_code << "\n"
                      << payloadLength << "...."
                      << (sizeof(struct nsm_msg_hdr) +
                          sizeof(nsm_get_current_power_draw_resp));

            return;
        }

        ordered_json result;
        result["Completion Code"] = cc;
        result["Sensor Id"] = sensorId;
        result["Averaging Interval"] = averagingInterval;
        result["Current Power Draw"] = reading;

        nsmtool::helper::DisplayInJson(result);
    }

    class GetCurrentPowerDrawAggregateResponseParser :
        public AggregateResponseParser
    {
      private:
        int handleSampleData(uint8_t tag, const uint8_t* data, size_t data_len,
                             ordered_json& sample_json) final
        {
            uint32_t reading;
            auto rc = decode_aggregate_get_current_power_draw_reading(
                data, data_len, &reading);
            if (rc == NSM_SUCCESS)
            {
                sample_json["Sensor Id"] = tag;
                sample_json["Current Power Draw"] = reading;
            }

            return rc;
        }
    };

  public:
    std::pair<int, std::vector<uint8_t>> createRequestMsg() override
    {
        std::vector<uint8_t> requestMsg(sizeof(nsm_msg_hdr) +
                                        sizeof(nsm_get_current_power_draw_req));
        auto request = reinterpret_cast<nsm_msg*>(requestMsg.data());
        auto rc = encode_get_current_power_draw_req(instanceId, sensorId,
                                                    averagingInterval, request);
        return {rc, requestMsg};
    }

    void parseResponseMsg(nsm_msg* responsePtr, size_t payloadLength) override
    {
        if (sensorId == AggregateSensorId)
        {
            GetCurrentPowerDrawAggregateResponseParser{}.parseAggregateResponse(
                responsePtr, payloadLength);
        }
        else
        {
            parseRegularResponse(responsePtr, payloadLength);
        }
    }

  private:
    uint8_t sensorId;
    static constexpr uint8_t AggregateSensorId{255};
    uint8_t averagingInterval;
};

class GetMaxObservedPower : public CommandInterface
{
  public:
    GetMaxObservedPower() = delete;
    GetMaxObservedPower(const GetMaxObservedPower&) = delete;
    GetMaxObservedPower(GetMaxObservedPower&&) = default;
    GetMaxObservedPower& operator=(const GetMaxObservedPower&) = delete;
    GetMaxObservedPower& operator=(GetMaxObservedPower&&) = delete;

    explicit GetMaxObservedPower(const char* type, const char* name,
                                 CLI::App* app) :
        CommandInterface(type, name, app)
    {
        app->add_option("-s, --sensorId", sensorId, "sensor Id")->required();

        app->add_option("-a, --averagingInterval", averagingInterval,
                        "averaging interval of current power draw reading")
            ->required();
    }

  private:
    void parseRegularResponse(nsm_msg* responsePtr, size_t payloadLength)
    {
        const size_t msg_len = payloadLength + sizeof(nsm_msg_hdr);
        uint8_t cc;
        uint16_t reason_code;
        uint32_t reading;

        auto rc = decode_get_max_observed_power_resp(responsePtr, msg_len, &cc,
                                                     &reason_code, &reading);
        if (rc != NSM_SUCCESS || cc != NSM_SUCCESS)
        {
            std::cerr << "Response message error: "
                      << "rc=" << rc << ", cc=" << (int)cc
                      << ", reasonCode=" << (int)reason_code << "\n"
                      << payloadLength << "...."
                      << (sizeof(struct nsm_msg_hdr) +
                          sizeof(nsm_get_current_power_draw_resp))
                      << '\n';

            return;
        }

        ordered_json result;
        result["Completion Code"] = cc;
        result["Sensor Id"] = sensorId;
        result["Averaging Interval"] = averagingInterval;
        result["Max Observed Power"] = reading;

        nsmtool::helper::DisplayInJson(result);
    }

    class GetMaxObservedPowerAggregateResponseParser :
        public AggregateResponseParser
    {
      private:
        int handleSampleData(uint8_t tag, const uint8_t* data, size_t data_len,
                             ordered_json& sample_json) final
        {
            uint32_t reading;
            auto rc = decode_aggregate_get_current_power_draw_reading(
                data, data_len, &reading);
            if (rc == NSM_SUCCESS)
            {
                sample_json["Sensor Id"] = tag;
                sample_json["Max Observed Power"] = reading;
            }

            return rc;
        }
    };

  public:
    std::pair<int, std::vector<uint8_t>> createRequestMsg() override
    {
        std::vector<uint8_t> requestMsg(sizeof(nsm_msg_hdr) +
                                        sizeof(nsm_get_current_power_draw_req));
        auto request = reinterpret_cast<nsm_msg*>(requestMsg.data());
        auto rc = encode_get_max_observed_power_req(instanceId, sensorId,
                                                    averagingInterval, request);
        return {rc, requestMsg};
    }

    void parseResponseMsg(nsm_msg* responsePtr, size_t payloadLength) override
    {
        if (sensorId == AggregateSensorId)
        {
            GetMaxObservedPowerAggregateResponseParser{}.parseAggregateResponse(
                responsePtr, payloadLength);
        }
        else
        {
            parseRegularResponse(responsePtr, payloadLength);
        }
    }

  private:
    uint8_t sensorId;
    static constexpr uint8_t AggregateSensorId{255};
    uint8_t averagingInterval;
};

class GetCurrentEnergyCount : public CommandInterface
{
  public:
    GetCurrentEnergyCount() = delete;
    GetCurrentEnergyCount(const GetCurrentEnergyCount&) = delete;
    GetCurrentEnergyCount(GetCurrentEnergyCount&&) = default;
    GetCurrentEnergyCount& operator=(const GetCurrentEnergyCount&) = delete;
    GetCurrentEnergyCount& operator=(GetCurrentEnergyCount&&) = delete;

    explicit GetCurrentEnergyCount(const char* type, const char* name,
                                   CLI::App* app) :
        CommandInterface(type, name, app)
    {
        app->add_option("-s, --sensorId", sensorId, "sensor Id")->required();
    }

  private:
    void parseRegularResponse(nsm_msg* responsePtr, size_t payloadLength)
    {
        const size_t msg_len = payloadLength + sizeof(nsm_msg_hdr);
        uint8_t cc;
        uint16_t reason_code;
        uint64_t reading;

        auto rc = decode_get_current_energy_count_resp(
            responsePtr, msg_len, &cc, &reason_code, &reading);
        if (rc != NSM_SUCCESS || cc != NSM_SUCCESS)
        {
            std::cerr << "Response message error: "
                      << "rc=" << rc << ", cc=" << (int)cc
                      << ", reasonCode=" << (int)reason_code << "\n"
                      << payloadLength << "...."
                      << (sizeof(struct nsm_msg_hdr) +
                          sizeof(struct nsm_get_current_energy_count_resp));

            return;
        }

        ordered_json result;
        result["Completion Code"] = cc;
        result["Sensor Id"] = sensorId;
        result["Current Energy Count"] = reading;

        nsmtool::helper::DisplayInJson(result);
    }

    class GetCurrentEnergyCountAggregateResponseParser :
        public AggregateResponseParser
    {
      private:
        int handleSampleData(uint8_t tag, const uint8_t* data, size_t data_len,
                             ordered_json& sample_json) final
        {
            uint64_t reading{};
            auto rc = decode_aggregate_energy_count_data(data, data_len,
                                                         &reading);

            if (rc == NSM_SUCCESS)
            {
                sample_json["Sensor Id"] = tag;
                sample_json["Current Energy Count"] = reading;
            }

            return rc;
        }
    };

  public:
    std::pair<int, std::vector<uint8_t>> createRequestMsg() override
    {
        std::vector<uint8_t> requestMsg(
            sizeof(nsm_msg_hdr) + sizeof(nsm_get_current_energy_count_req));
        auto request = reinterpret_cast<nsm_msg*>(requestMsg.data());
        auto rc = encode_get_current_energy_count_req(instanceId, sensorId,
                                                      request);
        return {rc, requestMsg};
    }

    void parseResponseMsg(nsm_msg* responsePtr, size_t payloadLength) override
    {
        if (sensorId == AggregateSensorId)
        {
            GetCurrentEnergyCountAggregateResponseParser{}
                .parseAggregateResponse(responsePtr, payloadLength);
        }
        else
        {
            parseRegularResponse(responsePtr, payloadLength);
        }
    }

  private:
    uint8_t sensorId;
    static constexpr uint8_t AggregateSensorId{255};
};

class GetVoltage : public CommandInterface
{
  public:
    GetVoltage() = delete;
    GetVoltage(const GetVoltage&) = delete;
    GetVoltage(GetVoltage&&) = default;
    GetVoltage& operator=(const GetVoltage&) = delete;
    GetVoltage& operator=(GetVoltage&&) = delete;

    explicit GetVoltage(const char* type, const char* name, CLI::App* app) :
        CommandInterface(type, name, app)
    {
        app->add_option("-s, --sensorId", sensorId, "sensor Id")->required();
    }

  private:
    void parseRegularResponse(nsm_msg* responsePtr, size_t payloadLength)
    {
        const size_t msg_len = payloadLength + sizeof(nsm_msg_hdr);
        uint8_t cc;
        uint16_t reason_code;
        uint32_t reading;

        auto rc = decode_get_voltage_resp(responsePtr, msg_len, &cc,
                                          &reason_code, &reading);
        if (rc != NSM_SUCCESS || cc != NSM_SUCCESS)
        {
            std::cerr << "Response message error: "
                      << "rc=" << rc << ", cc=" << (int)cc
                      << ", reasonCode=" << (int)reason_code << "\n"
                      << payloadLength << "...."
                      << (sizeof(struct nsm_msg_hdr) +
                          sizeof(nsm_get_voltage_resp));

            return;
        }

        ordered_json result;
        result["Completion Code"] = cc;
        result["Sensor Id"] = sensorId;
        result["Voltage"] = reading;

        nsmtool::helper::DisplayInJson(result);
    }

    class GetVoltageAggregateResponseParser : public AggregateResponseParser
    {
      private:
        int handleSampleData(uint8_t tag, const uint8_t* data, size_t data_len,
                             ordered_json& sample_json) final
        {
            uint32_t reading{};
            auto rc = decode_aggregate_voltage_data(data, data_len, &reading);

            if (rc == NSM_SUCCESS)
            {
                sample_json["Sensor Id"] = tag;
                sample_json["Voltage"] = reading;
            }

            return rc;
        }
    };

  public:
    std::pair<int, std::vector<uint8_t>> createRequestMsg() override
    {
        std::vector<uint8_t> requestMsg(sizeof(nsm_msg_hdr) +
                                        sizeof(nsm_get_voltage_req));
        auto request = reinterpret_cast<nsm_msg*>(requestMsg.data());
        auto rc = encode_get_voltage_req(instanceId, sensorId, request);
        return {rc, requestMsg};
    }

    void parseResponseMsg(nsm_msg* responsePtr, size_t payloadLength) override
    {
        if (sensorId == AggregateSensorId)
        {
            GetVoltageAggregateResponseParser{}.parseAggregateResponse(
                responsePtr, payloadLength);
        }
        else
        {
            parseRegularResponse(responsePtr, payloadLength);
        }
    }

  private:
    uint8_t sensorId;
    static constexpr uint8_t AggregateSensorId{255};
};

class GetAltitudePressure : public CommandInterface
{
  public:
    GetAltitudePressure() = delete;
    GetAltitudePressure(const GetAltitudePressure&) = delete;
    GetAltitudePressure(GetAltitudePressure&&) = default;
    GetAltitudePressure& operator=(const GetAltitudePressure&) = delete;
    GetAltitudePressure& operator=(GetAltitudePressure&&) = delete;

    explicit GetAltitudePressure(const char* type, const char* name,
                                 CLI::App* app) :
        CommandInterface(type, name, app)
    {}

  public:
    std::pair<int, std::vector<uint8_t>> createRequestMsg() override
    {
        std::vector<uint8_t> requestMsg(sizeof(nsm_msg_hdr) +
                                        sizeof(nsm_common_req));
        auto request = reinterpret_cast<nsm_msg*>(requestMsg.data());
        auto rc = encode_get_altitude_pressure_req(instanceId, request);
        return {rc, requestMsg};
    }

    void parseResponseMsg(nsm_msg* responsePtr, size_t payloadLength) override
    {
        const size_t msg_len = payloadLength + sizeof(nsm_msg_hdr);
        uint8_t cc;
        uint16_t reason_code;
        uint32_t reading;

        auto rc = decode_get_altitude_pressure_resp(responsePtr, msg_len, &cc,
                                                    &reason_code, &reading);
        if (rc != NSM_SUCCESS || cc != NSM_SUCCESS)
        {
            std::cerr << "Response message error: "
                      << "rc=" << rc << ", cc=" << (int)cc
                      << ", reasonCode=" << (int)reason_code << "\n"
                      << payloadLength << "...."
                      << (sizeof(struct nsm_msg_hdr) +
                          sizeof(nsm_get_altitude_pressure_resp));

            return;
        }

        ordered_json result;
        result["Completion Code"] = cc;
        result["Altitude Pressure"] = reading;

        nsmtool::helper::DisplayInJson(result);
    }
};

class GetMigMode : public CommandInterface
{
  public:
    ~GetMigMode() = default;
    GetMigMode() = delete;
    GetMigMode(const GetMigMode&) = delete;
    GetMigMode(GetMigMode&&) = default;
    GetMigMode& operator=(const GetMigMode&) = delete;
    GetMigMode& operator=(GetMigMode&&) = default;

    using CommandInterface::CommandInterface;

    std::pair<int, std::vector<uint8_t>> createRequestMsg() override
    {
        std::vector<uint8_t> requestMsg(sizeof(nsm_msg_hdr) +
                                        sizeof(nsm_common_req));
        auto request = reinterpret_cast<nsm_msg*>(requestMsg.data());
        auto rc = encode_get_MIG_mode_req(instanceId, request);
        return {rc, requestMsg};
    }

    void parseResponseMsg(nsm_msg* responsePtr, size_t payloadLength) override
    {
        uint8_t cc = NSM_ERROR;
        bitfield8_t flags;
        uint16_t data_size;
        uint16_t reason_code = ERR_NULL;
        auto rc = decode_get_MIG_mode_resp(responsePtr, payloadLength, &cc,
                                           &data_size, &reason_code, &flags);
        if (rc != NSM_SW_SUCCESS || cc != NSM_SUCCESS)
        {
            std::cerr << "Response message error: "
                      << "rc=" << rc << ", cc=" << (int)cc
                      << ", reasonCode=" << (int)reason_code << "\n"
                      << payloadLength << "...."
                      << (sizeof(struct nsm_msg_hdr) +
                          sizeof(struct nsm_get_MIG_mode_resp));

            return;
        }

        ordered_json result;
        result["Completion Code"] = cc;
        if (flags.bits.bit0)
        {
            result["MigModeEnabled"] = true;
        }
        else
        {
            result["MigModeEnabled"] = false;
        }
        nsmtool::helper::DisplayInJson(result);
    }
};

class SetMigMode : public CommandInterface
{
  public:
    ~SetMigMode() = default;
    SetMigMode() = delete;
    SetMigMode(const SetMigMode&) = delete;
    SetMigMode(SetMigMode&&) = default;
    SetMigMode& operator=(const SetMigMode&) = delete;
    SetMigMode& operator=(SetMigMode&&) = default;

    using CommandInterface::CommandInterface;

    explicit SetMigMode(const char* type, const char* name, CLI::App* app) :
        CommandInterface(type, name, app)
    {
        auto requestedMode =
            app->add_option_group("Required", "Requested Mig Mode can be 0/1.");

        requestedMode->add_option("-r, --mode", requested_mode,
                                  "retrieve requested mig mode");

        requestedMode->require_option(1);
    }

    std::pair<int, std::vector<uint8_t>> createRequestMsg() override
    {
        std::vector<uint8_t> requestMsg(sizeof(nsm_msg_hdr) +
                                        sizeof(nsm_set_MIG_mode_req));
        auto request = reinterpret_cast<nsm_msg*>(requestMsg.data());
        auto rc = encode_set_MIG_mode_req(instanceId, requested_mode, request);
        return {rc, requestMsg};
    }

    void parseResponseMsg(nsm_msg* responsePtr, size_t payloadLength) override
    {
        uint8_t cc = NSM_ERROR;
        uint16_t data_size;
        uint16_t reason_code = ERR_NULL;
        auto rc = decode_set_MIG_mode_resp(responsePtr, payloadLength, &cc,
                                           &data_size, &reason_code);
        if (rc != NSM_SW_SUCCESS || cc != NSM_SUCCESS)
        {
            std::cerr << "Response message error: "
                      << "rc=" << rc << ", cc=" << (int)cc
                      << ", reasonCode=" << (int)reason_code << "\n"
                      << payloadLength << "...."
                      << (sizeof(struct nsm_msg_hdr) +
                          sizeof(struct nsm_common_resp));

            return;
        }

        ordered_json result;
        result["Completion Code"] = cc;
        nsmtool::helper::DisplayInJson(result);
    }

    uint8_t requested_mode;
};

class GetEccMode : public CommandInterface
{
  public:
    ~GetEccMode() = default;
    GetEccMode() = delete;
    GetEccMode(const GetEccMode&) = delete;
    GetEccMode(GetEccMode&&) = default;
    GetEccMode& operator=(const GetEccMode&) = delete;
    GetEccMode& operator=(GetEccMode&&) = default;

    using CommandInterface::CommandInterface;

    std::pair<int, std::vector<uint8_t>> createRequestMsg() override
    {
        std::vector<uint8_t> requestMsg(sizeof(nsm_msg_hdr) +
                                        sizeof(nsm_common_req));
        auto request = reinterpret_cast<nsm_msg*>(requestMsg.data());
        auto rc = encode_get_ECC_mode_req(instanceId, request);
        return {rc, requestMsg};
    }

    void parseResponseMsg(nsm_msg* responsePtr, size_t payloadLength) override
    {
        uint8_t cc = NSM_ERROR;
        bitfield8_t flags;
        uint16_t data_size;
        uint16_t reason_code = ERR_NULL;
        auto rc = decode_get_ECC_mode_resp(responsePtr, payloadLength, &cc,
                                           &data_size, &reason_code, &flags);
        if (rc != NSM_SW_SUCCESS || cc != NSM_SUCCESS)
        {
            std::cerr << "Response message error: "
                      << "rc=" << rc << ", cc=" << (int)cc
                      << ", reasonCode=" << (int)reason_code << "\n"
                      << payloadLength << "...."
                      << (sizeof(struct nsm_msg_hdr) +
                          sizeof(struct nsm_get_ECC_mode_resp));

            return;
        }

        ordered_json result;
        result["Completion Code"] = cc;
        if (flags.bits.bit0)
        {
            result["ECCModeEnabled"] = true;
        }
        else
        {
            result["ECCModeEnabled"] = false;
        }
        if (flags.bits.bit1)
        {
            result["PendingECCState"] = true;
        }
        else
        {
            result["PendingECCState"] = false;
        }
        nsmtool::helper::DisplayInJson(result);
    }
};

class SetEccMode : public CommandInterface
{
  public:
    ~SetEccMode() = default;
    SetEccMode() = delete;
    SetEccMode(const SetEccMode&) = delete;
    SetEccMode(SetEccMode&&) = default;
    SetEccMode& operator=(const SetEccMode&) = delete;
    SetEccMode& operator=(SetEccMode&&) = default;

    using CommandInterface::CommandInterface;

    explicit SetEccMode(const char* type, const char* name, CLI::App* app) :
        CommandInterface(type, name, app)
    {
        auto requestedMode = app->add_option_group("Required",
                                                   "Requested ECC Mode.");

        requestedMode->add_option("-r, --mode", requested_mode,
                                  "requested ECC mode");

        requestedMode->require_option(1);
    }

    std::pair<int, std::vector<uint8_t>> createRequestMsg() override
    {
        std::vector<uint8_t> requestMsg(sizeof(nsm_msg_hdr) +
                                        sizeof(nsm_set_ECC_mode_req));
        auto request = reinterpret_cast<nsm_msg*>(requestMsg.data());
        auto rc = encode_set_ECC_mode_req(instanceId, requested_mode, request);
        return {rc, requestMsg};
    }

    void parseResponseMsg(nsm_msg* responsePtr, size_t payloadLength) override
    {
        uint8_t cc = NSM_ERROR;
        uint16_t data_size;
        uint16_t reason_code = ERR_NULL;
        auto rc = decode_set_ECC_mode_resp(responsePtr, payloadLength, &cc,
                                           &data_size, &reason_code);
        if (rc != NSM_SW_SUCCESS || cc != NSM_SUCCESS)
        {
            std::cerr << "Response message error: "
                      << "rc=" << rc << ", cc=" << (int)cc
                      << ", reasonCode=" << (int)reason_code << "\n"
                      << payloadLength << "...."
                      << (sizeof(struct nsm_msg_hdr) +
                          sizeof(struct nsm_common_resp));

            return;
        }

        ordered_json result;
        result["Completion Code"] = cc;
        nsmtool::helper::DisplayInJson(result);
    }

    uint8_t requested_mode;
};

class GetEccErrorCounts : public CommandInterface
{
  public:
    ~GetEccErrorCounts() = default;
    GetEccErrorCounts() = delete;
    GetEccErrorCounts(const GetEccErrorCounts&) = delete;
    GetEccErrorCounts(GetEccErrorCounts&&) = default;
    GetEccErrorCounts& operator=(const GetEccErrorCounts&) = delete;
    GetEccErrorCounts& operator=(GetEccErrorCounts&&) = default;

    using CommandInterface::CommandInterface;

    std::pair<int, std::vector<uint8_t>> createRequestMsg() override
    {
        std::vector<uint8_t> requestMsg(sizeof(nsm_msg_hdr) +
                                        sizeof(nsm_common_req));
        auto request = reinterpret_cast<nsm_msg*>(requestMsg.data());
        auto rc = encode_get_ECC_error_counts_req(instanceId, request);
        return {rc, requestMsg};
    }

    void parseResponseMsg(nsm_msg* responsePtr, size_t payloadLength) override
    {
        uint8_t cc = NSM_ERROR;
        struct nsm_ECC_error_counts errorCounts;
        uint16_t data_size;
        uint16_t reason_code = ERR_NULL;
        auto rc = decode_get_ECC_error_counts_resp(responsePtr, payloadLength,
                                                   &cc, &data_size,
                                                   &reason_code, &errorCounts);
        if (rc != NSM_SW_SUCCESS || cc != NSM_SUCCESS)
        {
            std::cerr << "Response message error: "
                      << "rc=" << rc << ", cc=" << (int)cc
                      << ", reasonCode=" << (int)reason_code << "\n"
                      << payloadLength << "...."
                      << (sizeof(struct nsm_msg_hdr) +
                          sizeof(struct nsm_get_ECC_error_counts_resp));

            return;
        }

        ordered_json result;
        result["Completion Code"] = cc;
        result["ueCount"] = errorCounts.sram_uncorrected_parity +
                            errorCounts.sram_uncorrected_secded;
        result["ecCount"] = (int)errorCounts.sram_corrected;
        nsmtool::helper::DisplayInJson(result);
    }
};

class SetClockLimit : public CommandInterface
{
  public:
    ~SetClockLimit() = default;
    SetClockLimit() = delete;
    SetClockLimit(const SetClockLimit&) = delete;
    SetClockLimit(SetClockLimit&&) = default;
    SetClockLimit& operator=(const SetClockLimit&) = delete;
    SetClockLimit& operator=(SetClockLimit&&) = default;

    using CommandInterface::CommandInterface;

    explicit SetClockLimit(const char* type, const char* name, CLI::App* app) :
        CommandInterface(type, name, app)
    {
        auto requestedClockLimit =
            app->add_option_group("Required", "Requested Clock Limit.");

        requestedClockLimit->add_option(
            "-c, --clockId", clockId,
            "clock type (0/1) (graphics clock/memory clock)");
        requestedClockLimit->add_option("-f, --flags", flags, "flags");
        requestedClockLimit->add_option("-a, --limit_min", limitMin,
                                        "Minimum Clock frequency");
        requestedClockLimit->add_option("-b, --limit_max", limitMax,
                                        "Maximum clock frequency");
        requestedClockLimit->require_option(4);
    }

    std::pair<int, std::vector<uint8_t>> createRequestMsg() override
    {
        std::vector<uint8_t> requestMsg(sizeof(nsm_msg_hdr) +
                                        sizeof(nsm_set_clock_limit_req));
        auto request = reinterpret_cast<nsm_msg*>(requestMsg.data());
        auto rc = encode_set_clock_limit_req(instanceId, clockId, flags,
                                             limitMin, limitMax, request);
        return {rc, requestMsg};
    }

    void parseResponseMsg(nsm_msg* responsePtr, size_t payloadLength) override
    {
        uint8_t cc = NSM_ERROR;
        uint16_t data_size;
        uint16_t reason_code = ERR_NULL;
        auto rc = decode_set_clock_limit_resp(responsePtr, payloadLength, &cc,
                                              &data_size, &reason_code);
        if (rc != NSM_SW_SUCCESS || cc != NSM_SUCCESS)
        {
            std::cerr << "Response message error: "
                      << "rc=" << rc << ", cc=" << (int)cc
                      << ", reasonCode=" << (int)reason_code << "\n"
                      << payloadLength << "...."
                      << (sizeof(struct nsm_msg_hdr) +
                          sizeof(struct nsm_common_resp));

            return;
        }

        ordered_json result;
        result["Completion Code"] = cc;
        nsmtool::helper::DisplayInJson(result);
    }
    uint32_t limitMin;
    uint32_t limitMax;
    uint8_t flags;
    uint8_t clockId;
};

class GetEDPpScalingFactors : public CommandInterface
{
  public:
    ~GetEDPpScalingFactors() = default;
    GetEDPpScalingFactors() = delete;
    GetEDPpScalingFactors(const GetEDPpScalingFactors&) = delete;
    GetEDPpScalingFactors(GetEDPpScalingFactors&&) = default;
    GetEDPpScalingFactors& operator=(const GetEDPpScalingFactors&) = delete;
    GetEDPpScalingFactors& operator=(GetEDPpScalingFactors&&) = default;

    using CommandInterface::CommandInterface;

    std::pair<int, std::vector<uint8_t>> createRequestMsg() override
    {
        std::vector<uint8_t> requestMsg(sizeof(nsm_msg_hdr) +
                                        sizeof(nsm_common_req));
        auto request = reinterpret_cast<nsm_msg*>(requestMsg.data());
        auto rc = encode_get_programmable_EDPp_scaling_factor_req(instanceId,
                                                                  request);
        return {rc, requestMsg};
    }

    void parseResponseMsg(nsm_msg* responsePtr, size_t payloadLength) override
    {
        uint8_t cc = NSM_ERROR;
        struct nsm_EDPp_scaling_factors scaling_factors;
        uint16_t data_size;
        uint16_t reason_code = ERR_NULL;

        auto rc = decode_get_programmable_EDPp_scaling_factor_resp(
            responsePtr, payloadLength, &cc, &data_size, &reason_code,
            &scaling_factors);
        if (rc != NSM_SW_SUCCESS || cc != NSM_SUCCESS)
        {
            std::cerr
                << "Response message error: "
                << "rc=" << rc << ", cc=" << (int)cc
                << ", reasonCode=" << (int)reason_code << "\n"
                << payloadLength << "...."
                << (sizeof(struct nsm_msg_hdr) +
                    sizeof(
                        struct nsm_get_programmable_EDPp_scaling_factor_resp));

            return;
        }

        ordered_json result;
        result["Completion Code"] = cc;
        result["Requested_Persistent_Scaling_Factor"] =
            scaling_factors.persistent_scaling_factor;
        result["Requested_OneShot_Scaling_Factor"] =
            scaling_factors.oneshot_scaling_factor;
        result["Enforced_Scaling_Factor"] =
            scaling_factors.enforced_scaling_factor;
        nsmtool::helper::DisplayInJson(result);
    }
};

class SetEDPpScalingFactors : public CommandInterface
{
  public:
    ~SetEDPpScalingFactors() = default;
    SetEDPpScalingFactors() = delete;
    SetEDPpScalingFactors(const SetEDPpScalingFactors&) = delete;
    SetEDPpScalingFactors(SetEDPpScalingFactors&&) = default;
    SetEDPpScalingFactors& operator=(const SetEDPpScalingFactors&) = delete;
    SetEDPpScalingFactors& operator=(SetEDPpScalingFactors&&) = default;

    using CommandInterface::CommandInterface;

    explicit SetEDPpScalingFactors(const char* type, const char* name,
                                   CLI::App* app) :
        CommandInterface(type, name, app)
    {
        app->add_option("-a, --action", action,
                        "Action to be perform on EDPp Scaling factor")
            ->required();
        app->add_option("-p, --persistence", persistence,
                        "life Time of EDPp scaling factor")
            ->required();
        app->add_option(
               "-s, --scaling_factor", scaling_factor,
               "Requested EDPp scaling factor as an integer percentage value")
            ->required();
    }

    std::pair<int, std::vector<uint8_t>> createRequestMsg() override
    {
        std::vector<uint8_t> requestMsg(
            sizeof(nsm_msg_hdr) +
            sizeof(nsm_set_programmable_EDPp_scaling_factor_req));
        auto request = reinterpret_cast<nsm_msg*>(requestMsg.data());
        auto rc = encode_set_programmable_EDPp_scaling_factor_req(
            instanceId, action, persistence, scaling_factor, request);
        return {rc, requestMsg};
    }

    void parseResponseMsg(nsm_msg* responsePtr, size_t payloadLength) override
    {
        uint8_t cc = NSM_ERROR;
        uint16_t data_size;
        uint16_t reason_code = ERR_NULL;

        auto rc = decode_set_programmable_EDPp_scaling_factor_resp(
            responsePtr, payloadLength, &cc, &data_size, &reason_code);
        if (rc != NSM_SW_SUCCESS || cc != NSM_SUCCESS)
        {
            std::cerr << "Response message error: "
                      << "rc=" << rc << ", cc=" << (int)cc
                      << ", reasonCode=" << (int)reason_code << "\n"
                      << payloadLength << "...."
                      << (sizeof(struct nsm_msg_hdr) +
                          sizeof(struct nsm_common_resp));

            return;
        }

        ordered_json result;
        result["Completion Code"] = cc;
        nsmtool::helper::DisplayInJson(result);
    }

  private:
    uint8_t action;
    uint8_t persistence;
    uint8_t scaling_factor;
};

class QueryScalarGroupTelemetry : public CommandInterface
{
  public:
    ~QueryScalarGroupTelemetry() = default;
    QueryScalarGroupTelemetry() = delete;
    QueryScalarGroupTelemetry(const QueryScalarGroupTelemetry&) = delete;
    QueryScalarGroupTelemetry(QueryScalarGroupTelemetry&&) = default;
    QueryScalarGroupTelemetry&
        operator=(const QueryScalarGroupTelemetry&) = delete;
    QueryScalarGroupTelemetry& operator=(QueryScalarGroupTelemetry&&) = default;

    using CommandInterface::CommandInterface;

    explicit QueryScalarGroupTelemetry(const char* type, const char* name,
                                       CLI::App* app) :
        CommandInterface(type, name, app)
    {
        auto scalarTelemetryOptionGroup = app->add_option_group(
            "Required", "Group Id for which data source is to be retrieved.");

        scalarTelemetryOptionGroup->add_option("-d, --deviceIndex", deviceIndex,
                                               "retrieve deviceIndex");
        scalarTelemetryOptionGroup->add_option(
            "-g, --groupId", groupId, "retrieve data source for groupId");
        scalarTelemetryOptionGroup->require_option(2);
    }

    virtual std::pair<int, std::vector<uint8_t>> createRequestMsg() override
    {
        std::vector<uint8_t> requestMsg(
            sizeof(nsm_msg_hdr) +
            sizeof(nsm_query_scalar_group_telemetry_v1_req));
        auto request = reinterpret_cast<nsm_msg*>(requestMsg.data());
        auto rc = encode_query_scalar_group_telemetry_v1_req(
            instanceId, deviceIndex, groupId, request);
        return {rc, requestMsg};
    }

    void parseResponseMsg(nsm_msg* responsePtr, size_t payloadLength) override
    {
        uint8_t cc = NSM_ERROR;
        switch (groupId)
        {
            case GROUP_ID_0:
            {
                struct nsm_query_scalar_group_telemetry_group_0 data;
                uint16_t data_size;
                uint16_t reason_code = ERR_NULL;

                auto rc = decode_query_scalar_group_telemetry_v1_group0_resp(
                    responsePtr, payloadLength, &cc, &data_size, &reason_code,
                    &data);
                if (rc != NSM_SW_SUCCESS || cc != NSM_SUCCESS)
                {
                    std::cerr
                        << "Response message error: "
                        << "rc=" << rc << ", cc=" << (int)cc
                        << ", reasonCode=" << (int)reason_code << "\n"
                        << payloadLength << "...."
                        << (sizeof(struct nsm_msg_hdr) +
                            sizeof(
                                struct
                                nsm_query_scalar_group_telemetry_v1_group_2_resp));

                    return;
                }

                ordered_json result;
                result["Completion Code"] = cc;
                result["PciVendorId"] = (int)data.pci_vendor_id;
                result["PciDeviceId"] = (int)data.pci_device_id;
                result["PciSubsystemVendorId"] =
                    (int)data.pci_subsystem_vendor_id;
                result["PciSubsystemDeviceId"] =
                    (int)data.pci_subsystem_device_id;
                nsmtool::helper::DisplayInJson(result);
                break;
            }
            case GROUP_ID_1:
            {
                struct nsm_query_scalar_group_telemetry_group_1 data;
                uint16_t data_size;
                uint16_t reason_code = ERR_NULL;

                auto rc = decode_query_scalar_group_telemetry_v1_group1_resp(
                    responsePtr, payloadLength, &cc, &data_size, &reason_code,
                    &data);
                if (rc != NSM_SW_SUCCESS || cc != NSM_SUCCESS)
                {
                    std::cerr
                        << "Response message error: "
                        << "rc=" << rc << ", cc=" << (int)cc
                        << ", reasonCode=" << (int)reason_code << "\n"
                        << payloadLength << "...."
                        << (sizeof(struct nsm_msg_hdr) +
                            sizeof(
                                struct
                                nsm_query_scalar_group_telemetry_v1_group_2_resp));

                    return;
                }

                ordered_json result;
                result["Completion Code"] = cc;
                result["NegotiatedLinkSpeed"] = (int)data.negotiated_link_speed;
                result["NegotiatedLinkWidth"] = (int)data.negotiated_link_width;
                result["maxLinkSpeed"] = (int)data.max_link_speed;
                result["maxLinkWidth"] = (int)data.max_link_width;
                nsmtool::helper::DisplayInJson(result);
                break;
            }
            case GROUP_ID_2:
            {
                struct nsm_query_scalar_group_telemetry_group_2 data;
                uint16_t data_size;
                uint16_t reason_code = ERR_NULL;

                auto rc = decode_query_scalar_group_telemetry_v1_group2_resp(
                    responsePtr, payloadLength, &cc, &data_size, &reason_code,
                    &data);
                if (rc != NSM_SW_SUCCESS || cc != NSM_SUCCESS)
                {
                    std::cerr
                        << "Response message error: "
                        << "rc=" << rc << ", cc=" << (int)cc
                        << ", reasonCode=" << (int)reason_code << "\n"
                        << payloadLength << "...."
                        << (sizeof(struct nsm_msg_hdr) +
                            sizeof(
                                struct
                                nsm_query_scalar_group_telemetry_v1_group_2_resp));

                    return;
                }

                ordered_json result;
                result["Completion Code"] = cc;
                result["nonfeCount"] = (int)data.non_fatal_errors;
                result["feCount"] = (int)data.fatal_errors;
                result["ceCount"] = (int)data.correctable_errors;
                nsmtool::helper::DisplayInJson(result);
                break;
            }
            case GROUP_ID_3:
            {
                struct nsm_query_scalar_group_telemetry_group_3 data;
                uint16_t data_size;
                uint16_t reason_code = ERR_NULL;

                auto rc = decode_query_scalar_group_telemetry_v1_group3_resp(
                    responsePtr, payloadLength, &cc, &data_size, &reason_code,
                    &data);
                if (rc != NSM_SW_SUCCESS || cc != NSM_SUCCESS)
                {
                    std::cerr
                        << "Response message error: "
                        << "rc=" << rc << ", cc=" << (int)cc
                        << ", reasonCode=" << (int)reason_code << "\n"
                        << payloadLength << "...."
                        << (sizeof(struct nsm_msg_hdr) +
                            sizeof(
                                struct
                                nsm_query_scalar_group_telemetry_v1_group_3_resp));

                    return;
                }

                ordered_json result;
                result["Completion Code"] = cc;
                result["l0ToRecoveryCount"] = (int)data.L0ToRecoveryCount;
                nsmtool::helper::DisplayInJson(result);
                break;
            }
            case GROUP_ID_4:
            {
                struct nsm_query_scalar_group_telemetry_group_4 data;
                uint16_t data_size;
                uint16_t reason_code = ERR_NULL;

                auto rc = decode_query_scalar_group_telemetry_v1_group4_resp(
                    responsePtr, payloadLength, &cc, &data_size, &reason_code,
                    &data);
                if (rc != NSM_SW_SUCCESS || cc != NSM_SUCCESS)
                {
                    std::cerr
                        << "Response message error: "
                        << "rc=" << rc << ", cc=" << (int)cc
                        << ", reasonCode=" << (int)reason_code << "\n"
                        << payloadLength << "...."
                        << (sizeof(struct nsm_msg_hdr) +
                            sizeof(
                                struct
                                nsm_query_scalar_group_telemetry_v1_group_4_resp));

                    return;
                }

                ordered_json result;
                result["Completion Code"] = cc;
                result["replayCount"] = (int)data.replay_cnt;
                result["replayRolloverCount"] = (int)data.replay_rollover_cnt;
                result["nakSentCount"] = (int)data.NAK_sent_cnt;
                result["nakRecievedCount"] = (int)data.NAK_recv_cnt;
                nsmtool::helper::DisplayInJson(result);
                break;
            }
            case GROUP_ID_5:
            {
                struct nsm_query_scalar_group_telemetry_group_5 data;
                uint16_t data_size;
                uint16_t reason_code = ERR_NULL;

                auto rc = decode_query_scalar_group_telemetry_v1_group5_resp(
                    responsePtr, payloadLength, &cc, &data_size, &reason_code,
                    &data);
                if (rc != NSM_SW_SUCCESS || cc != NSM_SUCCESS)
                {
                    std::cerr
                        << "Response message error: "
                        << "rc=" << rc << ", cc=" << (int)cc
                        << ", reasonCode=" << (int)reason_code << "\n"
                        << payloadLength << "...."
                        << (sizeof(struct nsm_msg_hdr) +
                            sizeof(
                                struct
                                nsm_query_scalar_group_telemetry_v1_group_5_resp));

                    return;
                }

                ordered_json result;
                result["Completion Code"] = cc;
                result["PCIeTXDwords"] = (uint32_t)data.PCIeTXDwords;
                result["PCIeRXDwords"] = (uint32_t)data.PCIeRXDwords;
                nsmtool::helper::DisplayInJson(result);
                break;
            }
            case GROUP_ID_6:
            {
                struct nsm_query_scalar_group_telemetry_group_6 data;
                uint16_t data_size;
                uint16_t reason_code = ERR_NULL;

                auto rc = decode_query_scalar_group_telemetry_v1_group6_resp(
                    responsePtr, payloadLength, &cc, &data_size, &reason_code,
                    &data);
                if (rc != NSM_SW_SUCCESS || cc != NSM_SUCCESS)
                {
                    std::cerr
                        << "Response message error: "
                        << "rc=" << rc << ", cc=" << (int)cc
                        << ", reasonCode=" << (int)reason_code << "\n"
                        << payloadLength << "...."
                        << (sizeof(struct nsm_msg_hdr) +
                            sizeof(
                                struct
                                nsm_query_scalar_group_telemetry_v1_group_6_resp));

                    return;
                }

                ordered_json result;
                result["Completion Code"] = cc;
                result["InvalidFlitCounter"] = (int)data.invalid_flit_counter;
                result["LTSSMState"] = (int)data.ltssm_state;
                nsmtool::helper::DisplayInJson(result);
                break;
            }

            case GROUP_ID_8:
            {
                struct nsm_query_scalar_group_telemetry_group_8 data;
                uint16_t data_size;
                uint16_t reason_code = ERR_NULL;

                auto rc = decode_query_scalar_group_telemetry_v1_group8_resp(
                    responsePtr, payloadLength, &cc, &data_size, &reason_code,
                    &data);
                if (rc != NSM_SW_SUCCESS || cc != NSM_SUCCESS)
                {
                    std::cerr
                        << "Response message error: "
                        << "rc=" << rc << ", cc=" << (int)cc
                        << ", reasonCode=" << (int)reason_code << "\n"
                        << payloadLength << "...."
                        << (sizeof(struct nsm_msg_hdr) +
                            sizeof(
                                struct
                                nsm_query_scalar_group_telemetry_v1_group_8_resp));

                    return;
                }

                ordered_json result;
                result["Completion Code"] = cc;
                std::vector<uint32_t> error_counts;
                for (int idx = 0; idx < TOTAL_PCIE_LANE_COUNT; idx++)
                {
                    error_counts.push_back((uint32_t)data.error_counts[idx]);
                }
                result["Per_Lane_Error_Counts"] = error_counts;
                nsmtool::helper::DisplayInJson(result);
                break;
            }

            case GROUP_ID_9:
            {
                struct nsm_query_scalar_group_telemetry_group_9 data;
                uint16_t data_size;
                uint16_t reason_code = ERR_NULL;

                auto rc = decode_query_scalar_group_telemetry_v1_group9_resp(
                    responsePtr, payloadLength, &cc, &data_size, &reason_code,
                    &data);
                if (rc != NSM_SW_SUCCESS || cc != NSM_SUCCESS)
                {
                    std::cerr
                        << "Response message error: "
                        << "rc=" << rc << ", cc=" << (int)cc
                        << ", reasonCode=" << (int)reason_code << "\n"
                        << payloadLength << "...."
                        << (sizeof(struct nsm_msg_hdr) +
                            sizeof(
                                struct
                                nsm_query_scalar_group_telemetry_v1_group_9_resp));

                    return;
                }

                ordered_json result;
                result["Completion Code"] = cc;
                result["AER_Uncorrectable_Error_status"] =
                    (uint32_t)data.aer_uncorrectable_error_status;
                result["AER_Correctable_Error_status"] =
                    (uint32_t)data.aer_correctable_error_status;
                nsmtool::helper::DisplayInJson(result);
                break;
            }

            case GROUP_ID_10:
            {
                nsm_query_scalar_group_telemetry_group_10 data;
                uint16_t reasonCode = ERR_NULL;

                auto rc = decode_query_scalar_group_telemetry_v1_group10_resp(
                    responsePtr, payloadLength, &cc, &reasonCode, &data);
                if (rc != NSM_SW_SUCCESS || cc != NSM_SUCCESS)
                {
                    std::cerr
                        << "Response message error: "
                        << "rc=" << rc << ", cc=" << (int)cc
                        << ", reasonCode=" << (int)reasonCode << "\n"
                        << payloadLength << "...."
                        << (sizeof(struct nsm_msg_hdr) +
                            sizeof(
                                struct
                                nsm_query_scalar_group_telemetry_v1_group_10_resp));

                    return;
                }

                uint64_t dwordsTransferredInOutboundReadTlp =
                    (uint64_t(data.dwords_transferred_in_outbound_read_tlp_high)
                     << 32) |
                    (uint64_t(
                        data.dwords_transferred_in_outbound_read_tlp_low));

                uint64_t dwordsTransferredInOutboundWriteTlp =
                    (uint64_t(
                         data.dwords_transferred_in_outbound_write_tlp_high)
                     << 32) |
                    (uint64_t(
                        data.dwords_transferred_in_outbound_write_tlp_low));

                ordered_json result;
                result["Completion Code"] = cc;
                result["Outbound Read TLP Count"] =
                    uint32_t(data.outbound_read_tlp_count);
                result["DWORDs Transferred in Outbound Read TLP"] =
                    dwordsTransferredInOutboundReadTlp;
                result["Outbound Write TLP Count"] =
                    uint32_t(data.outbound_write_tlp_count);
                result["DWORDs Transferred in Outbound Write TLP"] =
                    dwordsTransferredInOutboundWriteTlp;
                result["Outbound Completion TLP Count"] =
                    uint32_t(data.outbound_completion_tlp_count);
                result["DWORDs Transferred in Outbound Completion"] =
                    uint32_t(data.dwords_transferred_in_outbound_completion);
                result["Read Requests Dropped (Tag Unavailable)"] =
                    uint32_t(data.read_requests_dropped_tag_unavailable);
                result["Read Requests Dropped (Credit Exhaustion)"] =
                    uint32_t(data.read_requests_dropped_credit_exhaustion);
                result["Read Requests Dropped (Credit Not Posted)"] =
                    uint32_t(data.read_requests_dropped_credit_not_posted);
                nsmtool::helper::DisplayInJson(result);
                break;
            }

            default:
            {
                std::cerr << "Invalid Group Id \n";
                break;
            }
        }
    }

  protected:
    uint8_t deviceIndex;
    uint8_t groupId;
};

class QueryMultiportScalarGroupTelemetry : public QueryScalarGroupTelemetry
{
  public:
    ~QueryMultiportScalarGroupTelemetry() = default;
    QueryMultiportScalarGroupTelemetry() = delete;
    QueryMultiportScalarGroupTelemetry(
        const QueryMultiportScalarGroupTelemetry&) = delete;
    QueryMultiportScalarGroupTelemetry(QueryMultiportScalarGroupTelemetry&&) =
        default;
    QueryMultiportScalarGroupTelemetry&
        operator=(const QueryMultiportScalarGroupTelemetry&) = delete;
    QueryMultiportScalarGroupTelemetry&
        operator=(QueryMultiportScalarGroupTelemetry&&) = default;

    explicit QueryMultiportScalarGroupTelemetry(const char* type,
                                                const char* name,
                                                CLI::App* app) :
        QueryScalarGroupTelemetry(type, name, app)
    {
        auto multiportOptionGroup =
            app->add_option_group("Required", "Multi PCI Port Identification.");

        multiportOptionGroup->add_option(
            "-t, --Type", this->type,
            "Port Type (0 - Upstream, 1 - Downstream)");
        multiportOptionGroup->add_option("-u, --UpstreamPortIndex",
                                         this->upstreamPortIndex,
                                         "Upstream Port Index");
        multiportOptionGroup->add_option("-i, --Index", this->index,
                                         "Port Index");
        multiportOptionGroup->require_option(3);
    }

    std::pair<int, Request> createRequestMsg() override
    {
        Request requestMsg(
            sizeof(nsm_msg_hdr) +
            sizeof(nsm_multiport_query_scalar_group_telemetry_v2_req));
        auto request = reinterpret_cast<nsm_msg*>(requestMsg.data());
        const nsm_multiport_query_scalar_group_telemetry_v2_req_data data{
            .upstream_port_index = upstreamPortIndex,
            .type = type,
            .index = index,
            .group_index = groupId};
        auto rc = encode_multiport_query_scalar_group_telemetry_v2_req(
            instanceId, &data, request);
        return {rc, requestMsg};
    }

  private:
    uint8_t type;
    uint8_t upstreamPortIndex;
    uint8_t index;
};

class QueryAvailableAndClearableScalarGroup : public CommandInterface
{
  public:
    ~QueryAvailableAndClearableScalarGroup() = default;
    QueryAvailableAndClearableScalarGroup() = delete;
    QueryAvailableAndClearableScalarGroup(
        const QueryAvailableAndClearableScalarGroup&) = delete;
    QueryAvailableAndClearableScalarGroup(
        QueryAvailableAndClearableScalarGroup&&) = default;
    QueryAvailableAndClearableScalarGroup&
        operator=(const QueryAvailableAndClearableScalarGroup&) = delete;
    QueryAvailableAndClearableScalarGroup&
        operator=(QueryAvailableAndClearableScalarGroup&&) = default;

    using CommandInterface::CommandInterface;

    explicit QueryAvailableAndClearableScalarGroup(const char* type,
                                                   const char* name,
                                                   CLI::App* app) :
        CommandInterface(type, name, app)
    {
        auto scalarTelemetryOptionGroup = app->add_option_group(
            "Required", "Group Id for which data source is to be retrieved.");

        scalarTelemetryOptionGroup->add_option("-d, --deviceIndex", deviceIndex,
                                               "retrieve deviceIndex");
        scalarTelemetryOptionGroup->add_option(
            "-g, --groupId", groupId, "retrieve data source for groupId");
        scalarTelemetryOptionGroup->require_option(2);
    }

    std::pair<int, std::vector<uint8_t>> createRequestMsg() override
    {
        std::vector<uint8_t> requestMsg(
            sizeof(nsm_msg_hdr) +
            sizeof(nsm_query_scalar_group_telemetry_v1_req));
        auto request = reinterpret_cast<nsm_msg*>(requestMsg.data());
        auto rc = encode_query_available_clearable_scalar_data_sources_v1_req(
            instanceId, deviceIndex, groupId, request);
        return {rc, requestMsg};
    }

    void parseResponseMsg(nsm_msg* responsePtr, size_t payloadLength) override
    {
        uint8_t cc = NSM_ERROR;
        std::vector<std::string> clearableSource;
        std::vector<std::string> availableSource;
        switch (groupId)
        {
            case GROUP_ID_2:
            {
                bitfield8_t available_source[1];
                bitfield8_t clearable_source[1];
                uint8_t mask_length;
                uint16_t data_size;
                uint16_t reason_code = ERR_NULL;

                auto rc =
                    decode_query_available_clearable_scalar_data_sources_v1_resp(
                        responsePtr, payloadLength, &cc, &data_size,
                        &reason_code, &mask_length, (uint8_t*)available_source,
                        (uint8_t*)clearable_source);
                if (rc != NSM_SW_SUCCESS || cc != NSM_SUCCESS)
                {
                    std::cerr
                        << "Response message error: "
                        << "rc=" << rc << ", cc=" << (int)cc
                        << ", reasonCode=" << (int)reason_code << "\n"
                        << payloadLength << "...."
                        << (sizeof(nsm_msg_hdr) +
                            sizeof(
                                nsm_query_available_clearable_scalar_data_sources_v1_resp));

                    return;
                }

                ordered_json result;
                result["Completion Code"] = cc;
                if (available_source[0].bits.bit0)
                {
                    availableSource.push_back("TotalNonFatalErrors");
                }
                if (available_source[0].bits.bit1)
                {
                    availableSource.push_back("TotalFatalErrors");
                }
                if (available_source[0].bits.bit2)
                {
                    availableSource.push_back("UnsupportedRequestCounts");
                }
                if (available_source[0].bits.bit3)
                {
                    availableSource.push_back("CorrectableErrorCount");
                }
                result["AvailableSource"] = availableSource;

                if (clearable_source[0].bits.bit0)
                {
                    clearableSource.push_back("TotalNonFatalErrors");
                }
                if (clearable_source[0].bits.bit1)
                {
                    clearableSource.push_back("TotalFatalErrors");
                }
                if (clearable_source[0].bits.bit2)
                {
                    clearableSource.push_back("UnsupportedRequestCounts");
                }
                if (clearable_source[0].bits.bit3)
                {
                    clearableSource.push_back("CorresctableErrorCount");
                }
                result["ClearableSource"] = clearableSource;

                nsmtool::helper::DisplayInJson(result);
                break;
            }

            case GROUP_ID_3:
            {
                bitfield8_t available_source[1];
                bitfield8_t clearable_source[1];
                uint8_t mask_length;
                uint16_t data_size;
                uint16_t reason_code = ERR_NULL;

                auto rc =
                    decode_query_available_clearable_scalar_data_sources_v1_resp(
                        responsePtr, payloadLength, &cc, &data_size,
                        &reason_code, &mask_length, (uint8_t*)available_source,
                        (uint8_t*)clearable_source);
                if (rc != NSM_SW_SUCCESS || cc != NSM_SUCCESS)
                {
                    std::cerr
                        << "Response message error: "
                        << "rc=" << rc << ", cc=" << (int)cc
                        << ", reasonCode=" << (int)reason_code << "\n"
                        << payloadLength << "...."
                        << (sizeof(nsm_msg_hdr) +
                            sizeof(
                                nsm_query_available_clearable_scalar_data_sources_v1_resp));

                    return;
                }

                ordered_json result;
                result["Completion Code"] = cc;
                if (available_source[0].bits.bit0)
                {
                    availableSource.push_back("L0ToRecoveryCount");
                }
                result["AvailableSource"] = availableSource;

                if (clearable_source[0].bits.bit0)
                {
                    clearableSource.push_back("L0ToRecoveryCount");
                }
                result["ClearableSource"] = clearableSource;

                nsmtool::helper::DisplayInJson(result);
                break;
            }

            case GROUP_ID_4:
            {
                bitfield8_t available_source[1];
                bitfield8_t clearable_source[1];
                uint8_t mask_length;
                uint16_t data_size;
                uint16_t reason_code = ERR_NULL;

                auto rc =
                    decode_query_available_clearable_scalar_data_sources_v1_resp(
                        responsePtr, payloadLength, &cc, &data_size,
                        &reason_code, &mask_length, (uint8_t*)available_source,
                        (uint8_t*)clearable_source);
                if (rc != NSM_SW_SUCCESS || cc != NSM_SUCCESS)
                {
                    std::cerr
                        << "Response message error: "
                        << "rc=" << rc << ", cc=" << (int)cc
                        << ", reasonCode=" << (int)reason_code << "\n"
                        << payloadLength << "...."
                        << (sizeof(nsm_msg_hdr) +
                            sizeof(
                                nsm_query_available_clearable_scalar_data_sources_v1_resp));

                    return;
                }

                ordered_json result;
                result["Completion Code"] = cc;

                if (available_source[0].bits.bit0)
                {
                    availableSource.push_back("RecieverErrorCount");
                }
                if (available_source[0].bits.bit1)
                {
                    availableSource.push_back("NaksRecievedCount");
                }
                if (available_source[0].bits.bit2)
                {
                    availableSource.push_back("NaksSentCount");
                }
                if (available_source[0].bits.bit3)
                {
                    availableSource.push_back("BadTlpCount");
                }
                if (available_source[0].bits.bit4)
                {
                    availableSource.push_back("ReplayRollOverCount");
                }
                if (available_source[0].bits.bit5)
                {
                    availableSource.push_back("FcTimeoutErrorCount");
                }
                if (available_source[0].bits.bit6)
                {
                    availableSource.push_back("ReplayCount");
                }
                result["AvailableSource"] = availableSource;

                if (clearable_source[0].bits.bit0)
                {
                    clearableSource.push_back("RecieverErrorCount");
                }
                if (clearable_source[0].bits.bit1)
                {
                    clearableSource.push_back("NaksRecievedCount");
                }
                if (available_source[0].bits.bit2)
                {
                    clearableSource.push_back("NaksSentCount");
                }
                if (clearable_source[0].bits.bit3)
                {
                    clearableSource.push_back("BadTlpCount");
                }
                if (clearable_source[0].bits.bit4)
                {
                    clearableSource.push_back("ReplayRollOverCount");
                }
                if (clearable_source[0].bits.bit5)
                {
                    clearableSource.push_back("FcTimeoutErrorCount");
                }
                if (clearable_source[0].bits.bit6)
                {
                    clearableSource.push_back("ReplayCount");
                }
                result["clearableSource"] = clearableSource;

                nsmtool::helper::DisplayInJson(result);
                break;
            }
            case GROUP_ID_8:
            {
                bitfield8_t available_source[1];
                bitfield8_t clearable_source[1];
                uint8_t mask_length;
                uint16_t data_size;
                uint16_t reason_code = ERR_NULL;

                auto rc =
                    decode_query_available_clearable_scalar_data_sources_v1_resp(
                        responsePtr, payloadLength, &cc, &data_size,
                        &reason_code, &mask_length, (uint8_t*)available_source,
                        (uint8_t*)clearable_source);
                if (rc != NSM_SW_SUCCESS || cc != NSM_SUCCESS)
                {
                    std::cerr
                        << "Response message error: "
                        << "rc=" << rc << ", cc=" << (int)cc
                        << ", reasonCode=" << (int)reason_code << "\n"
                        << payloadLength << "...."
                        << (sizeof(nsm_msg_hdr) +
                            sizeof(
                                nsm_query_available_clearable_scalar_data_sources_v1_resp));

                    return;
                }

                ordered_json result;
                result["Completion Code"] = cc;
                if (available_source[0].bits.bit0)
                {
                    availableSource.push_back("PerLaneErrorCounts");
                }
                result["AvailableSource"] = availableSource;

                if (clearable_source[0].bits.bit0)
                {
                    clearableSource.push_back("PerLaneErrorCounts");
                }
                result["ClearableSource"] = clearableSource;

                nsmtool::helper::DisplayInJson(result);
                break;
            }

            case GROUP_ID_9:
            {
                bitfield8_t available_source[1];
                bitfield8_t clearable_source[1];
                uint8_t mask_length;
                uint16_t data_size;
                uint16_t reason_code = ERR_NULL;

                auto rc =
                    decode_query_available_clearable_scalar_data_sources_v1_resp(
                        responsePtr, payloadLength, &cc, &data_size,
                        &reason_code, &mask_length, (uint8_t*)available_source,
                        (uint8_t*)clearable_source);
                if (rc != NSM_SW_SUCCESS || cc != NSM_SUCCESS)
                {
                    std::cerr
                        << "Response message error: "
                        << "rc=" << rc << ", cc=" << (int)cc
                        << ", reasonCode=" << (int)reason_code << "\n"
                        << payloadLength << "...."
                        << (sizeof(nsm_msg_hdr) +
                            sizeof(
                                nsm_query_available_clearable_scalar_data_sources_v1_resp));

                    return;
                }

                ordered_json result;
                result["Completion Code"] = cc;
                if (available_source[0].bits.bit0)
                {
                    availableSource.push_back("AerUncorrectableErrorStatus");
                }
                if (available_source[0].bits.bit1)
                {
                    availableSource.push_back("AerCorrectableErrorStatus");
                }
                result["AvailableSource"] = availableSource;
                if (clearable_source[0].bits.bit0)
                {
                    clearableSource.push_back("AerUncorrectableErrorStatus");
                }

                if (clearable_source[0].bits.bit1)
                {
                    clearableSource.push_back("AerCorrectableErrorStatus");
                }
                result["ClearableSource"] = clearableSource;

                nsmtool::helper::DisplayInJson(result);
                break;
            }

            default:
            {
                std::cerr << "Invalid Group Id \n";
                break;
            }
        }
    }

  private:
    uint8_t deviceIndex;
    uint8_t groupId;
};

class PcieFundamentalReset : public CommandInterface
{
  public:
    ~PcieFundamentalReset() = default;
    PcieFundamentalReset() = delete;
    PcieFundamentalReset(const PcieFundamentalReset&) = delete;
    PcieFundamentalReset(PcieFundamentalReset&&) = default;
    PcieFundamentalReset& operator=(const PcieFundamentalReset&) = delete;
    PcieFundamentalReset& operator=(PcieFundamentalReset&&) = default;

    using CommandInterface::CommandInterface;

    explicit PcieFundamentalReset(const char* type, const char* name,
                                  CLI::App* app) :
        CommandInterface(type, name, app)
    {
        app->add_option("-d, --device_index", device_index,
                        "Device Index for which reset is performed")
            ->required();
        app->add_option("-a, --action", action,
                        "Action to be performed 0-Not reset 1-reset")
            ->required();
    }

    std::pair<int, std::vector<uint8_t>> createRequestMsg() override
    {
        std::vector<uint8_t> requestMsg(
            sizeof(nsm_msg_hdr) +
            sizeof(nsm_assert_pcie_fundamental_reset_req));
        auto request = reinterpret_cast<nsm_msg*>(requestMsg.data());
        auto rc = encode_assert_pcie_fundamental_reset_req(
            instanceId, device_index, action, request);
        return {rc, requestMsg};
    }

    void parseResponseMsg(nsm_msg* responsePtr, size_t payloadLength) override
    {
        uint8_t cc = NSM_ERROR;
        uint16_t data_size;
        uint16_t reason_code = ERR_NULL;
        auto rc = decode_assert_pcie_fundamental_reset_resp(
            responsePtr, payloadLength, &cc, &data_size, &reason_code);
        if (rc != NSM_SW_SUCCESS || cc != NSM_SUCCESS)
        {
            std::cerr << "Response message error: "
                      << "rc=" << rc << ", cc=" << (int)cc
                      << ", reasonCode=" << (int)reason_code << "\n"
                      << payloadLength << "...."
                      << (sizeof(struct nsm_msg_hdr) +
                          sizeof(struct nsm_common_resp));

            return;
        }

        ordered_json result;
        result["Completion Code"] = cc;
        nsmtool::helper::DisplayInJson(result);
    }

    uint8_t device_index;
    uint8_t action;
};

class ClearScalarDataSource : public CommandInterface
{
  public:
    ~ClearScalarDataSource() = default;
    ClearScalarDataSource() = delete;
    ClearScalarDataSource(const ClearScalarDataSource&) = delete;
    ClearScalarDataSource(ClearScalarDataSource&&) = default;
    ClearScalarDataSource& operator=(const ClearScalarDataSource&) = delete;
    ClearScalarDataSource& operator=(ClearScalarDataSource&&) = default;

    using CommandInterface::CommandInterface;

    explicit ClearScalarDataSource(const char* type, const char* name,
                                   CLI::App* app) :
        CommandInterface(type, name, app)
    {
        app->add_option("-d, --device_index", device_index,
                        "Device Index for which reset is performed")
            ->required();
        app->add_option("-g, --groupId", groupId,
                        "Identifier of group to query")
            ->required();
        app->add_option("-i, --dsId", dsId,
                        "Index of data source within the group")
            ->required();
    }

    std::pair<int, std::vector<uint8_t>> createRequestMsg() override
    {
        std::vector<uint8_t> requestMsg(sizeof(nsm_msg_hdr) +
                                        sizeof(nsm_clear_data_source_v1_req));
        auto request = reinterpret_cast<nsm_msg*>(requestMsg.data());
        auto rc = encode_clear_data_source_v1_req(instanceId, device_index,
                                                  groupId, dsId, request);
        return {rc, requestMsg};
    }

    void parseResponseMsg(nsm_msg* responsePtr, size_t payloadLength) override
    {
        uint8_t cc = NSM_ERROR;
        uint16_t data_size;
        uint16_t reason_code = ERR_NULL;
        auto rc = decode_clear_data_source_v1_resp(
            responsePtr, payloadLength, &cc, &data_size, &reason_code);
        if (rc != NSM_SW_SUCCESS || cc != NSM_SUCCESS)
        {
            std::cerr << "Response message error: "
                      << "rc=" << rc << ", cc=" << (int)cc
                      << ", reasonCode=" << (int)reason_code << "\n"
                      << payloadLength << "...."
                      << (sizeof(struct nsm_msg_hdr) +
                          sizeof(struct nsm_common_resp));

            return;
        }

        ordered_json result;
        result["Completion Code"] = cc;
        nsmtool::helper::DisplayInJson(result);
    }

    uint8_t device_index;
    uint8_t groupId;
    uint8_t dsId;
};

class GetClockLimit : public CommandInterface
{
  public:
    ~GetClockLimit() = default;
    GetClockLimit() = delete;
    GetClockLimit(const GetClockLimit&) = delete;
    GetClockLimit(GetClockLimit&&) = default;
    GetClockLimit& operator=(const GetClockLimit&) = delete;
    GetClockLimit& operator=(GetClockLimit&&) = default;

    using CommandInterface::CommandInterface;

    explicit GetClockLimit(const char* type, const char* name, CLI::App* app) :
        CommandInterface(type, name, app)
    {
        auto clockLimitOptionGroup = app->add_option_group(
            "Required",
            "Clock Id for which Limit is to be retrieved Graphics(0)/Memory(1).");

        clockId = 2;
        clockLimitOptionGroup->add_option("-c, --clockId", clockId,
                                          "retrieve clock Limit for clockId");
        clockLimitOptionGroup->require_option(1);
    }

    std::pair<int, std::vector<uint8_t>> createRequestMsg() override
    {
        std::vector<uint8_t> requestMsg(sizeof(nsm_msg_hdr) +
                                        sizeof(nsm_get_clock_limit_req));
        auto request = reinterpret_cast<nsm_msg*>(requestMsg.data());
        auto rc = encode_get_clock_limit_req(instanceId, clockId, request);
        return {rc, requestMsg};
    }

    void parseResponseMsg(nsm_msg* responsePtr, size_t payloadLength) override
    {
        uint8_t cc = NSM_ERROR;
        struct nsm_clock_limit clockLimit;
        uint16_t data_size;
        uint16_t reason_code = ERR_NULL;

        auto rc = decode_get_clock_limit_resp(responsePtr, payloadLength, &cc,
                                              &data_size, &reason_code,
                                              &clockLimit);
        if (rc != NSM_SW_SUCCESS || cc != NSM_SUCCESS)
        {
            std::cerr << "Response message error: "
                      << "rc=" << rc << ", cc=" << (int)cc
                      << ", reasonCode=" << (int)reason_code << "\n"
                      << payloadLength << "...."
                      << (sizeof(struct nsm_msg_hdr) +
                          sizeof(struct nsm_get_clock_limit_resp));

            return;
        }

        ordered_json result;
        result["Completion Code"] = cc;
        result["SpeedLimit"] = (uint32_t)clockLimit.present_limit_max;
        result["PresentLimitMin"] = (uint32_t)clockLimit.present_limit_min;
        result["PresentLimitMax"] = (uint32_t)clockLimit.present_limit_max;
        result["RequestedLimitMax"] = (uint32_t)clockLimit.requested_limit_max;
        result["RequestedLimitMin"] = (uint32_t)clockLimit.requested_limit_min;
        if (clockLimit.present_limit_min == clockLimit.present_limit_max)
        {
            result["SpeedLocked"] = true;
            result["SpeedConfig"] =
                std::make_tuple(true, (uint32_t)clockLimit.present_limit_max);
        }
        else
        {
            result["SpeedLocked"] = false;
            result["SpeedConfig"] =
                std::make_tuple(false, (uint32_t)clockLimit.present_limit_max);
        }
        nsmtool::helper::DisplayInJson(result);
    }

  private:
    uint8_t clockId;
};

class GetCurrClockFreq : public CommandInterface
{
  public:
    ~GetCurrClockFreq() = default;
    GetCurrClockFreq() = delete;
    GetCurrClockFreq(const GetCurrClockFreq&) = delete;
    GetCurrClockFreq(GetCurrClockFreq&&) = default;
    GetCurrClockFreq& operator=(const GetCurrClockFreq&) = delete;
    GetCurrClockFreq& operator=(GetCurrClockFreq&&) = default;

    using CommandInterface::CommandInterface;

    explicit GetCurrClockFreq(const char* type, const char* name,
                              CLI::App* app) : CommandInterface(type, name, app)
    {
        auto currClockFreqOptionGroup = app->add_option_group(
            "Required",
            "Clock Id for which Limit is to be retrieved Graphics(0)/Memory(1).");

        currClockFreqOptionGroup->add_option(
            "-c, --clockId", clockId, "retrieve clock Limit for clockId");
        currClockFreqOptionGroup->require_option(1);
    }

    std::pair<int, std::vector<uint8_t>> createRequestMsg() override
    {
        std::vector<uint8_t> requestMsg(sizeof(nsm_msg_hdr) +
                                        sizeof(nsm_get_curr_clock_freq_req));
        auto request = reinterpret_cast<nsm_msg*>(requestMsg.data());

        auto rc = encode_get_curr_clock_freq_req(instanceId, clockId, request);
        return {rc, requestMsg};
    }

    void parseResponseMsg(nsm_msg* responsePtr, size_t payloadLength) override
    {
        uint8_t cc = NSM_ERROR;
        uint32_t clockFreq = 2;
        uint16_t data_size;
        uint16_t reason_code = ERR_NULL;

        auto rc = decode_get_curr_clock_freq_resp(responsePtr, payloadLength,
                                                  &cc, &data_size, &reason_code,
                                                  &clockFreq);
        if (rc != NSM_SW_SUCCESS || cc != NSM_SUCCESS)
        {
            std::cerr << "Response message error: "
                      << "rc=" << rc << ", cc=" << (int)cc
                      << ", reasonCode=" << (int)reason_code << "\n"
                      << payloadLength << "...."
                      << (sizeof(struct nsm_msg_hdr) +
                          sizeof(struct nsm_get_curr_clock_freq_resp));

            return;
        }

        ordered_json result;
        result["Completion Code"] = cc;
        result["OperatingSpeed"] = clockFreq;
        nsmtool::helper::DisplayInJson(result);
    }

  private:
    uint8_t clockId;
};

class GetProcessorThrottleReason : public CommandInterface
{
  public:
    ~GetProcessorThrottleReason() = default;
    GetProcessorThrottleReason() = delete;
    GetProcessorThrottleReason(const GetMigMode&) = delete;
    GetProcessorThrottleReason(GetProcessorThrottleReason&&) = default;
    GetProcessorThrottleReason&
        operator=(const GetProcessorThrottleReason&) = delete;
    GetProcessorThrottleReason&
        operator=(GetProcessorThrottleReason&&) = default;

    using CommandInterface::CommandInterface;

    std::pair<int, std::vector<uint8_t>> createRequestMsg() override
    {
        std::vector<uint8_t> requestMsg(sizeof(nsm_msg_hdr) +
                                        sizeof(nsm_common_req));
        auto request = reinterpret_cast<nsm_msg*>(requestMsg.data());
        auto rc = encode_get_current_clock_event_reason_code_req(instanceId,
                                                                 request);
        return {rc, requestMsg};
    }

    void parseResponseMsg(nsm_msg* responsePtr, size_t payloadLength) override
    {
        uint8_t cc = NSM_ERROR;
        bitfield32_t flags;
        uint16_t data_size;
        uint16_t reason_code = ERR_NULL;
        auto rc = decode_get_current_clock_event_reason_code_resp(
            responsePtr, payloadLength, &cc, &data_size, &reason_code, &flags);
        if (rc != NSM_SW_SUCCESS || cc != NSM_SUCCESS)
        {
            std::cerr
                << "Response message error: "
                << "rc=" << rc << ", cc=" << (int)cc
                << ", reasonCode=" << (int)reason_code << "\n"
                << payloadLength << "...."
                << (sizeof(struct nsm_msg_hdr) +
                    sizeof(
                        struct nsm_get_current_clock_event_reason_code_resp));

            return;
        }

        ordered_json result;
        result["Completion Code"] = cc;
        std::vector<std::string> throttleReasons;
        if (flags.bits.bit0)
        {
            throttleReasons.push_back(
                "xyz.openbmc_project.State.ProcessorPerformance.ThrottleReasons.SWPowerCap");
        }
        if (flags.bits.bit1)
        {
            throttleReasons.push_back(
                "xyz.openbmc_project.State.ProcessorPerformance.ThrottleReasons.HWSlowdown");
        }
        if (flags.bits.bit2)
        {
            throttleReasons.push_back(
                "xyz.openbmc_project.State.ProcessorPerformance.ThrottleReasons.HWThermalSlowdown");
        }
        if (flags.bits.bit3)
        {
            throttleReasons.push_back(
                "xyz.openbmc_project.State.ProcessorPerformance.ThrottleReasons.HWPowerBrakeSlowdown");
        }
        if (flags.bits.bit4)
        {
            throttleReasons.push_back(
                "xyz.openbmc_project.State.ProcessorPerformance.ThrottleReasons.SyncBoost");
        }
        if (flags.bits.bit5)
        {
            throttleReasons.push_back(
                "xyz.openbmc_project.State.ProcessorPerformance.ThrottleReasons.ClockOptimizedForThermalEngage");
        }

        result["ThrottleReasons"] = throttleReasons;
        nsmtool::helper::DisplayInJson(result);
    }
};

class SetPowerLimit : public CommandInterface
{
  public:
    ~SetPowerLimit() = default;
    SetPowerLimit() = delete;
    SetPowerLimit(const SetPowerLimit&) = delete;
    SetPowerLimit(SetPowerLimit&&) = default;
    SetPowerLimit& operator=(const SetPowerLimit&) = delete;
    SetPowerLimit& operator=(SetPowerLimit&&) = default;

    using CommandInterface::CommandInterface;

    explicit SetPowerLimit(const char* type, const char* name, CLI::App* app) :
        CommandInterface(type, name, app)
    {
        app->add_option("-i, --powerLimitId", powerLimitId,
                        "Power Limit Id Device/Module")
            ->required();

        app->add_option("-a, --action", action,
                        "action to be performed on power limit")
            ->required();

        app->add_option("-p, --persistence", persistence,
                        "Lifetime of new power limit")
            ->required();

        app->add_option("-l, --power_limit", power_limit,
                        "Device power Limit in miliwatts")
            ->required();
    }

    std::pair<int, std::vector<uint8_t>> createRequestMsg() override
    {
        std::vector<uint8_t> requestMsg(sizeof(nsm_msg_hdr) +
                                        sizeof(nsm_set_power_limit_req));
        auto request = reinterpret_cast<nsm_msg*>(requestMsg.data());

        int rc = NSM_SW_ERROR_DATA;
        if (powerLimitId == DEVICE)
        {
            rc = encode_set_device_power_limit_req(
                instanceId, action, persistence, power_limit, request);
        }
        else if (powerLimitId == MODULE)
        {
            rc = encode_set_module_power_limit_req(
                instanceId, action, persistence, power_limit, request);
        }
        return {rc, requestMsg};
    }

    void parseResponseMsg(nsm_msg* responsePtr, size_t payloadLength) override
    {
        uint8_t cc = NSM_ERROR;
        uint16_t data_size;
        uint16_t reason_code = ERR_NULL;
        auto rc = decode_set_power_limit_resp(responsePtr, payloadLength, &cc,
                                              &data_size, &reason_code);
        if (rc != NSM_SW_SUCCESS || cc != NSM_SUCCESS)
        {
            std::cerr << "Response message error: "
                      << "rc=" << rc << ", cc=" << (int)cc
                      << ", reasonCode=" << (int)reason_code << "\n"
                      << payloadLength << "...."
                      << (sizeof(struct nsm_msg_hdr) +
                          sizeof(struct nsm_common_resp));

            return;
        }

        ordered_json result;
        result["Completion Code"] = cc;
        nsmtool::helper::DisplayInJson(result);
    }

    uint32_t powerLimitId;
    uint8_t action;
    uint8_t persistence;
    uint32_t power_limit;
};

class GetPowerLimit : public CommandInterface
{
  public:
    ~GetPowerLimit() = default;
    GetPowerLimit() = delete;
    GetPowerLimit(const GetPowerLimit&) = delete;
    GetPowerLimit(GetPowerLimit&&) = default;
    GetPowerLimit& operator=(const GetPowerLimit&) = delete;
    GetPowerLimit& operator=(GetPowerLimit&&) = default;

    using CommandInterface::CommandInterface;

    explicit GetPowerLimit(const char* type, const char* name, CLI::App* app) :
        CommandInterface(type, name, app)
    {
        app->add_option("-i, --powerLimitId", powerLimitId,
                        "Power Limit Id Device/Module")
            ->required();
    }

    std::pair<int, std::vector<uint8_t>> createRequestMsg() override
    {
        std::vector<uint8_t> requestMsg(sizeof(nsm_msg_hdr) +
                                        sizeof(nsm_get_power_limit_req));
        auto request = reinterpret_cast<nsm_msg*>(requestMsg.data());

        int rc = NSM_SW_ERROR_DATA;
        if (powerLimitId == DEVICE)
        {
            rc = encode_get_device_power_limit_req(instanceId, request);
        }
        else if (powerLimitId == MODULE)
        {
            rc = encode_get_module_power_limit_req(instanceId, request);
        }
        return {rc, requestMsg};
    }

    void parseResponseMsg(nsm_msg* responsePtr, size_t payloadLength) override
    {
        uint8_t cc = NSM_ERROR;
        uint16_t data_size;
        uint16_t reason_code = ERR_NULL;
        uint32_t requestedPersistentLimit;
        uint32_t requestedOneShotlimit;
        uint32_t enforcedLimit;
        auto rc = decode_get_power_limit_resp(
            responsePtr, payloadLength, &cc, &data_size, &reason_code,
            &requestedPersistentLimit, &requestedOneShotlimit, &enforcedLimit);
        if (rc != NSM_SW_SUCCESS || cc != NSM_SUCCESS)
        {
            std::cerr << "Response message error: "
                      << "rc=" << rc << ", cc=" << (int)cc
                      << ", reasonCode=" << (int)reason_code << "\n"
                      << payloadLength << "...."
                      << (sizeof(struct nsm_msg_hdr) +
                          sizeof(struct nsm_get_power_limit_resp));

            return;
        }

        ordered_json result;
        result["Completion Code"] = cc;
        result["requestedPersistentLimit"] = requestedPersistentLimit;
        result["requestedOneShotlimit"] = requestedOneShotlimit;
        result["enforcedLimit"] = enforcedLimit;
        nsmtool::helper::DisplayInJson(result);
    }

    uint32_t powerLimitId;
};

class GetAccumGpuUtilTime : public CommandInterface
{
  public:
    ~GetAccumGpuUtilTime() = default;
    GetAccumGpuUtilTime() = delete;
    GetAccumGpuUtilTime(const GetAccumGpuUtilTime&) = delete;
    GetAccumGpuUtilTime(GetAccumGpuUtilTime&&) = default;
    GetAccumGpuUtilTime& operator=(const GetAccumGpuUtilTime&) = delete;
    GetAccumGpuUtilTime& operator=(GetAccumGpuUtilTime&&) = default;

    using CommandInterface::CommandInterface;

    std::pair<int, std::vector<uint8_t>> createRequestMsg() override
    {
        std::vector<uint8_t> requestMsg(sizeof(nsm_msg_hdr) +
                                        sizeof(nsm_common_req));
        auto request = reinterpret_cast<nsm_msg*>(requestMsg.data());
        auto rc = encode_get_accum_GPU_util_time_req(instanceId, request);
        return {rc, requestMsg};
    }

    void parseResponseMsg(nsm_msg* responsePtr, size_t payloadLength) override
    {
        uint8_t cc = NSM_ERROR;
        uint32_t context_util_time;
        uint32_t SM_util_time;
        uint16_t data_size;
        uint16_t reason_code = ERR_NULL;
        auto rc = decode_get_accum_GPU_util_time_resp(
            responsePtr, payloadLength, &cc, &data_size, &reason_code,
            &context_util_time, &SM_util_time);
        if (rc != NSM_SW_SUCCESS || cc != NSM_SUCCESS)
        {
            std::cerr << "Response message error: "
                      << "rc=" << rc << ", cc=" << (int)cc
                      << ", reasonCode=" << (int)reason_code << "\n"
                      << payloadLength << "...."
                      << (sizeof(struct nsm_msg_hdr) +
                          sizeof(struct nsm_get_accum_GPU_util_time_resp));

            return;
        }

        ordered_json result;
        result["Completion Code"] = cc;
        result["AccumulatedGPUContextUtilizationDuration"] =
            (int)context_util_time;
        result["AccumulatedSMUtilizationDuration"] = (int)SM_util_time;

        nsmtool::helper::DisplayInJson(result);
    }
};

class GetRowRemapState : public CommandInterface
{
  public:
    ~GetRowRemapState() = default;
    GetRowRemapState() = delete;
    GetRowRemapState(const GetRowRemapState&) = delete;
    GetRowRemapState(GetRowRemapState&&) = default;
    GetRowRemapState& operator=(const GetRowRemapState&) = delete;
    GetRowRemapState& operator=(GetRowRemapState&&) = default;

    using CommandInterface::CommandInterface;

    std::pair<int, std::vector<uint8_t>> createRequestMsg() override
    {
        std::vector<uint8_t> requestMsg(sizeof(nsm_msg_hdr) +
                                        sizeof(nsm_common_req));
        auto request = reinterpret_cast<nsm_msg*>(requestMsg.data());
        auto rc = encode_get_row_remap_state_req(instanceId, request);
        return {rc, requestMsg};
    }

    void parseResponseMsg(nsm_msg* responsePtr, size_t payloadLength) override
    {
        uint8_t cc = NSM_ERROR;
        bitfield8_t flags;
        uint16_t data_size;
        uint16_t reason_code = ERR_NULL;
        auto rc = decode_get_row_remap_state_resp(
            responsePtr, payloadLength, &cc, &data_size, &reason_code, &flags);
        if (rc != NSM_SW_SUCCESS || cc != NSM_SUCCESS)
        {
            std::cerr << "Response message error: "
                      << "rc=" << rc << ", cc=" << (int)cc
                      << ", reasonCode=" << (int)reason_code << "\n"
                      << payloadLength << "...."
                      << (sizeof(struct nsm_msg_hdr) +
                          sizeof(struct nsm_get_row_remap_state_resp));

            return;
        }

        ordered_json result;
        result["Completion Code"] = cc;
        if (flags.bits.bit0)
        {
            result["RowRemappingFailureState"] = true;
        }
        else
        {
            result["RowRemappingFailureState"] = false;
        }
        if (flags.bits.bit1)
        {
            result["RowRemappingPendingState"] = true;
        }
        else
        {
            result["RowRemappingPendingState"] = false;
        }
        nsmtool::helper::DisplayInJson(result);
    }
};

class GetRowRemappingCounts : public CommandInterface
{
  public:
    ~GetRowRemappingCounts() = default;
    GetRowRemappingCounts() = delete;
    GetRowRemappingCounts(const GetRowRemappingCounts&) = delete;
    GetRowRemappingCounts(GetRowRemappingCounts&&) = default;
    GetRowRemappingCounts& operator=(const GetRowRemappingCounts&) = delete;
    GetRowRemappingCounts& operator=(GetRowRemappingCounts&&) = default;

    using CommandInterface::CommandInterface;

    std::pair<int, std::vector<uint8_t>> createRequestMsg() override
    {
        std::vector<uint8_t> requestMsg(sizeof(nsm_msg_hdr) +
                                        sizeof(nsm_common_req));
        auto request = reinterpret_cast<nsm_msg*>(requestMsg.data());
        auto rc = encode_get_row_remapping_counts_req(instanceId, request);
        return {rc, requestMsg};
    }

    void parseResponseMsg(nsm_msg* responsePtr, size_t payloadLength) override
    {
        uint8_t cc = NSM_ERROR;
        uint32_t correctable_error;
        uint32_t uncorrectable_error;
        uint16_t data_size;
        uint16_t reason_code = ERR_NULL;
        auto rc = decode_get_row_remapping_counts_resp(
            responsePtr, payloadLength, &cc, &data_size, &reason_code,
            &correctable_error, &uncorrectable_error);
        if (rc != NSM_SW_SUCCESS || cc != NSM_SUCCESS)
        {
            std::cerr << "Response message error: "
                      << "rc=" << rc << ", cc=" << (int)cc
                      << ", reasonCode=" << (int)reason_code << "\n"
                      << payloadLength << "...."
                      << (sizeof(struct nsm_msg_hdr) +
                          sizeof(struct nsm_get_row_remapping_counts_resp));

            return;
        }

        ordered_json result;
        result["Completion Code"] = cc;
        result["ceRowRemappingCount"] = correctable_error;
        result["ueRowRemappingCount"] = uncorrectable_error;
        nsmtool::helper::DisplayInJson(result);
    }
};

class GetRowRemapAvailability : public CommandInterface
{
  public:
    ~GetRowRemapAvailability() = default;
    GetRowRemapAvailability() = delete;
    GetRowRemapAvailability(const GetRowRemapAvailability&) = delete;
    GetRowRemapAvailability(GetRowRemapAvailability&&) = default;
    GetRowRemapAvailability& operator=(const GetRowRemapAvailability&) = delete;
    GetRowRemapAvailability& operator=(GetRowRemapAvailability&&) = default;

    using CommandInterface::CommandInterface;

    std::pair<int, std::vector<uint8_t>> createRequestMsg() override
    {
        std::vector<uint8_t> requestMsg(sizeof(nsm_msg_hdr) +
                                        sizeof(nsm_common_req));
        auto request = reinterpret_cast<nsm_msg*>(requestMsg.data());
        auto rc = encode_get_row_remap_availability_req(instanceId, request);
        return {rc, requestMsg};
    }

    void parseResponseMsg(nsm_msg* responsePtr, size_t payloadLength) override
    {
        uint8_t cc = NSM_ERROR;
        struct nsm_row_remap_availability data;
        uint16_t data_size;
        uint16_t reason_code = ERR_NULL;
        auto rc = decode_get_row_remap_availability_resp(
            responsePtr, payloadLength, &cc, &data_size, &reason_code, &data);
        if (rc != NSM_SW_SUCCESS || cc != NSM_SUCCESS)
        {
            std::cerr << "Response message error: "
                      << "rc=" << rc << ", cc=" << (int)cc
                      << ", reasonCode=" << (int)reason_code << "\n"
                      << payloadLength << "...."
                      << (sizeof(struct nsm_msg_hdr) +
                          sizeof(struct nsm_get_row_remap_availability_resp));

            return;
        }

        ordered_json result;
        result["Completion Code"] = cc;
        result["NoRemappingAvailability"] = (uint16_t)data.no_remapping;
        result["LowRemappingAvaialability"] = (uint16_t)data.low_remapping;
        result["PartialRemappingAvailability"] =
            (uint16_t)data.partial_remapping;
        result["HighRemappingAvailability"] = (uint16_t)data.high_remapping;
        result["MaxRemappingAvailability"] = (uint16_t)data.max_remapping;
        nsmtool::helper::DisplayInJson(result);
    }
};

class GetMemoryCapacityUtil : public CommandInterface
{
  public:
    ~GetMemoryCapacityUtil() = default;
    GetMemoryCapacityUtil() = delete;
    GetMemoryCapacityUtil(const GetMemoryCapacityUtil&) = delete;
    GetMemoryCapacityUtil(GetMemoryCapacityUtil&&) = default;
    GetMemoryCapacityUtil& operator=(const GetMemoryCapacityUtil&) = delete;
    GetMemoryCapacityUtil& operator=(GetMemoryCapacityUtil&&) = default;

    using CommandInterface::CommandInterface;

    std::pair<int, std::vector<uint8_t>> createRequestMsg() override
    {
        std::vector<uint8_t> requestMsg(sizeof(nsm_msg_hdr) +
                                        sizeof(nsm_common_req));
        auto request = reinterpret_cast<nsm_msg*>(requestMsg.data());
        auto rc = encode_get_memory_capacity_util_req(instanceId, request);
        return {rc, requestMsg};
    }

    void parseResponseMsg(nsm_msg* responsePtr, size_t payloadLength) override
    {
        uint8_t cc = NSM_ERROR;
        struct nsm_memory_capacity_utilization data;
        uint16_t data_size;
        uint16_t reason_code = ERR_NULL;
        auto rc = decode_get_memory_capacity_util_resp(
            responsePtr, payloadLength, &cc, &data_size, &reason_code, &data);
        if (rc != NSM_SW_SUCCESS || cc != NSM_SUCCESS)
        {
            std::cerr << "Response message error: "
                      << "rc=" << rc << ", cc=" << (int)cc
                      << ", reasonCode=" << (int)reason_code << "\n"
                      << payloadLength << "...."
                      << (sizeof(struct nsm_msg_hdr) +
                          sizeof(struct nsm_get_memory_capacity_util_resp));

            return;
        }

        ordered_json result;
        result["Completion Code"] = cc;
        result["UsedMemory"] = static_cast<uint32_t>(data.used_memory);
        result["ReservedMemory"] = static_cast<uint32_t>(data.reserved_memory);
        nsmtool::helper::DisplayInJson(result);
    }
};

class GetCurrentUtilization : public CommandInterface
{
  public:
    ~GetCurrentUtilization() = default;
    GetCurrentUtilization() = delete;
    GetCurrentUtilization(const GetCurrentUtilization&) = delete;
    GetCurrentUtilization(GetCurrentUtilization&&) = default;
    GetCurrentUtilization& operator=(const GetCurrentUtilization&) = delete;
    GetCurrentUtilization& operator=(GetCurrentUtilization&&) = default;

    using CommandInterface::CommandInterface;

    std::pair<int, std::vector<uint8_t>> createRequestMsg() override
    {
        std::vector<uint8_t> requestMsg(sizeof(nsm_msg_hdr) +
                                        sizeof(nsm_common_req));
        auto request = reinterpret_cast<nsm_msg*>(requestMsg.data());
        auto rc = encode_get_current_utilization_req(instanceId, request);
        return {rc, requestMsg};
    }

    void parseResponseMsg(nsm_msg* responsePtr, size_t payloadLength) override
    {
        uint8_t cc = NSM_ERROR;
        nsm_get_current_utilization_data data;
        uint16_t data_size;
        uint16_t reason_code = ERR_NULL;

        auto rc = decode_get_current_utilization_resp(
            responsePtr, payloadLength, &cc, &data_size, &reason_code, &data);

        if (rc != NSM_SW_SUCCESS || cc != NSM_SUCCESS)
        {
            std::cerr << "Response message error: "
                      << "rc=" << rc << ", cc=" << (int)cc
                      << ", reasonCode=" << (int)reason_code << "\n"
                      << payloadLength << "...."
                      << (sizeof(struct nsm_msg_hdr) +
                          sizeof(struct nsm_get_current_utilization_resp))
                      << '\n';

            return;
        }

        ordered_json result;
        result["Completion Code"] = cc;
        result["GPU Utilizatin"] = uint32_t(data.gpu_utilization);
        result["Memory Utilizatin"] = uint32_t(data.memory_utilization);
        nsmtool::helper::DisplayInJson(result);
    }
};

class GetClockOutputEnableState : public CommandInterface
{
  public:
    ~GetClockOutputEnableState() = default;
    GetClockOutputEnableState() = delete;
    GetClockOutputEnableState(const GetClockOutputEnableState&) = delete;
    GetClockOutputEnableState(GetClockOutputEnableState&&) = default;
    GetClockOutputEnableState&
        operator=(const GetClockOutputEnableState&) = delete;
    GetClockOutputEnableState& operator=(GetClockOutputEnableState&&) = default;

    using CommandInterface::CommandInterface;

    explicit GetClockOutputEnableState(const char* type, const char* name,
                                       CLI::App* app) :
        CommandInterface(type, name, app)
    {
        auto clockBufOptionGroup = app->add_option_group(
            "Required",
            "Index for which clock buffer is to be retrieved [PCIe(0x80)/NVHS(0x81)/IBLink(0x82)]");

        index = 00;
        clockBufOptionGroup->add_option("-i, --index", index,
                                        "retrieve clock buffer for Index");
        clockBufOptionGroup->require_option(1);
    }

    std::pair<int, std::vector<uint8_t>> createRequestMsg() override
    {
        std::vector<uint8_t> requestMsg(
            sizeof(nsm_msg_hdr) +
            sizeof(nsm_get_clock_output_enabled_state_req));
        auto request = reinterpret_cast<nsm_msg*>(requestMsg.data());
        auto rc = encode_get_clock_output_enable_state_req(instanceId, index,
                                                           request);
        return {rc, requestMsg};
    }

    void parseResponseMsg(nsm_msg* responsePtr, size_t payloadLength) override
    {
        uint8_t cc = NSM_SUCCESS;
        uint16_t reasonCode = ERR_NULL;
        uint16_t dataLen = 0;
        uint32_t clkBuf = 0;

        auto rc = decode_get_clock_output_enable_state_resp(
            responsePtr, payloadLength, &cc, &reasonCode, &dataLen, &clkBuf);

        if (rc == NSM_SW_SUCCESS && cc == NSM_SUCCESS)
        {
            printClockBufferData(clkBuf);
        }
        else
        {
            std::cerr
                << "Response message error: decode_get_clock_output_enable_state_resp fail"
                << "rc=" << rc << ", cc=" << (int)cc
                << ", reasonCode=" << (int)reasonCode << "\n";
            return;
        }
        return;
    }

    void printClockBufferData(uint32_t& data)
    {
        ordered_json result;
        result["Index"] = index;
        ordered_json clockBufferResult;

        switch (index)
        {
            case PCIE_CLKBUF_INDEX:
            {
                auto clockBuffer =
                    reinterpret_cast<nsm_pcie_clock_buffer_data*>(&data);
                clockBufferResult["GPU PCIe Clock 1"] =
                    static_cast<int>(clockBuffer->clk_buf_gpu1);
                clockBufferResult["GPU PCIe Clock 2"] =
                    static_cast<int>(clockBuffer->clk_buf_gpu2);
                clockBufferResult["GPU PCIe Clock 3"] =
                    static_cast<int>(clockBuffer->clk_buf_gpu3);
                clockBufferResult["GPU PCIe Clock 4"] =
                    static_cast<int>(clockBuffer->clk_buf_gpu4);
                clockBufferResult["GPU PCIe Clock 5"] =
                    static_cast<int>(clockBuffer->clk_buf_gpu5);
                clockBufferResult["GPU PCIe Clock 6"] =
                    static_cast<int>(clockBuffer->clk_buf_gpu6);
                clockBufferResult["GPU PCIe Clock 7"] =
                    static_cast<int>(clockBuffer->clk_buf_gpu7);
                clockBufferResult["GPU PCIe Clock 8"] =
                    static_cast<int>(clockBuffer->clk_buf_gpu8);

                clockBufferResult["Retimer PCIe Clock 1"] =
                    static_cast<int>(clockBuffer->clk_buf_retimer1);
                clockBufferResult["Retimer PCIe Clock 2"] =
                    static_cast<int>(clockBuffer->clk_buf_retimer2);
                clockBufferResult["Retimer PCIe Clock 3"] =
                    static_cast<int>(clockBuffer->clk_buf_retimer3);
                clockBufferResult["Retimer PCIe Clock 4"] =
                    static_cast<int>(clockBuffer->clk_buf_retimer4);
                clockBufferResult["Retimer PCIe Clock 5"] =
                    static_cast<int>(clockBuffer->clk_buf_retimer5);
                clockBufferResult["Retimer PCIe Clock 6"] =
                    static_cast<int>(clockBuffer->clk_buf_retimer6);
                clockBufferResult["Retimer PCIe Clock 7"] =
                    static_cast<int>(clockBuffer->clk_buf_retimer7);
                clockBufferResult["Retimer PCIe Clock 8"] =
                    static_cast<int>(clockBuffer->clk_buf_retimer8);

                clockBufferResult["NvSwitch PCIe Clock 1"] =
                    static_cast<int>(clockBuffer->clk_buf_nvSwitch_1);
                clockBufferResult["NvSwitch PCIe Clock 2"] =
                    static_cast<int>(clockBuffer->clk_buf_nvSwitch_2);

                clockBufferResult["NvLink Mgmt NIC PCIe Clock"] =
                    static_cast<int>(clockBuffer->clk_buf_nvlinkMgmt_nic);
            }
            break;
            case NVHS_CLKBUF_INDEX:
            {
                auto clockBuffer =
                    reinterpret_cast<nsm_nvhs_clock_buffer_data*>(&data);
                clockBufferResult["SXM NVHS Clock 1"] =
                    static_cast<int>(clockBuffer->clk_buf_sxm_nvhs1);
                clockBufferResult["SXM NVHS Clock 2"] =
                    static_cast<int>(clockBuffer->clk_buf_sxm_nvhs2);
                clockBufferResult["SXM NVHS Clock 3"] =
                    static_cast<int>(clockBuffer->clk_buf_sxm_nvhs3);
                clockBufferResult["SXM NVHS Clock 4"] =
                    static_cast<int>(clockBuffer->clk_buf_sxm_nvhs4);
                clockBufferResult["SXM NVHS Clock 5"] =
                    static_cast<int>(clockBuffer->clk_buf_sxm_nvhs5);
                clockBufferResult["SXM NVHS Clock 6"] =
                    static_cast<int>(clockBuffer->clk_buf_sxm_nvhs6);
                clockBufferResult["SXM NVHS Clock 7"] =
                    static_cast<int>(clockBuffer->clk_buf_sxm_nvhs7);
                clockBufferResult["SXM NVHS Clock 8"] =
                    static_cast<int>(clockBuffer->clk_buf_sxm_nvhs8);

                clockBufferResult["NvSwitch NVHS Clock 1"] =
                    static_cast<int>(clockBuffer->clk_buf_nvSwitch_nvhs1);
                clockBufferResult["NvSwitch NVHS Clock 2"] =
                    static_cast<int>(clockBuffer->clk_buf_nvSwitch_nvhs2);
                clockBufferResult["NvSwitch NVHS Clock 3"] =
                    static_cast<int>(clockBuffer->clk_buf_nvSwitch_nvhs3);
                clockBufferResult["NvSwitch NVHS Clock 4"] =
                    static_cast<int>(clockBuffer->clk_buf_nvSwitch_nvhs4);
            }
            break;
            case IBLINK_CLKBUF_INDEX:
            {
                auto clockBuffer =
                    reinterpret_cast<nsm_iblink_clock_buffer_data*>(&data);
                clockBufferResult["NvSwitch IBLink Clock 1"] =
                    static_cast<int>(clockBuffer->clk_buf_nvSwitch_1);
                clockBufferResult["NvSwitch IBLink Clock 2"] =
                    static_cast<int>(clockBuffer->clk_buf_nvSwitch_2);

                clockBufferResult["NvLink Mgmt NIC IBLink Clock"] =
                    static_cast<int>(clockBuffer->clk_buf_nvlinkMgmt_nic);
            }
            break;
            default:
                clockBufferResult["Error"] = "Unsupported index in request";
                break;
        }
        result["Clock Enable State Information"] = clockBufferResult;

        nsmtool::helper::DisplayInJson(result);
    }

  private:
    uint8_t index;
};

class QueryAggregatedGPMMetrics : public CommandInterface
{
  public:
    QueryAggregatedGPMMetrics() = delete;
    QueryAggregatedGPMMetrics(const QueryAggregatedGPMMetrics&) = delete;
    QueryAggregatedGPMMetrics(QueryAggregatedGPMMetrics&&) = default;
    QueryAggregatedGPMMetrics&
        operator=(const QueryAggregatedGPMMetrics&) = delete;
    QueryAggregatedGPMMetrics& operator=(QueryAggregatedGPMMetrics&&) = delete;

    explicit QueryAggregatedGPMMetrics(const char* type, const char* name,
                                       CLI::App* app) :
        CommandInterface(type, name, app)
    {
        app->add_option("-r, --retrievalSource", retrievalSource,
                        "Retrieval Source")
            ->required();
        app->add_option("-g, --gpuInstance", gpuInstance, "GPU Instance")
            ->required();
        app->add_option("-c, --computeInstance", computeInstance,
                        "Compute Instance")
            ->required();
        app->add_option("-b, --metricsBitfield", metricsBitfield,
                        "Metrics Bitfield")
            ->required();
    }

  private:
    class QueryAggregatedGPMMetricsAggregateResponseParser :
        public AggregateResponseParser
    {
      private:
        int handleSampleData(uint8_t tag, const uint8_t* data, size_t data_len,
                             ordered_json& sample_json) final
        {
            const auto info = metricsTable.find(tag);
            if (info == metricsTable.end())
            {
                return NSM_SW_ERROR_DATA;
            }

            uint8_t rc = NSM_SW_SUCCESS;
            double value{};

            switch (info->second.unit)
            {
                case GPMMetricsUnit::PERCENTAGE:
                {
                    rc = decode_aggregate_gpm_metric_percentage_data(
                        data, data_len, &value);

                    break;
                }

                case GPMMetricsUnit::BANDWIDTH:
                {
                    uint64_t val;
                    rc = decode_aggregate_gpm_metric_bandwidth_data(
                        data, data_len, &val);

                    // unit of bandwidth is Bytes per seconds in NSM Command
                    // Response and unit for GPMMetrics PDI is Gbps. Hence it is
                    // converted to Gbps.
                    static constexpr uint64_t conversionFactor = 1024 * 1024 *
                                                                 128;
                    value = val / static_cast<double>(conversionFactor);

                    break;
                }
            }

            if (rc == NSM_SUCCESS)
            {
                sample_json["Metric Id"] = tag;
                sample_json["Metric Name"] = info->second.name;
                sample_json["Metric Value"] = value;
            }

            return rc;
        }
    };

  public:
    std::pair<int, std::vector<uint8_t>> createRequestMsg() override
    {
        // struct nsm_query_aggregate_gpm_metrics_req has char[1] as its last
        // member to handle variable size Metrics bitfield of the NSM Request.
        // 1 is subtracted from it's size to account for it.
        std::vector<uint8_t> requestMsg(
            sizeof(nsm_msg_hdr) + sizeof(nsm_query_aggregate_gpm_metrics_req) -
            1 + metricsBitfield.size());
        auto requestPtr = reinterpret_cast<nsm_msg*>(requestMsg.data());

        auto rc = encode_query_aggregate_gpm_metrics_req(
            instanceId, retrievalSource, gpuInstance, computeInstance,
            metricsBitfield.data(), metricsBitfield.size(), requestPtr);

        return {rc, requestMsg};
    }

    void parseResponseMsg(nsm_msg* responsePtr, size_t payloadLength) override
    {
        QueryAggregatedGPMMetricsAggregateResponseParser{}
            .parseAggregateResponse(responsePtr, payloadLength);
    }

  private:
    uint8_t retrievalSource;
    uint8_t gpuInstance;
    uint8_t computeInstance;
    std::vector<uint8_t> metricsBitfield;
};

class QueryPerInstanceGPMMetrics : public CommandInterface
{
  public:
    QueryPerInstanceGPMMetrics() = delete;
    QueryPerInstanceGPMMetrics(const QueryPerInstanceGPMMetrics&) = delete;
    QueryPerInstanceGPMMetrics(QueryPerInstanceGPMMetrics&&) = default;
    QueryPerInstanceGPMMetrics&
        operator=(const QueryPerInstanceGPMMetrics&) = delete;
    QueryPerInstanceGPMMetrics& operator=(QueryAggregatedGPMMetrics&&) = delete;

    explicit QueryPerInstanceGPMMetrics(const char* type, const char* name,
                                        CLI::App* app) :
        CommandInterface(type, name, app)
    {
        app->add_option("-r, --retrievalSource", retrievalSource,
                        "Retrieval Source")
            ->required();
        app->add_option("-g, --gpuInstance", gpuInstance, "GPU Instance")
            ->required();
        app->add_option("-c, --computeInstance", computeInstance,
                        "Compute Instance")
            ->required();
        app->add_option("-i, --metricId", metricId, "Metric Id")->required();
        app->add_option("-b, --instanceBitfield", instanceBitfield,
                        "Instance Bitfield")
            ->required();
    }

  private:
    class QueryPerInstanceGPMMetricsAggregateResponseParser :
        public AggregateResponseParser
    {
      public:
        QueryPerInstanceGPMMetricsAggregateResponseParser(
            const MetricsInfo* info) : info(info)
        {}

      private:
        int handleSampleData(uint8_t tag, const uint8_t* data, size_t data_len,
                             ordered_json& sample_json) final
        {
            uint8_t rc = NSM_SW_SUCCESS;
            double value{};

            switch (info->unit)
            {
                case GPMMetricsUnit::PERCENTAGE:
                {
                    rc = decode_aggregate_gpm_metric_percentage_data(
                        data, data_len, &value);

                    break;
                }

                case GPMMetricsUnit::BANDWIDTH:
                {
                    uint64_t val;
                    rc = decode_aggregate_gpm_metric_bandwidth_data(
                        data, data_len, &val);

                    // unit of bandwidth is Bytes per seconds in NSM Command
                    // Response and unit for GPMMetrics PDI is Gbps. Hence it is
                    // converted to Gbps.
                    static constexpr uint64_t conversionFactor = 1024 * 1024 *
                                                                 128;
                    value = val / static_cast<double>(conversionFactor);

                    break;
                }
            }

            if (rc == NSM_SUCCESS)
            {
                sample_json["Instance Id"] = tag;
                sample_json["Metric Value"] = value;
            }

            return rc;
        }

      private:
        const MetricsInfo* info;
    };

  public:
    std::pair<int, std::vector<uint8_t>> createRequestMsg() override
    {
        std::vector<uint8_t> requestMsg(
            sizeof(nsm_msg_hdr) +
            sizeof(nsm_query_per_instance_gpm_metrics_req));

        auto requestPtr = reinterpret_cast<nsm_msg*>(requestMsg.data());

        auto rc = encode_query_per_instance_gpm_metrics_req(
            instanceId, retrievalSource, gpuInstance, computeInstance, metricId,
            instanceBitfield, requestPtr);

        return {rc, requestMsg};
    }

    void parseResponseMsg(nsm_msg* responsePtr, size_t payloadLength) override
    {
        const auto find_result = metricsTable.find(metricId);
        if (find_result == metricsTable.end())
        {
            return;
        }
        QueryPerInstanceGPMMetricsAggregateResponseParser{&find_result->second}
            .parseAggregateResponse(responsePtr, payloadLength);
    }

  private:
    uint8_t retrievalSource;
    uint8_t gpuInstance;
    uint8_t computeInstance;
    uint8_t metricId;
    uint32_t instanceBitfield;
};

class GetViolationDuration : public CommandInterface
{
  public:
    ~GetViolationDuration() = default;
    GetViolationDuration() = delete;
    GetViolationDuration(const GetViolationDuration&) = delete;
    GetViolationDuration(GetViolationDuration&&) = default;
    GetViolationDuration& operator=(const GetViolationDuration&) = delete;
    GetViolationDuration& operator=(GetViolationDuration&&) = default;

    using CommandInterface::CommandInterface;

    std::pair<int, std::vector<uint8_t>> createRequestMsg() override
    {
        std::vector<uint8_t> requestMsg(sizeof(nsm_msg_hdr) +
                                        sizeof(nsm_common_req));
        auto request = reinterpret_cast<nsm_msg*>(requestMsg.data());
        auto rc = encode_get_violation_duration_req(instanceId, request);
        return {rc, requestMsg};
    }

    void parseResponseMsg(nsm_msg* responsePtr, size_t payloadLength) override
    {
        uint8_t cc = NSM_ERROR;
        struct nsm_violation_duration violationDuration;
        uint16_t data_size;
        uint16_t reason_code = ERR_NULL;

        auto rc = decode_get_violation_duration_resp(
            responsePtr, payloadLength, &cc, &data_size, &reason_code,
            &violationDuration);
        if (rc != NSM_SW_SUCCESS || cc != NSM_SUCCESS)
        {
            std::cerr << "Response message error: "
                      << "rc=" << rc << ", cc=" << (int)cc
                      << ", reasonCode=" << (int)reason_code << "\n"
                      << payloadLength << "...."
                      << (sizeof(struct nsm_msg_hdr) +
                          sizeof(struct nsm_get_violation_duration_resp));

            return;
        }

        ordered_json result;
        result["Completion Code"] = cc;
        result["SupportedCounter"] =
            static_cast<uint64_t>(violationDuration.supported_counter.byte);
        result["HwViolationDuration"] =
            static_cast<uint64_t>(violationDuration.hw_violation_duration);
        result["GlobalSwViolationDuration"] = static_cast<uint64_t>(
            violationDuration.global_sw_violation_duration);
        result["PowerViolationDuration"] =
            static_cast<uint64_t>(violationDuration.power_violation_duration);
        result["ThermalViolationDuration"] =
            static_cast<uint64_t>(violationDuration.thermal_violation_duration);
        result["Counter4"] = static_cast<uint64_t>(violationDuration.counter4);
        result["Counter5"] = static_cast<uint64_t>(violationDuration.counter5);
        result["Counter6"] = static_cast<uint64_t>(violationDuration.counter6);
        result["Counter7"] = static_cast<uint64_t>(violationDuration.counter7);
        nsmtool::helper::DisplayInJson(result);
    }
};

class GetListAvailablePciePorts : public CommandInterface
{
  public:
    GetListAvailablePciePorts() = delete;
    GetListAvailablePciePorts(const GetListAvailablePciePorts&) = delete;
    GetListAvailablePciePorts(GetListAvailablePciePorts&&) = default;
    GetListAvailablePciePorts&
        operator=(const GetListAvailablePciePorts&) = delete;
    GetListAvailablePciePorts& operator=(GetListAvailablePciePorts&&) = delete;

    using CommandInterface::CommandInterface;

    std::pair<int, std::vector<uint8_t>> createRequestMsg() override
    {
        std::vector<uint8_t> requestMsg(sizeof(nsm_msg_hdr) +
                                        sizeof(nsm_common_req));
        auto request = reinterpret_cast<nsm_msg*>(requestMsg.data());
        auto rc = encode_list_available_pcie_ports_req(instanceId, request);
        return {rc, requestMsg};
    }

    void parseResponseMsg(nsm_msg* responsePtr, size_t payloadLength) override
    {
        uint8_t cc = NSM_ERROR;
        uint16_t reasonCode = ERR_NULL;
        struct nsm_list_available_pcie_ports_info info;
        auto rc = decode_list_available_pcie_ports_resp(
            responsePtr, payloadLength, &cc, &reasonCode, &info);
        if (rc != NSM_SW_SUCCESS || cc != NSM_SUCCESS)
        {
            std::cerr << "Response message error: "
                      << "rc=" << rc << ", cc=" << (int)cc
                      << ", reasonCode=" << (int)reasonCode << "\n"
                      << payloadLength << "...."
                      << NSM_LIST_AVAILABLE_PCIE_PORTS_RESPONSE_MIN_LEN;

            return;
        }

        ordered_json result;
        result["Completion Code"] = cc;
        result["Upstream Ports Count"] = uint16_t(info.ports_count);
        for (uint16_t i = 0; i < info.ports_count; i++)
        {
            result["Ports"][i]["Type"] = info.ports[i].type == 0 ? "External"
                                                                 : "Internal";
            result["Ports"][i]["Downstream Ports Count"] =
                uint16_t(info.ports[i].downstream_ports_count);
        }
        nsmtool::helper::DisplayInJson(result);
    }
};

class GetEthPortTelemetryCounter : public CommandInterface
{
  public:
    ~GetEthPortTelemetryCounter() = default;
    GetEthPortTelemetryCounter() = delete;
    GetEthPortTelemetryCounter(const GetEthPortTelemetryCounter&) = delete;
    GetEthPortTelemetryCounter(GetEthPortTelemetryCounter&&) = default;
    GetEthPortTelemetryCounter&
        operator=(const GetEthPortTelemetryCounter&) = delete;
    GetEthPortTelemetryCounter&
        operator=(GetEthPortTelemetryCounter&&) = default;

    using CommandInterface::CommandInterface;

    explicit GetEthPortTelemetryCounter(const char* type, const char* name,
                                        CLI::App* app) :
        CommandInterface(type, name, app)
    {
        auto portOptionGroup = app->add_option_group(
            "Required",
            "Port number for which network addresses are to be retrieved.");

        portNumber = 0;
        portOptionGroup->add_option(
            "-p, --portNum", portNumber,
            "Retrieve network addresses for Port number");
        portOptionGroup->require_option(1);
    }

    std::pair<int, std::vector<uint8_t>> createRequestMsg() override
    {
        std::vector<uint8_t> requestMsg(
            sizeof(nsm_msg_hdr) +
            sizeof(nsm_get_ethernet_port_telemetry_counter_req));
        auto request = reinterpret_cast<nsm_msg*>(requestMsg.data());
        auto rc = encode_get_eth_port_telemetry_counter_req(
            instanceId, portNumber, request);
        return {rc, requestMsg};
    }

    void parseResponseMsg(nsm_msg* responsePtr, size_t payloadLength) override
    {
        GetEthPortTelemetryCounterAggregateResponseParser{}
            .parseAggregateResponse(responsePtr, payloadLength);
    }

  private:
    class GetEthPortTelemetryCounterAggregateResponseParser :
        public AggregateResponseParser
    {
      private:
        int handleSampleData(uint8_t tag, const uint8_t* data, size_t data_len,
                             ordered_json& sample_json) final
        {
            nsm_ethernet_port_counter_data counter_reading;
            int rc = decode_aggregate_eth_port_telemetry_data(
                data, &data_len, tag, &counter_reading);
            if (rc != NSM_SW_SUCCESS)
            {
                return rc;
            }
            sample_json[ethPortTelemetryCounterList[tag]] =
                counter_reading.ethernet_port_counter_data_64bit;
            return NSM_SW_SUCCESS;
        }
    };

    uint16_t portNumber;
    static constexpr const char* ethPortTelemetryCounterList[21] = {
        "RXBytes",                   // 0
        "TXBytes",                   // 1
        "RXUnicastBytes",            // 2
        "RXMulticastBytes",          // 3
        "RXBroadcastBytes",          // 4
        "TXUnicastBytes",            // 5
        "TXMulticastBytes",          // 6
        "TXBroadcastBytes",          // 7
        "RXFCSErrors",               // 8
        "RXAlignmentErrors",         // 9
        "RXFalseCarrierDetections",  // 10
        "RXRuntBytes",               // 11
        "RXJabberBytes",             // 12
        "RXXONFrames",               // 13
        "RXXOFFFrames",              // 14
        "TXXONFrames",               // 15
        "TXXOFFFrames",              // 16
        "TXSingleCollisionFrames",   // 17
        "TXMultipleCollisionFrames", // 18
        "TXLateCollisionFrames",     // 19
        "TXExcessCollisionFrames"    // 20
    };
};

class GetPortNetworkAddresses : public CommandInterface
{
  public:
    ~GetPortNetworkAddresses() = default;
    GetPortNetworkAddresses() = delete;
    GetPortNetworkAddresses(const GetPortNetworkAddresses&) = delete;
    GetPortNetworkAddresses(GetPortNetworkAddresses&&) = default;
    GetPortNetworkAddresses& operator=(const GetPortNetworkAddresses&) = delete;
    GetPortNetworkAddresses& operator=(GetPortNetworkAddresses&&) = default;

    using CommandInterface::CommandInterface;

    explicit GetPortNetworkAddresses(const char* type, const char* name,
                                     CLI::App* app) :
        CommandInterface(type, name, app)
    {
        auto portOptionGroup = app->add_option_group(
            "Required",
            "Port number for which network addresses are to be retrieved.");

        portNumber = 0;
        portOptionGroup->add_option(
            "-p, --portNum", portNumber,
            "Retrieve network addresses for Port number");
        portOptionGroup->require_option(1);
    }

    std::pair<int, std::vector<uint8_t>> createRequestMsg() override
    {
        std::vector<uint8_t> requestMsg(sizeof(nsm_msg_hdr) +
                                        sizeof(nsm_get_network_addresses_req));
        auto request = reinterpret_cast<nsm_msg*>(requestMsg.data());
        auto rc = encode_get_network_addresses_req(instanceId, portNumber,
                                                   request);
        return {rc, requestMsg};
    }

    void parseResponseMsg(nsm_msg* responsePtr, size_t payloadLength) override
    {
        GetPortNetworkAddressesAggregateResponseParser{}.parseAggregateResponse(
            responsePtr, payloadLength);
    }

  private:
    class GetPortNetworkAddressesAggregateResponseParser :
        public AggregateResponseParser
    {
      private:
        int handleSampleData(uint8_t tag, const uint8_t* data, size_t data_len,
                             ordered_json& sample_json) final
        {
            network_address_sample_data address;
            int rc = decode_aggregate_network_address_data(tag, data, data_len,
                                                           &address);
            if (rc != NSM_SW_SUCCESS)
            {
                return rc;
            }

            switch (tag)
            {
                case NSM_TAG_LINK_TYPE:
                    sample_json["Link Type"] = address.link_type;
                    break;
                case NSM_TAG_MAC_ADDRESS:
                {
                    std::string network_address;
                    utils::convertMacAddressToString(address.mac_address,
                                                     MAC_ADDRESS_LENGTH,
                                                     network_address);
                    sample_json["MAC Address"] = network_address.c_str();
                }
                break;
                case NSM_TAG_PERMANENT_MAC_ADDRESS:
                {
                    std::string network_address;
                    utils::convertMacAddressToString(address.mac_address,
                                                     MAC_ADDRESS_LENGTH,
                                                     network_address);
                    sample_json["Permanent MAC Address"] =
                        network_address.c_str();
                }
                break;
                case NSM_TAG_NODE_GUID:
                {
                    std::string network_address;
                    utils::convertGuid64ToString(
                        address.network_identifier_64bit, network_address);
                    sample_json["InfiniBand Node GUID"] = network_address;
                }
                break;
                case NSM_TAG_PORT_GUID:
                {
                    std::string network_address;
                    utils::convertGuid64ToString(
                        address.network_identifier_64bit, network_address);
                    sample_json["InfiniBand Port GUID"] = network_address;
                }
                break;
                default:
                    return NSM_SW_ERROR_DATA;
            }
            return NSM_SW_SUCCESS;
        }
    };

    uint16_t portNumber;
};

class GetPortEccCounters : public CommandInterface
{
  public:
    ~GetPortEccCounters() = default;
    GetPortEccCounters() = delete;
    GetPortEccCounters(const GetPortEccCounters&) = delete;
    GetPortEccCounters(GetPortEccCounters&&) = default;
    GetPortEccCounters& operator=(const GetPortEccCounters&) = delete;
    GetPortEccCounters& operator=(GetPortEccCounters&&) = default;

    using CommandInterface::CommandInterface;

    explicit GetPortEccCounters(const char* type, const char* name,
                                CLI::App* app) :
        CommandInterface(type, name, app)
    {
        auto portOptionGroup = app->add_option_group(
            "Required",
            "Port number for which ECC counters are to be retrieved.");

        portNumber = 0;
        portOptionGroup->add_option("-p, --portNum", portNumber,
                                    "Retrieve ECC counters for Port number");
        portOptionGroup->require_option(1);
    }

    std::pair<int, std::vector<uint8_t>> createRequestMsg() override
    {
        std::vector<uint8_t> requestMsg(sizeof(nsm_msg_hdr) +
                                        sizeof(nsm_get_port_ecc_counters_req));
        auto request = reinterpret_cast<nsm_msg*>(requestMsg.data());
        auto rc = encode_get_port_ecc_counters_req(instanceId, portNumber,
                                                   request);
        return {rc, requestMsg};
    }

    void parseResponseMsg(nsm_msg* responsePtr, size_t payloadLength) override
    {
        GetPortEccCountersAggregateResponseParser{}.parseAggregateResponse(
            responsePtr, payloadLength);
    }

  private:
    class GetPortEccCountersAggregateResponseParser :
        public AggregateResponseParser
    {
      private:
        int handleSampleData(uint8_t tag, const uint8_t* data, size_t data_len,
                             ordered_json& sample_json) final
        {
            uint64_t counter_value;
            int rc = decode_aggregate_port_ecc_counter_data(tag, data, data_len,
                                                            &counter_value);
            if (rc != NSM_SW_SUCCESS)
            {
                return rc;
            }

            switch (tag)
            {
                case NSM_TAG_ECC_RX_SYMBOL_ERRORS_BYTES:
                    sample_json["SymbolErrorRXBytes"] = counter_value;
                    break;
                case NSM_TAG_ECC_CORRECTED_BITS:
                    sample_json["CorrectedBits"] = counter_value;
                    break;
                case NSM_TAG_ECC_RAW_ERRORS_LANE_0:
                    sample_json["RawErrorsPerLane_0"] = counter_value;
                    break;
                case NSM_TAG_ECC_RAW_ERRORS_LANE_1:
                    sample_json["RawErrorsPerLane_1"] = counter_value;
                    break;
                case NSM_TAG_ECC_RAW_ERRORS_LANE_2:
                    sample_json["RawErrorsPerLane_2"] = counter_value;
                    break;
                case NSM_TAG_ECC_RAW_ERRORS_LANE_3:
                    sample_json["RawErrorsPerLane_3"] = counter_value;
                    break;
                default:
                    return NSM_SW_ERROR_DATA;
            }
            return NSM_SW_SUCCESS;
        }
    };

    uint16_t portNumber;
};

void registerCommand(CLI::App& app)
{
    auto telemetry = app.add_subcommand(
        "telemetry", "Network, PCI link and platform telemetry type command");
    telemetry->require_subcommand(1);

    auto getPortTelemetryCounter = telemetry->add_subcommand(
        "GetPortTelemetryCounter", "get port telemetry counter");
    commands.push_back(std::make_unique<GetPortTelemetryCounter>(
        "telemetry", "GetPortTelemetryCounter", getPortTelemetryCounter));

    auto queryPortCharacteristics = telemetry->add_subcommand(
        "QueryPortCharacteristics", "query port characteristics");
    commands.push_back(std::make_unique<QueryPortCharacteristics>(
        "telemetry", "QueryPortCharacteristics", queryPortCharacteristics));

    auto queryPortStatus = telemetry->add_subcommand("QueryPortStatus",
                                                     "query port status");
    commands.push_back(std::make_unique<QueryPortStatus>(
        "telemetry", "QueryPortStatus", queryPortStatus));

    auto queryPortsAvailable = telemetry->add_subcommand(
        "QueryPortsAvailable", "query ports available");
    commands.push_back(std::make_unique<QueryPortsAvailable>(
        "telemetry", "QueryPortsAvailable", queryPortsAvailable));

    auto setPortDisableFuture = telemetry->add_subcommand(
        "SetPortDisableFuture", "query ports available");
    commands.push_back(std::make_unique<SetPortDisableFuture>(
        "telemetry", "SetPortDisableFuture", setPortDisableFuture));

    auto getFabricManagerState = telemetry->add_subcommand(
        "GetFabricManagerState", "Get Fabric Manager State");
    commands.push_back(std::make_unique<GetFabricManagerState>(
        "telemetry", "GetFabricManagerState", getFabricManagerState));

    auto getPortDisableFuture = telemetry->add_subcommand(
        "GetPortDisableFuture", "query ports available");
    commands.push_back(std::make_unique<GetPortDisableFuture>(
        "telemetry", "GetPortDisableFuture", getPortDisableFuture));

    auto getPowerMode = telemetry->add_subcommand("GetPowerMode",
                                                  "Get L1 power mode");
    commands.push_back(std::make_unique<GetPowerMode>(
        "telemetry", "GetPowerMode", getPowerMode));

    auto setPowerMode = telemetry->add_subcommand("SetPowerMode",
                                                  "Set L1 power mode");
    commands.push_back(std::make_unique<SetPowerMode>(
        "telemetry", "SetPowerMode", setPowerMode));

    auto getSwitchIsolationMode = telemetry->add_subcommand(
        "GetSwitchIsolationMode", "Get Switch Isolation Mode");
    commands.push_back(std::make_unique<GetSwitchIsolationMode>(
        "telemetry", "GetSwitchIsolationMode", getSwitchIsolationMode));

    auto setSwitchIsolationMode = telemetry->add_subcommand(
        "SetSwitchIsolationMode", "Set Switch Isolation Mode");
    commands.push_back(std::make_unique<SetSwitchIsolationMode>(
        "telemetry", "SetSwitchIsolationMode", setSwitchIsolationMode));

    auto getInventoryInformation = telemetry->add_subcommand(
        "GetInventoryInformation", "get inventory information");
    commands.push_back(std::make_unique<GetInventoryInformation>(
        "telemetry", "GetInventoryInformation", getInventoryInformation));

    auto getTemperatureReading = telemetry->add_subcommand(
        "GetTemperatureReading", "get temperature reading of a sensor");
    commands.push_back(std::make_unique<GetTemperatureReading>(
        "telemetry", "GetTemperatureReading", getTemperatureReading));

    auto readThermalParameter = telemetry->add_subcommand(
        "ReadThermalParameter", "read thermal parameter a device");
    commands.push_back(std::make_unique<ReadThermalParameter>(
        "telemetry", "ReadThermalParameter", readThermalParameter));

    auto getCurrentPowerDraw = telemetry->add_subcommand(
        "GetCurrentPowerDraw", "get current power draw of a device");
    commands.push_back(std::make_unique<GetCurrentPowerDraw>(
        "telemetry", "GetCurrentPowerDraw", getCurrentPowerDraw));

    auto getMaxObservedPower = telemetry->add_subcommand(
        "GetMaxObservedPower", "get peak power observed of a device");
    commands.push_back(std::make_unique<GetMaxObservedPower>(
        "telemetry", "GetMaxObservedPower", getMaxObservedPower));

    auto getCurrentEnergyCount = telemetry->add_subcommand(
        "GetCurrentEnergyCount",
        "get current energy counter value of a device");
    commands.push_back(std::make_unique<GetCurrentEnergyCount>(
        "telemetry", "GetCurrentEnergyCount", getCurrentEnergyCount));

    auto getVoltage = telemetry->add_subcommand("GetVoltage",
                                                "get voltage of a device");
    commands.push_back(
        std::make_unique<GetVoltage>("telemetry", "GetVoltage", getVoltage));

    auto getAltitudePressure = telemetry->add_subcommand(
        "GetAltitudePressure", "get current power draw of a device");
    commands.push_back(std::make_unique<GetAltitudePressure>(
        "telemetry", "GetAltitudePressure", getAltitudePressure));

    auto getDriverInfo = telemetry->add_subcommand("GetDriverInfo",
                                                   "get Driver info");
    commands.push_back(std::make_unique<GetDriverInfo>(
        "telemetry", "GetDriverInfo", getDriverInfo));

    auto getMigMode = telemetry->add_subcommand("GetMigModes", "get MIG modes");
    commands.push_back(
        std::make_unique<GetMigMode>("telemetry", "GetMigMode", getMigMode));

    auto setMigMode = telemetry->add_subcommand("SetMigModes", "set MIG mode");
    commands.push_back(
        std::make_unique<SetMigMode>("telemetry", "SetMigMode", setMigMode));

    auto getEccMode = telemetry->add_subcommand("GetEccMode", "get ECC modes");
    commands.push_back(
        std::make_unique<GetEccMode>("telemetry", "GetEccMode", getEccMode));

    auto setEccMode = telemetry->add_subcommand("SetEccMode", "set ECC modes");
    commands.push_back(
        std::make_unique<SetEccMode>("telemetry", "SetEccMode", setEccMode));

    auto getEccErrorCounts = telemetry->add_subcommand("GetEccErrorCounts",
                                                       "get ECC error counts");
    commands.push_back(std::make_unique<GetEccErrorCounts>(
        "telemetry", "GetEccErrorCounts", getEccErrorCounts));

    auto setClockLimit = telemetry->add_subcommand("SetClockLimit",
                                                   "set Clock Limit");
    commands.push_back(std::make_unique<SetClockLimit>(
        "telemetry", "SetClockLimit", setClockLimit));

    auto getEDPpScalingFactors = telemetry->add_subcommand(
        "GetEDPpScalingFactors", "get programmable EDPp Scaling Factors");
    commands.push_back(std::make_unique<GetEDPpScalingFactors>(
        "telemetry", "GetEDPpScalingFactors", getEDPpScalingFactors));

    auto setEDPpScalingFactors = telemetry->add_subcommand(
        "SetEDPpScalingFactors", "set programmable EDPp Scaling Factors");
    commands.push_back(std::make_unique<SetEDPpScalingFactors>(
        "telemetry", "SetEDPpScalingFactors", setEDPpScalingFactors));

    auto queryScalarGroupTelemetry = telemetry->add_subcommand(
        "QueryScalarGroupTelemetry", "retrieve Scalar Data source for group ");
    commands.push_back(std::make_unique<QueryScalarGroupTelemetry>(
        "telemetry", "QueryScalarGroupTelemetry", queryScalarGroupTelemetry));

    auto queryAvailableAndClearableScalarGroup = telemetry->add_subcommand(
        "QueryAvailableAndClearableScalarGroup",
        "retrieve available and clearable Scalar Data source for the group");
    commands.push_back(std::make_unique<QueryAvailableAndClearableScalarGroup>(
        "telemetry", "QueryAvailableAndClearableScalarGroup",
        queryAvailableAndClearableScalarGroup));

    auto pcieFundamentalReset = telemetry->add_subcommand(
        "PcieFundamentalReset", "Assert PCIe Fundamental Reset action");
    commands.push_back(std::make_unique<PcieFundamentalReset>(
        "telemetry", "PcieFundamentalReset", pcieFundamentalReset));

    auto clearScalarDataSource = telemetry->add_subcommand(
        "ClearScalarDataSource", "Clear Scalar Data Source");
    commands.push_back(std::make_unique<ClearScalarDataSource>(
        "telemetry", "ClearScalarDataSource", clearScalarDataSource));

    auto getClockLimit = telemetry->add_subcommand(
        "GetClockLimit", "retrieve clock Limit for clockId");
    commands.push_back(std::make_unique<GetClockLimit>(
        "telemetry", "GetClockLimit", getClockLimit));

    auto setPowerLimit = telemetry->add_subcommand("SetPowerLimit",
                                                   "set Power Limit");
    commands.push_back(std::make_unique<SetPowerLimit>(
        "telemetry", "SetPowerLimit", setPowerLimit));
    auto getPowerLimit = telemetry->add_subcommand("GetPowerLimit",
                                                   "get Power Limit");
    commands.push_back(std::make_unique<GetPowerLimit>(
        "telemetry", "getPowerLimit", getPowerLimit));

    auto getCurrClockFreq = telemetry->add_subcommand(
        "GetCurrClockFreq", "get current clock frequency of GPU");
    commands.push_back(std::make_unique<GetCurrClockFreq>(
        "telemetry", "GetCurrClockFreq", getCurrClockFreq));

    auto getAccumGpuUtilTime = telemetry->add_subcommand(
        "GetAccumGpuUtilTime",
        "Get Accumulated GPU Utilization Time Context/SM");
    commands.push_back(std::make_unique<GetAccumGpuUtilTime>(
        "telemetry", "GetAccumGpuUtilTime", getAccumGpuUtilTime));

    auto getProcessorThrottleReason = telemetry->add_subcommand(
        "GetProcessorThrottleReason", "Get Processor Throttle Reason");
    commands.push_back(std::make_unique<GetProcessorThrottleReason>(
        "telemetry", "GetProcessorThrottleReason", getProcessorThrottleReason));

    auto getRowRemapState = telemetry->add_subcommand("GetRowRemapState",
                                                      "get Row Remap State");
    commands.push_back(std::make_unique<GetRowRemapState>(
        "telemetry", "GetRowRemapState", getRowRemapState));

    auto getRowRemappingCounts = telemetry->add_subcommand(
        "GetRowRemappingCounts", "get Row Remapping Error Counts");
    commands.push_back(std::make_unique<GetRowRemappingCounts>(
        "telemetry", "GetRowRemappingCounts", getRowRemappingCounts));

    auto getRowRemapAvailability = telemetry->add_subcommand(
        "GetRowRemapAvailability", "get Row Remapping Availability ");
    commands.push_back(std::make_unique<GetRowRemapAvailability>(
        "telemetry", "GetRowRemapAvailability", getRowRemapAvailability));

    auto getMemoryCapacityUtil = telemetry->add_subcommand(
        "GetMemoryCapacityUtil", "Get memory Capacity Capacity Utilization");
    commands.push_back(std::make_unique<GetMemoryCapacityUtil>(
        "telemetry", "GetMemoryCapacityUtil", getMemoryCapacityUtil));

    auto getCurrentUtilization = telemetry->add_subcommand(
        "GetCurrentUtilization", "Get Current Capacity Utilization");
    commands.push_back(std::make_unique<GetCurrentUtilization>(
        "telemetry", "GetCurrentUtilization", getCurrentUtilization));

    auto getClockOutputEnableState = telemetry->add_subcommand(
        "GetClockOutputEnableState", "get clock output enable state");
    commands.push_back(std::make_unique<GetClockOutputEnableState>(
        "telemetry", "GetClockOutputEnableState", getClockOutputEnableState));

    auto queryAggregatedGPMMetrics = telemetry->add_subcommand(
        "QueryAggregatedGPMMetrics", "Query Aggregated GPM Metrics");
    commands.push_back(std::make_unique<QueryAggregatedGPMMetrics>(
        "telemetry", "QueryAggregatedGPMMetrics", queryAggregatedGPMMetrics));

    auto queryPerInstanceGPMMetrics = telemetry->add_subcommand(
        "QueryPerInstanceGPMMetrics", "Query Per-instance GPM Metrics");
    commands.push_back(std::make_unique<QueryPerInstanceGPMMetrics>(
        "telemetry", "QueryPerInstanceGPMMetrics", queryPerInstanceGPMMetrics));

    auto getViolationDuration = telemetry->add_subcommand(
        "GetViolationDuration", "get processor throttle duration");
    commands.push_back(std::make_unique<GetViolationDuration>(
        "telemetry", "GetViolationDuration", getViolationDuration));

    auto getListAvailablePciePorts = telemetry->add_subcommand(
        "GetListAvailablePciePorts", "get list of available PCIe ports");
    commands.push_back(std::make_unique<GetListAvailablePciePorts>(
        "telemetry", "GetListAvailablePciePorts", getListAvailablePciePorts));

    auto queryMultiportScalarGroupTelemetry = telemetry->add_subcommand(
        "QueryMultiportScalarGroupTelemetry",
        "Get Multiport Scalar Data Telemetry for groupId");
    commands.push_back(std::make_unique<QueryMultiportScalarGroupTelemetry>(
        "telemetry", "QueryMultiportScalarGroupTelemetry",
        queryMultiportScalarGroupTelemetry));

    auto getEthPortTelemetryCounter = telemetry->add_subcommand(
        "GetEthPortTelemetryCounter", "get ethernet port telemetry counter");
    commands.push_back(std::make_unique<GetEthPortTelemetryCounter>(
        "telemetry", "GetEthPortTelemetryCounter", getEthPortTelemetryCounter));
    auto getPortNetworkAddresses = telemetry->add_subcommand(
        "GetPortNetworkAddresses", "Get Port Network Addresses");
    commands.push_back(std::make_unique<GetPortNetworkAddresses>(
        "telemetry", "GetPortNetworkAddresses", getPortNetworkAddresses));

    auto getPortEccCounters = telemetry->add_subcommand(
        "GetPortEccCounters", "Get Port ECC Counters");
    commands.push_back(std::make_unique<GetPortEccCounters>(
        "telemetry", "GetPortEccCounters", getPortEccCounters));
}

} // namespace telemetry

} // namespace nsmtool
