#include "pldm_bios_cmd.hpp"

#include "common/bios_utils.hpp"
#include "common/utils.hpp"
#include "pldm_cmd_helper.hpp"

#include <libpldm/bios_table.h>
#include <libpldm/utils.h>

#include <map>
#include <optional>

namespace pldmtool
{

namespace bios
{

namespace
{

using namespace pldmtool::helper;
using namespace pldm::bios::utils;
using namespace pldm::utils;

std::vector<std::unique_ptr<CommandInterface>> commands;

const std::map<const char*, pldm_bios_table_types> pldmBIOSTableTypes{
    {"StringTable", PLDM_BIOS_STRING_TABLE},
    {"AttributeTable", PLDM_BIOS_ATTR_TABLE},
    {"AttributeValueTable", PLDM_BIOS_ATTR_VAL_TABLE},
};

} // namespace

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

    using CommandInterface::CommandInterface;

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

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

    void parseResponseMsg(pldm_msg* responsePtr, size_t payloadLength) override
    {
        uint8_t cc = 0;

        uint8_t seconds, minutes, hours, day, month;
        uint16_t year;
        auto rc = decode_get_date_time_resp(responsePtr, payloadLength, &cc,
                                            &seconds, &minutes, &hours, &day,
                                            &month, &year);
        if (rc != PLDM_SUCCESS || cc != PLDM_SUCCESS)
        {
            std::cerr << "Response Message Error: "
                      << "rc=" << rc << ",cc=" << (int)cc << std::endl;
            return;
        }

        std::stringstream dt;
        ordered_json data;
        dt << bcd2dec16(year) << "-" << setWidth(month) << "-" << setWidth(day)
           << " " << setWidth(hours) << ":" << setWidth(minutes) << ":"
           << setWidth(seconds);
        data["Response"] = dt.str();
        pldmtool::helper::DisplayInJson(data);
    }

  private:
    static std::string setWidth(uint8_t data)
    {
        std::stringstream s;
        s << std::setfill('0') << std::setw(2)
          << static_cast<uint32_t>(bcd2dec8(data));
        return s.str();
    }
};

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

    explicit SetDateTime(const char* type, const char* name, CLI::App* app) :
        CommandInterface(type, name, app)
    {
        app->add_option("-d,--data", tmData,
                        "set date time data\n"
                        "eg: YYYYMMDDHHMMSS")
            ->required();
    }

    std::pair<int, std::vector<uint8_t>> createRequestMsg() override
    {
        std::vector<uint8_t> requestMsg(sizeof(pldm_msg_hdr) +
                                        sizeof(struct pldm_set_date_time_req));
        auto request = reinterpret_cast<pldm_msg*>(requestMsg.data());
        uint16_t year = 0;
        uint8_t month = 0;
        uint8_t day = 0;
        uint8_t hours = 0;
        uint8_t minutes = 0;
        uint8_t seconds = 0;

        if (!uintToDate(tmData, &year, &month, &day, &hours, &minutes,
                        &seconds))
        {
            std::cerr << "decode date Error: "
                      << "tmData=" << tmData << std::endl;

            return {PLDM_ERROR_INVALID_DATA, requestMsg};
        }

        auto rc = encode_set_date_time_req(
            instanceId, seconds, minutes, hours, day, month, year, request,
            sizeof(struct pldm_set_date_time_req));

        return {rc, requestMsg};
    }

    void parseResponseMsg(pldm_msg* responsePtr, size_t payloadLength) override
    {
        uint8_t completionCode = 0;
        auto rc = decode_set_date_time_resp(responsePtr, payloadLength,
                                            &completionCode);

        if (rc != PLDM_SUCCESS || completionCode != PLDM_SUCCESS)
        {
            std::cerr << "Response Message Error: "
                      << "rc=" << rc << ",cc=" << (int)completionCode
                      << std::endl;
            return;
        }

        ordered_json data;
        data["Response"] = "SUCCESS";
        pldmtool::helper::DisplayInJson(data);
    }

