#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_check(
            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_check(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_check(
            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);
                if (verbose)
                {
                    output["CurrentValue"] = cv;
                }
                else
                {
                    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_check(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_check(
                        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_check(
                        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 Unavaliable" << 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 Unavaliable" << 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_check(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_check(
                    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