  private:
    uint64_t tmData;
};

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

    using Table = std::vector<uint8_t>;

    using CommandInterface::CommandInterface;

    static inline const std::map<pldm_bios_attribute_type, const char*>
        attrTypeMap = {
            {PLDM_BIOS_ENUMERATION, "BIOSEnumeration"},
            {PLDM_BIOS_ENUMERATION_READ_ONLY, "BIOSEnumerationReadOnly"},
            {PLDM_BIOS_STRING, "BIOSString"},
            {PLDM_BIOS_STRING_READ_ONLY, "BIOSStringReadOnly"},
            {PLDM_BIOS_PASSWORD, "BIOSPassword"},
            {PLDM_BIOS_PASSWORD_READ_ONLY, "BIOSPasswordReadOnly"},
            {PLDM_BIOS_INTEGER, "BIOSInteger"},
            {PLDM_BIOS_INTEGER_READ_ONLY, "BIOSIntegerReadOnly"},

        };

    std::pair<int, std::vector<uint8_t>> createRequestMsg() override
    {
        return {PLDM_ERROR, {}};
    }

    void parseResponseMsg(pldm_msg*, size_t) override {}

    std::optional<Table> getBIOSTable(pldm_bios_table_types tableType)
    {
        std::vector<uint8_t> requestMsg(sizeof(pldm_msg_hdr) +
                                        PLDM_GET_BIOS_TABLE_REQ_BYTES);
        auto request = reinterpret_cast<pldm_msg*>(requestMsg.data());

        auto rc = encode_get_bios_table_req(instanceId, 0, PLDM_GET_FIRSTPART,
                                            tableType, request);
        if (rc != PLDM_SUCCESS)
        {
            std::cerr << "Encode GetBIOSTable Error, tableType=," << tableType
                      << " ,rc=" << rc << std::endl;
            return std::nullopt;
        }
        std::vector<uint8_t> responseMsg;
        rc = pldmSendRecv(requestMsg, responseMsg);
        if (rc != PLDM_SUCCESS)
        {
            std::cerr << "PLDM: Communication Error, rc =" << rc << std::endl;
            return std::nullopt;
        }

        uint8_t cc = 0, transferFlag = 0;
        uint32_t nextTransferHandle = 0;
        size_t bios_table_offset;
        auto responsePtr =
            reinterpret_cast<struct pldm_msg*>(responseMsg.data());
        auto payloadLength = responseMsg.size() - sizeof(pldm_msg_hdr);

        rc = decode_get_bios_table_resp(responsePtr, payloadLength, &cc,
                                        &nextTransferHandle, &transferFlag,
                                        &bios_table_offset);

        if (rc != PLDM_SUCCESS || cc != PLDM_SUCCESS)
        {
            std::cerr << "GetBIOSTable Response Error: tableType=" << tableType
                      << ", rc=" << rc << ", cc=" << (int)cc << std::endl;
            return std::nullopt;
        }
        auto tableData =
            reinterpret_cast<char*>((responsePtr->payload) + bios_table_offset);
        auto tableSize = payloadLength - sizeof(nextTransferHandle) -
                         sizeof(transferFlag) - sizeof(cc);
        return std::make_optional<Table>(tableData, tableData + tableSize);
    }

    const pldm_bios_attr_table_entry*
        findAttrEntryByName(const std::string& name, const Table& attrTable,
                            const Table& stringTable)
    {
        auto stringEntry = pldm_bios_table_string_find_by_string(
            stringTable.data(), stringTable.size(), name.c_str());
        if (stringEntry == nullptr)
        {
            return nullptr;
        }

        auto nameHandle =
            pldm_bios_table_string_entry_decode_handle(stringEntry);

        for (auto attr : BIOSTableIter<PLDM_BIOS_ATTR_TABLE>(attrTable.data(),
                                                             attrTable.size()))
        {
            auto attrNameHandle =
                pldm_bios_table_attr_entry_decode_string_handle(attr);
            if (attrNameHandle == nameHandle)
            {
                return attr;
            }
        }
        return nullptr;
    }

    std::optional<uint16_t> findAttrHandleByName(const std::string& name,
                                                 const Table& attrTable,
                                                 const Table& stringTable)
    {
        auto attribute = findAttrEntryByName(name, attrTable, stringTable);
        if (attribute == nullptr)
        {
            return std::nullopt;
        }

        return pldm_bios_table_attr_entry_decode_attribute_handle(attribute);
    }

    std::string decodeStringFromStringEntry(
        const pldm_bios_string_table_entry* stringEntry)
    {
        auto strLength =
            pldm_bios_table_string_entry_decode_string_length(stringEntry);
        std::vector<char> buffer(strLength + 1 /* sizeof '\0' */);
        // Preconditions are upheld therefore no error check necessary
        pldm_bios_table_string_entry_decode_string(stringEntry, buffer.data(),
                                                   buffer.size());

        return std::string(buffer.data(), buffer.data() + strLength);
    }

    std::string displayStringHandle(uint16_t handle,
                                    const std::optional<Table>& stringTable,
                                    bool displayHandle = true)
    {
        std::string displayString = std::to_string(handle);
        if (!stringTable)
        {
            return displayString;
        }
        auto stringEntry = pldm_bios_table_string_find_by_handle(
            stringTable->data(), stringTable->size(), handle);
        if (stringEntry == nullptr)
        {
            return displayString;
        }

        auto decodedStr = decodeStringFromStringEntry(stringEntry);
        if (!displayHandle)
        {
            return decodedStr;
        }

        return displayString + "(" + decodedStr + ")";
    }

    std::string displayEnumValueByIndex(uint16_t attrHandle, uint8_t index,
                                        const std::optional<Table>& attrTable,
                                        const std::optional<Table>& stringTable)
    {
        std::string displayString;
        if (!attrTable)
        {
            return displayString;
        }

        auto attrEntry = pldm_bios_table_attr_find_by_handle(
            attrTable->data(), attrTable->size(), attrHandle);
        if (attrEntry == nullptr)
        {
            return displayString;
        }
        uint8_t pvNum;
        int rc = pldm_bios_table_attr_entry_enum_decode_pv_num(attrEntry,
                                                               &pvNum);
        if (rc != PLDM_SUCCESS)
        {
            return displayString;
        }
        std::vector<uint16_t> pvHandls(pvNum);
        // Preconditions are upheld therefore no error check necessary
        pldm_bios_table_attr_entry_enum_decode_pv_hdls(
            attrEntry, pvHandls.data(), pvHandls.size());
        return displayStringHandle(pvHandls[index], stringTable, false);
    }

    void displayAttributeValueEntry(
        const pldm_bios_attr_val_table_entry* tableEntry,
        const std::optional<Table>& attrTable,
        const std::optional<Table>& stringTable, bool verbose,
        ordered_json& output)
    {
        auto attrHandle =
            pldm_bios_table_attr_value_entry_decode_attribute_handle(
                tableEntry);
        auto attrType = static_cast<pldm_bios_attribute_type>(
            pldm_bios_table_attr_value_entry_decode_attribute_type(tableEntry));

        if (verbose)
        {
            output["AttributeHandle"] = attrHandle;
            if (attrTypeMap.contains(attrType))
            {
                output["AttributeType"] = attrTypeMap.at(attrType);
            }
            else
            {
                std::cout << "Get AttributeType failed.\n";
            }
        }
        switch (attrType)
        {
            case PLDM_BIOS_ENUMERATION:
            case PLDM_BIOS_ENUMERATION_READ_ONLY:
            {
                auto count =
                    pldm_bios_table_attr_value_entry_enum_decode_number(
                        tableEntry);
                std::vector<uint8_t> handles(count);
                pldm_bios_table_attr_value_entry_enum_decode_handles(
                    tableEntry, handles.data(), handles.size());
                if (verbose)
                {
                    output["NumberOfCurrentValues"] = (int)count;
                }
                for (size_t i = 0; i < handles.size(); i++)
                {
                    if (verbose)
                    {
                        output["CurrentValueStringHandleIndex[" +
                               std::to_string(i) + "]"] =
                            displayEnumValueByIndex(attrHandle, handles[i],
                                                    attrTable, stringTable);
                    }
                    else
                    {
                        output["CurrentValue"] = displayEnumValueByIndex(
                            attrHandle, handles[i], attrTable, stringTable);
                    }
                }
                break;
            }
            case PLDM_BIOS_INTEGER:
            case PLDM_BIOS_INTEGER_READ_ONLY:
            {
                auto cv = pldm_bios_table_attr_value_entry_integer_decode_cv(
                    tableEntry);
                output["CurrentValue"] = cv;
                break;
            }
            case PLDM_BIOS_STRING:
            case PLDM_BIOS_STRING_READ_ONLY:
            {
                variable_field currentString;
                pldm_bios_table_attr_value_entry_string_decode_string(
                    tableEntry, &currentString);
                if (verbose)
                {
                    output["CurrentStringLength"] = currentString.length;
                    output["CurrentString"] = std::string(
                        reinterpret_cast<const char*>(currentString.ptr),
                        currentString.length);
                }
                else
                {
                    output["CurrentValue"] = std::string(
                        reinterpret_cast<const char*>(currentString.ptr),
                        currentString.length);
                }

                break;
            }
            case PLDM_BIOS_PASSWORD:
            case PLDM_BIOS_PASSWORD_READ_ONLY:
            {
                std::cout << "Password attribute: Not Supported" << std::endl;
                break;
            }
        }
    }
};

class GetBIOSTable : public GetBIOSTableHandler
{
  public:
    ~GetBIOSTable() = default;
    GetBIOSTable() = delete;
    GetBIOSTable(const GetBIOSTable&) = delete;
    GetBIOSTable(GetBIOSTable&&) = delete;
    GetBIOSTable& operator=(const GetBIOSTable&) = delete;
    GetBIOSTable& operator=(GetBIOSTable&&) = delete;

    using Table = std::vector<uint8_t>;

    explicit GetBIOSTable(const char* type, const char* name, CLI::App* app) :
        GetBIOSTableHandler(type, name, app)
    {
        app->add_option("-t,--type", pldmBIOSTableType, "pldm bios table type")
            ->required()
            ->transform(
                CLI::CheckedTransformer(pldmBIOSTableTypes, CLI::ignore_case));
    }

    void exec() override
    {
        switch (pldmBIOSTableType)
        {
            case PLDM_BIOS_STRING_TABLE:
            {
                auto stringTable = getBIOSTable(PLDM_BIOS_STRING_TABLE);
                decodeStringTable(stringTable);
                break;
            }
            case PLDM_BIOS_ATTR_TABLE:
            {
                auto stringTable = getBIOSTable(PLDM_BIOS_STRING_TABLE);
                auto attrTable = getBIOSTable(PLDM_BIOS_ATTR_TABLE);

                decodeAttributeTable(attrTable, stringTable);
                break;
            }
            case PLDM_BIOS_ATTR_VAL_TABLE:
            {
                auto stringTable = getBIOSTable(PLDM_BIOS_STRING_TABLE);
                auto attrTable = getBIOSTable(PLDM_BIOS_ATTR_TABLE);
                auto attrValTable = getBIOSTable(PLDM_BIOS_ATTR_VAL_TABLE);

                decodeAttributeValueTable(attrValTable, attrTable, stringTable);
                break;
            }
        }
    }

  private:
    pldm_bios_table_types pldmBIOSTableType;

    void decodeStringTable(const std::optional<Table>& stringTable)
    {
        if (!stringTable)
        {
            std::cerr << "GetBIOSStringTable Error" << std::endl;
            return;
        }
        ordered_json stringdata;

        for (auto tableEntry : BIOSTableIter<PLDM_BIOS_STRING_TABLE>(
                 stringTable->data(), stringTable->size()))
        {
            auto strHandle =
                pldm_bios_table_string_entry_decode_handle(tableEntry);
            auto strTableData = decodeStringFromStringEntry(tableEntry);
            stringdata[std::to_string(strHandle)] = strTableData;
        }
        pldmtool::helper::DisplayInJson(stringdata);
    }
    void decodeAttributeTable(const std::optional<Table>& attrTable,
                              const std::optional<Table>& stringTable)
    {
        if (!stringTable)
        {
            std::cerr << "GetBIOSAttributeTable Error" << std::endl;
            return;
        }
        ordered_json output;

        for (auto entry : BIOSTableIter<PLDM_BIOS_ATTR_TABLE>(
                 attrTable->data(), attrTable->size()))
        {
            ordered_json attrdata;

            auto attrHandle =
                pldm_bios_table_attr_entry_decode_attribute_handle(entry);
            auto attrNameHandle =
                pldm_bios_table_attr_entry_decode_string_handle(entry);
            auto attrType = static_cast<pldm_bios_attribute_type>(
                pldm_bios_table_attr_entry_decode_attribute_type(entry));

            attrdata["AttributeHandle"] = attrHandle;
            attrdata["AttributeNameHandle"] =
                displayStringHandle(attrNameHandle, stringTable);
            if (attrTypeMap.contains(attrType))
            {
                attrdata["AttributeType"] = attrTypeMap.at(attrType);
            }
            else
            {
                std::cout << "Get AttributeType failed.\n";
            }

            switch (attrType)
            {
                case PLDM_BIOS_ENUMERATION:
                case PLDM_BIOS_ENUMERATION_READ_ONLY:
                {
                    uint8_t pvNum;
                    // Preconditions are upheld therefore no error check
                    // necessary
                    pldm_bios_table_attr_entry_enum_decode_pv_num(entry,
                                                                  &pvNum);
                    std::vector<uint16_t> pvHandls(pvNum);
                    // Preconditions are upheld therefore no error check
                    // necessary
                    pldm_bios_table_attr_entry_enum_decode_pv_hdls(
                        entry, pvHandls.data(), pvHandls.size());
                    uint8_t defNum;
                    // Preconditions are upheld therefore no error check
                    // necessary
                    pldm_bios_table_attr_entry_enum_decode_def_num(entry,
                                                                   &defNum);
                    std::vector<uint8_t> defIndices(defNum);
                    pldm_bios_table_attr_entry_enum_decode_def_indices(
                        entry, defIndices.data(), defIndices.size());

                    attrdata["NumberOfPossibleValues"] = (int)pvNum;

                    for (size_t i = 0; i < pvHandls.size(); i++)
                    {
                        attrdata["PossibleValueStringHandle[" +
                                 std::to_string(i) + "]"] =
                            displayStringHandle(pvHandls[i], stringTable);
                    }
                    attrdata["NumberOfDefaultValues"] = (int)defNum;
                    for (size_t i = 0; i < defIndices.size(); i++)
                    {
                        attrdata["DefaultValueStringHandleIndex[" +
                                 std::to_string(i) + "]"] = (int)defIndices[i];
                        attrdata["DefaultValueStringHandle"] =
                            displayStringHandle(pvHandls[defIndices[i]],
                                                stringTable);
                    }
                    break;
                }
                case PLDM_BIOS_INTEGER:
                case PLDM_BIOS_INTEGER_READ_ONLY:
                {
                    uint64_t lower, upper, def;
                    uint32_t scalar;
                    pldm_bios_table_attr_entry_integer_decode(
                        entry, &lower, &upper, &scalar, &def);
                    attrdata["LowerBound"] = lower;
                    attrdata["UpperBound"] = upper;
                    attrdata["ScalarIncrement"] = scalar;
                    attrdata["DefaultValue"] = def;
                    break;
                }
                case PLDM_BIOS_STRING:
                case PLDM_BIOS_STRING_READ_ONLY:
                {
                    auto strType =
                        pldm_bios_table_attr_entry_string_decode_string_type(
                            entry);
                    auto min =
                        pldm_bios_table_attr_entry_string_decode_min_length(
                            entry);
                    auto max =
                        pldm_bios_table_attr_entry_string_decode_max_length(
                            entry);
                    uint16_t def;
                    // Preconditions are upheld therefore no error check
                    // necessary
                    pldm_bios_table_attr_entry_string_decode_def_string_length_check(
                        entry, &def);
                    std::vector<char> defString(def + 1);
                    pldm_bios_table_attr_entry_string_decode_def_string(
                        entry, defString.data(), defString.size());

                    std::stringstream stringtype;
                    stringtype << "0x" << std::hex << std::setw(2)
                               << std::setfill('0') << (int)strType << std::dec
                               << std::setw(0);
                    attrdata["StringType"] = stringtype.str();
                    attrdata["MinimumStringLength"] = (int)min;
                    attrdata["MaximumStringLength"] = (int)max;
                    attrdata["DefaultStringLength"] = (int)def;
                    attrdata["DefaultString"] = defString.data();
                    break;
                }
                case PLDM_BIOS_PASSWORD:
                case PLDM_BIOS_PASSWORD_READ_ONLY:
                    std::cout << "Password attribute: Not Supported"
                              << std::endl;
            }
            output.emplace_back(std::move(attrdata));
        }
        pldmtool::helper::DisplayInJson(output);
    }
    void decodeAttributeValueTable(const std::optional<Table>& attrValTable,
                                   const std::optional<Table>& attrTable,
                                   const std::optional<Table>& stringTable)
    {
        if (!attrValTable)
        {
            std::cerr << "GetBIOSAttributeValueTable Error" << std::endl;
            return;
        }
        ordered_json output;
        for (auto tableEntry : BIOSTableIter<PLDM_BIOS_ATTR_VAL_TABLE>(
                 attrValTable->data(), attrValTable->size()))
        {
            ordered_json attrValueData;
            displayAttributeValueEntry(tableEntry, attrTable, stringTable, true,
                                       attrValueData);
            output.emplace_back(attrValueData);
        }
        pldmtool::helper::DisplayInJson(output);
    }
};

class GetBIOSAttributeCurrentValueByHandle : public GetBIOSTableHandler
{
  public:
    ~GetBIOSAttributeCurrentValueByHandle() = default;
    GetBIOSAttributeCurrentValueByHandle(
        const GetBIOSAttributeCurrentValueByHandle&) = delete;
    GetBIOSAttributeCurrentValueByHandle(
        GetBIOSAttributeCurrentValueByHandle&&) = delete;
    GetBIOSAttributeCurrentValueByHandle&
        operator=(const GetBIOSAttributeCurrentValueByHandle&) = delete;
    GetBIOSAttributeCurrentValueByHandle&
        operator=(GetBIOSAttributeCurrentValueByHandle&&) = delete;

    explicit GetBIOSAttributeCurrentValueByHandle(const char* type,
                                                  const char* name,
                                                  CLI::App* app) :
        GetBIOSTableHandler(type, name, app)
    {
        app->add_option("-a, --attribute", attrName, "pldm BIOS attribute name")
            ->required();
    }

    void exec()
    {
        auto stringTable = getBIOSTable(PLDM_BIOS_STRING_TABLE);
        auto attrTable = getBIOSTable(PLDM_BIOS_ATTR_TABLE);

        if (!stringTable || !attrTable)
        {
            std::cout << "StringTable/AttrTable Unavailable" << std::endl;
            return;
        }

        auto handle = findAttrHandleByName(attrName, *attrTable, *stringTable);
        if (!handle)
        {
            std::cerr << "Can not find the attribute " << attrName << std::endl;
            return;
        }

        std::vector<uint8_t> requestMsg(
            sizeof(pldm_msg_hdr) +
            PLDM_GET_BIOS_ATTR_CURR_VAL_BY_HANDLE_REQ_BYTES);
        auto request = reinterpret_cast<pldm_msg*>(requestMsg.data());

        auto rc = encode_get_bios_attribute_current_value_by_handle_req(
            instanceId, 0, PLDM_GET_FIRSTPART, *handle, request);
        if (rc != PLDM_SUCCESS)
        {
            std::cerr << "PLDM: Request Message Error, rc =" << rc << std::endl;
            return;
        }

        std::vector<uint8_t> responseMsg;
        rc = pldmSendRecv(requestMsg, responseMsg);
        if (rc != PLDM_SUCCESS)
        {
            std::cerr << "PLDM: Communication Error, rc =" << rc << std::endl;
            return;
        }

        uint8_t cc = 0, transferFlag = 0;
        uint32_t nextTransferHandle = 0;
        struct variable_field attributeData;
        auto responsePtr =
            reinterpret_cast<struct pldm_msg*>(responseMsg.data());
        auto payloadLength = responseMsg.size() - sizeof(pldm_msg_hdr);

        rc = decode_get_bios_attribute_current_value_by_handle_resp(
            responsePtr, payloadLength, &cc, &nextTransferHandle, &transferFlag,
            &attributeData);
        if (rc != PLDM_SUCCESS || cc != PLDM_SUCCESS)
        {
            std::cerr << "Response Message Error: "
                      << "rc=" << rc << ",cc=" << (int)cc << std::endl;
            return;
        }

        auto tableEntry =
            reinterpret_cast<const struct pldm_bios_attr_val_table_entry*>(
                attributeData.ptr);

        ordered_json avdata;
        displayAttributeValueEntry(tableEntry, attrTable, stringTable, false,
                                   avdata);
        pldmtool::helper::DisplayInJson(avdata);
    }

  private:
    std::string attrName;
};

class SetBIOSAttributeCurrentValue : public GetBIOSTableHandler
{
  public:
    ~SetBIOSAttributeCurrentValue() = default;
    SetBIOSAttributeCurrentValue() = delete;
    SetBIOSAttributeCurrentValue(const SetBIOSAttributeCurrentValue&) = delete;
    SetBIOSAttributeCurrentValue(SetBIOSAttributeCurrentValue&&) = delete;
    SetBIOSAttributeCurrentValue&
        operator=(const SetBIOSAttributeCurrentValue&) = delete;
    SetBIOSAttributeCurrentValue&
        operator=(SetBIOSAttributeCurrentValue&&) = delete;

    explicit SetBIOSAttributeCurrentValue(const char* type, const char* name,
                                          CLI::App* app) :
        GetBIOSTableHandler(type, name, app)
    {
        app->add_option("-a, --attribute", attrName, "pldm attribute name")
            ->required();
        app->add_option("-d, --data", attrValue, "pldm attribute value")
            ->required();
        // -v is conflict with --verbose in class CommandInterface, so used -d
    }

    void exec()
    {
        auto stringTable = getBIOSTable(PLDM_BIOS_STRING_TABLE);
        auto attrTable = getBIOSTable(PLDM_BIOS_ATTR_TABLE);
        auto attrValueTable = getBIOSTable(PLDM_BIOS_ATTR_VAL_TABLE);

        if (!stringTable || !attrTable)
        {
            std::cout << "StringTable/AttrTable Unavailable" << std::endl;
            return;
        }

        auto attrEntry = findAttrEntryByName(attrName, *attrTable,
                                             *stringTable);
        if (attrEntry == nullptr)
        {
            std::cout << "Could not find attribute :" << attrName << std::endl;
            return;
        }

        std::vector<uint8_t> requestMsg;

        int rc = 0;
        auto attrType = attrEntry->attr_type;
        size_t entryLength = 1;
        std::vector<uint8_t> attrValueEntry(entryLength, 0);

        switch (attrType)
        {
            case PLDM_BIOS_ENUMERATION:
            case PLDM_BIOS_ENUMERATION_READ_ONLY:
            {
                entryLength =
                    pldm_bios_table_attr_value_entry_encode_enum_length(1);
                uint8_t pvNum;
                // Preconditions are upheld therefore no error check necessary
                pldm_bios_table_attr_entry_enum_decode_pv_num(attrEntry,
                                                              &pvNum);
                std::vector<uint16_t> pvHdls(pvNum, 0);
                // Preconditions are upheld therefore no error check necessary
                pldm_bios_table_attr_entry_enum_decode_pv_hdls(
                    attrEntry, pvHdls.data(), pvNum);
                auto stringEntry = pldm_bios_table_string_find_by_string(
                    stringTable->data(), stringTable->size(),
                    attrValue.c_str());
                if (stringEntry == nullptr)
                {
                    std::cout
                        << "Set Attribute Error: It's not a possible value"
                        << std::endl;
                    return;
                }
                auto valueHandle =
                    pldm_bios_table_string_entry_decode_handle(stringEntry);

                uint8_t i;
                for (i = 0; i < pvNum; i++)
                {
                    if (valueHandle == pvHdls[i])
                        break;
                }
                if (i == pvNum)
                {
                    std::cout
                        << "Set Attribute Error: It's not a possible value"
                        << std::endl;
                    return;
                }

                attrValueEntry.resize(entryLength);
                std::vector<uint8_t> handles = {i};
                int rc = pldm_bios_table_attr_value_entry_encode_enum_check(
                    attrValueEntry.data(), attrValueEntry.size(),
                    attrEntry->attr_handle, attrType, 1, handles.data());
                if (rc != PLDM_SUCCESS)
                {
                    std::cout
                        << "Failed to encode BIOS table attribute enum: " << rc
                        << std::endl;
                    return;
                }
                break;
            }
            case PLDM_BIOS_STRING:
            case PLDM_BIOS_STRING_READ_ONLY:
            {
                entryLength =
                    pldm_bios_table_attr_value_entry_encode_string_length(
                        attrValue.size());

                attrValueEntry.resize(entryLength);

                int rc = pldm_bios_table_attr_value_entry_encode_string_check(
                    attrValueEntry.data(), entryLength, attrEntry->attr_handle,
                    attrType, attrValue.size(), attrValue.c_str());
                if (rc != PLDM_SUCCESS)
                {
                    std::cout
                        << "Failed to encode BIOS table attribute string: "
                        << rc << std::endl;
                    return;
                }
                break;
            }
            case PLDM_BIOS_INTEGER:
            case PLDM_BIOS_INTEGER_READ_ONLY:
            {
                uint64_t value = std::stoll(attrValue);
                entryLength =
                    pldm_bios_table_attr_value_entry_encode_integer_length();
                attrValueEntry.resize(entryLength);
                int rc = pldm_bios_table_attr_value_entry_encode_integer_check(
                    attrValueEntry.data(), entryLength, attrEntry->attr_handle,
                    attrType, value);
                if (rc != PLDM_SUCCESS)
                {
                    std::cout
                        << "Failed to encode BIOS table attribute integer: "
                        << rc << std::endl;
                    return;
                }
                break;
            }
        }

        requestMsg.resize(entryLength + sizeof(pldm_msg_hdr) +
                          PLDM_SET_BIOS_ATTR_CURR_VAL_MIN_REQ_BYTES);

        rc = encode_set_bios_attribute_current_value_req(
            instanceId, 0, PLDM_START_AND_END, attrValueEntry.data(),
            attrValueEntry.size(),
            reinterpret_cast<pldm_msg*>(requestMsg.data()),
            requestMsg.size() - sizeof(pldm_msg_hdr));

        if (rc != PLDM_SUCCESS)
        {
            std::cerr << "PLDM: Request Message Error, rc =" << rc << std::endl;
            return;
        }
        std::vector<uint8_t> responseMsg;
        rc = pldmSendRecv(requestMsg, responseMsg);
        if (rc != PLDM_SUCCESS)
        {
            std::cerr << "PLDM: Communication Error, rc =" << rc << std::endl;
            return;
        }
        uint8_t cc = 0;
        uint32_t nextTransferHandle = 0;
        auto responsePtr =
            reinterpret_cast<struct pldm_msg*>(responseMsg.data());
        auto payloadLength = responseMsg.size() - sizeof(pldm_msg_hdr);

        rc = decode_set_bios_attribute_current_value_resp(
            responsePtr, payloadLength, &cc, &nextTransferHandle);
        if (rc != PLDM_SUCCESS || cc != PLDM_SUCCESS)
        {
            std::cerr << "Response Message Error: "
                      << "rc=" << rc << ",cc=" << (int)cc << std::endl;
            return;
        }

        ordered_json data;
        data["Response"] = "SUCCESS";
        pldmtool::helper::DisplayInJson(data);
    }

  private:
    std::string attrName;
    std::string attrValue;
};

void registerCommand(CLI::App& app)
{
    auto bios = app.add_subcommand("bios", "bios type command");
    bios->require_subcommand(1);
    auto getDateTime = bios->add_subcommand("GetDateTime", "get date time");
    commands.push_back(
        std::make_unique<GetDateTime>("bios", "GetDateTime", getDateTime));

    auto setDateTime = bios->add_subcommand("SetDateTime",
                                            "set host date time");
    commands.push_back(
        std::make_unique<SetDateTime>("bios", "setDateTime", setDateTime));

    auto getBIOSTable = bios->add_subcommand("GetBIOSTable", "get bios table");
    commands.push_back(
        std::make_unique<GetBIOSTable>("bios", "GetBIOSTable", getBIOSTable));

    auto getBIOSAttributeCurrentValueByHandle =
        bios->add_subcommand("GetBIOSAttributeCurrentValueByHandle",
                             "get bios attribute current value by handle");
    commands.push_back(std::make_unique<GetBIOSAttributeCurrentValueByHandle>(
        "bios", "GetBIOSAttributeCurrentValueByHandle",
        getBIOSAttributeCurrentValueByHandle));

    auto setBIOSAttributeCurrentValue = bios->add_subcommand(
        "SetBIOSAttributeCurrentValue", "set bios attribute current value");
    commands.push_back(std::make_unique<SetBIOSAttributeCurrentValue>(
        "bios", "SetBIOSAttributeCurrentValue", setBIOSAttributeCurrentValue));
}

} // namespace bios

} // namespace pldmtool
