#include "config.h"

#include "vpd_tool.hpp"

#include "tool_constants.hpp"
#include "tool_types.hpp"
#include "tool_utils.hpp"

#include <cstdlib>
#include <iostream>
#include <regex>
#include <tuple>
namespace vpd
{
int VpdTool::readKeyword(
    const std::string& i_vpdPath, const std::string& i_recordName,
    const std::string& i_keywordName, const bool i_onHardware,
    const std::string& i_fileToSave)
{
    int l_rc = constants::FAILURE;
    try
    {
        types::DbusVariantType l_keywordValue;
        if (i_onHardware)
        {
            l_keywordValue = utils::readKeywordFromHardware(
                i_vpdPath, std::make_tuple(i_recordName, i_keywordName));
        }
        else
        {
            std::string l_inventoryObjectPath(
                constants::baseInventoryPath + i_vpdPath);

            l_keywordValue = utils::readDbusProperty(
                constants::inventoryManagerService, l_inventoryObjectPath,
                constants::ipzVpdInfPrefix + i_recordName, i_keywordName);
        }

        if (const auto l_value =
                std::get_if<types::BinaryVector>(&l_keywordValue);
            l_value && !l_value->empty())
        {
            // ToDo: Print value in both ASCII and hex formats
            const std::string& l_keywordStrValue =
                utils::getPrintableValue(*l_value);

            if (i_fileToSave.empty())
            {
                utils::displayOnConsole(i_vpdPath, i_keywordName,
                                        l_keywordStrValue);
                l_rc = constants::SUCCESS;
            }
            else
            {
                if (utils::saveToFile(i_fileToSave, l_keywordStrValue))
                {
                    std::cout
                        << "Value read is saved on the file: " << i_fileToSave
                        << std::endl;
                    l_rc = constants::SUCCESS;
                }
                else
                {
                    std::cerr
                        << "Error while saving the read value on the file: "
                        << i_fileToSave
                        << "\nDisplaying the read value on console"
                        << std::endl;
                    utils::displayOnConsole(i_vpdPath, i_keywordName,
                                            l_keywordStrValue);
                }
            }
        }
        else
        {
            // TODO: Enable logging when verbose is enabled.
            std::cout << "Invalid data type or empty data received."
                      << std::endl;
        }
    }
    catch (const std::exception& l_ex)
    {
        // TODO: Enable logging when verbose is enabled.
        std::cerr << "Read keyword's value failed for path: " << i_vpdPath
                  << ", Record: " << i_recordName << ", Keyword: "
                  << i_keywordName << ", error: " << l_ex.what() << std::endl;
    }
    return l_rc;
}

int VpdTool::dumpObject(std::string i_fruPath) const noexcept
{
    int l_rc{constants::FAILURE};
    try
    {
        // ToDo: For PFuture system take only full path from the user.
        i_fruPath = constants::baseInventoryPath + i_fruPath;

        nlohmann::json l_resultJsonArray = nlohmann::json::array({});
        const nlohmann::json l_fruJson = getFruProperties(i_fruPath);
        if (!l_fruJson.empty())
        {
            l_resultJsonArray += l_fruJson;

            utils::printJson(l_resultJsonArray);
        }
        else
        {
            std::cout << "FRU [" << i_fruPath
                      << "] is not present in the system" << std::endl;
        }
        l_rc = constants::SUCCESS;
    }
    catch (std::exception& l_ex)
    {
        // TODO: Enable logging when verbose is enabled.
        std::cerr << "Dump Object failed for FRU [" << i_fruPath
                  << "], Error: " << l_ex.what() << std::endl;
    }
    return l_rc;
}

template <typename PropertyType>
void VpdTool::populateInterfaceJson(const std::string& i_inventoryObjPath,
                                    const std::string& i_infName,
                                    const std::vector<std::string>& i_propList,
                                    nlohmann::json& io_fruJsonObject) const
{
    nlohmann::json l_interfaceJsonObj = nlohmann::json::object({});

    auto l_readProperties = [i_inventoryObjPath, &l_interfaceJsonObj, i_infName,
                             this](const std::string& i_property) {
        const nlohmann::json l_propertyJsonObj =
            getInventoryPropertyJson<PropertyType>(i_inventoryObjPath,
                                                   i_infName, i_property);
        l_interfaceJsonObj.insert(l_propertyJsonObj.cbegin(),
                                  l_propertyJsonObj.cend());
    };

    std::for_each(i_propList.cbegin(), i_propList.cend(), l_readProperties);

    if (!l_interfaceJsonObj.empty())
    {
        io_fruJsonObject.insert(l_interfaceJsonObj.cbegin(),
                                l_interfaceJsonObj.cend());
    }
}

void VpdTool::populateFruJson(
    const std::string& i_inventoryObjPath, nlohmann::json& io_fruJsonObject,
    const std::vector<std::string>& i_interfaceList) const
{
    for (const auto& l_interface : i_interfaceList)
    {
        if (l_interface == constants::inventoryItemInf)
        {
            const std::vector<std::string> l_properties = {"PrettyName"};
            populateInterfaceJson<std::string>(i_inventoryObjPath,
                                               constants::inventoryItemInf,
                                               l_properties, io_fruJsonObject);
            continue;
        }

        if (l_interface == constants::locationCodeInf)
        {
            const std::vector<std::string> l_properties = {"LocationCode"};
            populateInterfaceJson<std::string>(i_inventoryObjPath,
                                               constants::locationCodeInf,
                                               l_properties, io_fruJsonObject);
            continue;
        }

        if (l_interface == constants::viniInf)
        {
            const std::vector<std::string> l_properties = {"SN", "PN", "CC",
                                                           "FN", "DR"};
            populateInterfaceJson<vpd::types::BinaryVector>(
                i_inventoryObjPath, constants::viniInf, l_properties,
                io_fruJsonObject);
            continue;
        }

        if (l_interface == constants::assetInf)
        {
            if (std::find(i_interfaceList.begin(), i_interfaceList.end(),
                          constants::viniInf) != i_interfaceList.end())
            {
                // The value will be filled from VINI interface. Don't
                // process asset interface.
                continue;
            }

            const std::vector<std::string> l_properties = {
                "Model", "SerialNumber", "SubModel"};

            populateInterfaceJson<std::string>(i_inventoryObjPath,
                                               constants::assetInf,
                                               l_properties, io_fruJsonObject);
            continue;
        }

        if (l_interface == constants::networkInf)
        {
            const std::vector<std::string> l_properties = {"MACAddress"};
            populateInterfaceJson<std::string>(i_inventoryObjPath,
                                               constants::networkInf,
                                               l_properties, io_fruJsonObject);
            continue;
        }

        if (l_interface == constants::pcieSlotInf)
        {
            const std::vector<std::string> l_properties = {"SlotType"};
            populateInterfaceJson<std::string>(i_inventoryObjPath,
                                               constants::pcieSlotInf,
                                               l_properties, io_fruJsonObject);
            continue;
        }

        if (l_interface == constants::slotNumInf)
        {
            const std::vector<std::string> l_properties = {"SlotNumber"};
            populateInterfaceJson<uint32_t>(i_inventoryObjPath,
                                            constants::slotNumInf, l_properties,
                                            io_fruJsonObject);
            continue;
        }

        if (l_interface == constants::i2cDeviceInf)
        {
            const std::vector<std::string> l_properties = {"Address", "Bus"};
            populateInterfaceJson<uint32_t>(i_inventoryObjPath,
                                            constants::i2cDeviceInf,
                                            l_properties, io_fruJsonObject);
            continue;
        }
    }
}

nlohmann::json VpdTool::getFruProperties(const std::string& i_objectPath) const
{
    // check if FRU is present in the system
    if (!isFruPresent(i_objectPath))
    {
        return nlohmann::json::object_t();
    }

    nlohmann::json l_fruJson = nlohmann::json::object_t({});

    // need to trim out the base inventory path in the FRU JSON.
    const std::string l_displayObjectPath =
        (i_objectPath.find(constants::baseInventoryPath) == std::string::npos)
            ? i_objectPath
            : i_objectPath.substr(strlen(constants::baseInventoryPath));

    l_fruJson.emplace(l_displayObjectPath, nlohmann::json::object_t({}));

    auto& l_fruObject = l_fruJson[l_displayObjectPath];

    types::MapperGetObject l_mapperResp = utils::GetServiceInterfacesForObject(
        i_objectPath, std::vector<std::string>{});

    for (const auto& [l_service, l_interfaceList] : l_mapperResp)
    {
        if (l_service != constants::inventoryManagerService)
        {
            continue;
        }
        populateFruJson(i_objectPath, l_fruObject, l_interfaceList);
    }

    const auto l_typePropertyJson = getFruTypeProperty(i_objectPath);
    if (!l_typePropertyJson.empty())
    {
        l_fruObject.insert(l_typePropertyJson.cbegin(),
                           l_typePropertyJson.cend());
    }

    // insert FRU "TYPE"
    l_fruObject.emplace("TYPE", "FRU");

    return l_fruJson;
}

template <typename PropertyType>
nlohmann::json VpdTool::getInventoryPropertyJson(
    const std::string& i_objectPath, const std::string& i_interface,
    const std::string& i_propertyName) const noexcept
{
    nlohmann::json l_resultInJson = nlohmann::json::object({});
    try
    {
        types::DbusVariantType l_keyWordValue;

        l_keyWordValue =
            utils::readDbusProperty(constants::inventoryManagerService,
                                    i_objectPath, i_interface, i_propertyName);

        if (const auto l_value = std::get_if<PropertyType>(&l_keyWordValue))
        {
            if constexpr (std::is_same<PropertyType, std::string>::value)
            {
                l_resultInJson.emplace(i_propertyName, *l_value);
            }
            else if constexpr (std::is_same<PropertyType, bool>::value)
            {
                l_resultInJson.emplace(i_propertyName,
                                       *l_value ? "true" : "false");
            }
            else if constexpr (std::is_same<PropertyType,
                                            types::BinaryVector>::value)
            {
                const std::string& l_keywordStrValue =
                    vpd::utils::getPrintableValue(*l_value);

                l_resultInJson.emplace(i_propertyName, l_keywordStrValue);
            }
            else if constexpr (std::is_same<PropertyType, uint32_t>::value)
            {
                l_resultInJson.emplace(i_propertyName,
                                       std::to_string(*l_value));
            }
        }
        else
        {
            // TODO: Enable logging when verbose is enabled.
            std::cout << "Invalid data type received." << std::endl;
        }
    }
    catch (const std::exception& l_ex)
    {
        // TODO: Enable logging when verbose is enabled.
        std::cerr << "Read " << i_propertyName
                  << " value for FRU path: " << i_objectPath
                  << ", failed with exception: " << l_ex.what() << std::endl;
    }
    return l_resultInJson;
}

int VpdTool::fixSystemVpd() const noexcept
{
    int l_rc = constants::FAILURE;

    nlohmann::json l_backupRestoreCfgJsonObj = getBackupRestoreCfgJsonObj();
    if (!fetchKeywordInfo(l_backupRestoreCfgJsonObj))
    {
        return l_rc;
    }

    printSystemVpd(l_backupRestoreCfgJsonObj);

    do
    {
        printFixSystemVpdOption(types::UserOption::UseBackupDataForAll);
        printFixSystemVpdOption(
            types::UserOption::UseSystemBackplaneDataForAll);
        printFixSystemVpdOption(types::UserOption::MoreOptions);
        printFixSystemVpdOption(types::UserOption::Exit);

        int l_userSelectedOption = types::UserOption::Exit;
        std::cin >> l_userSelectedOption;

        std::cout << std::endl << std::string(191, '=') << std::endl;

        if (types::UserOption::UseBackupDataForAll == l_userSelectedOption)
        {
            l_rc = updateAllKeywords(l_backupRestoreCfgJsonObj, true);
            break;
        }
        else if (types::UserOption::UseSystemBackplaneDataForAll ==
                 l_userSelectedOption)
        {
            l_rc = updateAllKeywords(l_backupRestoreCfgJsonObj, false);
            break;
        }
        else if (types::UserOption::MoreOptions == l_userSelectedOption)
        {
            l_rc = handleMoreOption(l_backupRestoreCfgJsonObj);
            break;
        }
        else if (types::UserOption::Exit == l_userSelectedOption)
        {
            std::cout << "Exit successfully" << std::endl;
            break;
        }
        else
        {
            std::cout << "Provide a valid option. Retry." << std::endl;
        }
    } while (true);

    return l_rc;
}

int VpdTool::writeKeyword(
    std::string i_vpdPath, const std::string& i_recordName,
    const std::string& i_keywordName, const std::string& i_keywordValue,
    const bool i_onHardware) noexcept
{
    int l_rc = constants::FAILURE;
    try
    {
        if (i_vpdPath.empty() || i_recordName.empty() ||
            i_keywordName.empty() || i_keywordValue.empty())
        {
            throw std::runtime_error("Received input is empty.");
        }

        auto l_paramsToWrite =
            std::make_tuple(i_recordName, i_keywordName,
                            utils::convertToBinary(i_keywordValue));

        if (i_onHardware)
        {
            l_rc = utils::writeKeywordOnHardware(i_vpdPath, l_paramsToWrite);
        }
        else
        {
            i_vpdPath = constants::baseInventoryPath + i_vpdPath;
            l_rc = utils::writeKeyword(i_vpdPath, l_paramsToWrite);
        }

        if (l_rc > 0)
        {
            std::cout << "Data updated successfully " << std::endl;
            l_rc = constants::SUCCESS;
        }
    }
    catch (const std::exception& l_ex)
    {
        // TODO: Enable log when verbose is enabled.
        std::cerr << "Write keyword's value for path: " << i_vpdPath
                  << ", Record: " << i_recordName
                  << ", Keyword: " << i_keywordName
                  << " is failed. Exception: " << l_ex.what() << std::endl;
    }
    return l_rc;
}

nlohmann::json VpdTool::getBackupRestoreCfgJsonObj() const noexcept
{
    nlohmann::json l_parsedBackupRestoreJson{};
    try
    {
        nlohmann::json l_parsedSystemJson =
            utils::getParsedJson(INVENTORY_JSON_SYM_LINK);

        // check for mandatory fields at this point itself.
        if (!l_parsedSystemJson.contains("backupRestoreConfigPath"))
        {
            throw std::runtime_error(
                "backupRestoreConfigPath tag is missing from system config JSON : " +
                std::string(INVENTORY_JSON_SYM_LINK));
        }

        l_parsedBackupRestoreJson =
            utils::getParsedJson(l_parsedSystemJson["backupRestoreConfigPath"]);
    }
    catch (const std::exception& l_ex)
    {
        // TODO: Enable logging when verbose is enabled.
        std::cerr << l_ex.what() << std::endl;
    }

    return l_parsedBackupRestoreJson;
}

int VpdTool::cleanSystemVpd(bool i_syncBiosAttributesRequired) const noexcept
{
    try
    {
        // In order to do syncBiosAttributes, we need BIOS Config Manager
        // service up and running
        if (i_syncBiosAttributesRequired &&
            !utils::isServiceRunning(constants::biosConfigMgrService))
        {
            std::cerr
                << "Cannot sync BIOS attributes as BIOS Config Manager service is not running."
                << std::endl;
            return constants::FAILURE;
        }

        // get the keyword map from backup_restore json
        // iterate through the keyword map get default value of
        // l_keywordName.
        // use writeKeyword API to update default value on hardware,
        // backup and D - Bus.
        const nlohmann::json l_parsedBackupRestoreJson =
            getBackupRestoreCfgJsonObj();

        // check for mandatory tags
        if (l_parsedBackupRestoreJson.contains("source") &&
            l_parsedBackupRestoreJson.contains("backupMap") &&
            l_parsedBackupRestoreJson["source"].contains("hardwarePath") &&
            l_parsedBackupRestoreJson["backupMap"].is_array())
        {
            // get the source hardware path
            const auto& l_hardwarePath =
                l_parsedBackupRestoreJson["source"]["hardwarePath"];

            // iterate through the backup map
            for (const auto& l_aRecordKwInfo :
                 l_parsedBackupRestoreJson["backupMap"])
            {
                // check if Manufacturing Reset is required for this entry
                const bool l_isMfgCleanRequired =
                    l_aRecordKwInfo.value("isManufactureResetRequired", false);

                if (l_isMfgCleanRequired)
                {
                    // get the Record name and Keyword name
                    const std::string& l_srcRecordName =
                        l_aRecordKwInfo.value("sourceRecord", "");
                    const std::string& l_srcKeywordName =
                        l_aRecordKwInfo.value("sourceKeyword", "");

                    // validate the Record name, Keyword name and the
                    // defaultValue
                    if (!l_srcRecordName.empty() && !l_srcKeywordName.empty() &&
                        l_aRecordKwInfo.contains("defaultValue") &&
                        l_aRecordKwInfo["defaultValue"].is_array())
                    {
                        // check if this keyword is used for backing up BIOS
                        // attribute
                        const bool l_isUsedForBiosAttributeBackup =
                            l_aRecordKwInfo.value("isBiosSyncRequired", false);

                        const types::BinaryVector l_keywordValueToUpdate =
                            (i_syncBiosAttributesRequired &&
                             l_isUsedForBiosAttributeBackup)
                                ? getVpdValueInBiosConfigManager(
                                      l_srcRecordName, l_srcKeywordName)
                                : l_aRecordKwInfo["defaultValue"]
                                      .get<types::BinaryVector>();

                        if (l_keywordValueToUpdate.empty())
                        {
                            std::cerr << "Failed to update " << l_srcRecordName
                                      << ":" << l_srcKeywordName
                                      << " . Keyword value to update is empty"
                                      << std::endl;
                            continue;
                        }

                        // update the Keyword with default value, use D-Bus
                        // method UpdateKeyword exposed by vpd-manager.
                        // Note: writing to all paths (Primary EEPROM path,
                        // Secondary EEPROM path, D-Bus cache and Backup path)
                        // is the responsibility of vpd-manager's UpdateKeyword
                        // API
                        if (constants::FAILURE ==
                            utils::writeKeyword(
                                l_hardwarePath,
                                std::make_tuple(l_srcRecordName,
                                                l_srcKeywordName,
                                                l_keywordValueToUpdate)))
                        {
                            // TODO: Enable logging when verbose
                            // is enabled.
                            std::cerr << "Failed to update " << l_srcRecordName
                                      << ":" << l_srcKeywordName << std::endl;
                        }
                    }
                    else
                    {
                        std::cerr
                            << "Unrecognized Entry Record [" << l_srcRecordName
                            << "] Keyword [" << l_srcKeywordName
                            << "] in Backup Restore JSON backup map"
                            << std::endl;
                    }
                } // mfgClean required check
            } // keyword list loop
        }
        else // backupRestoreJson is not valid
        {
            std::cerr << "Backup Restore JSON is not valid" << std::endl;
        }

        // success/failure message
        std::cout << "The critical keywords from system backplane VPD has "
                     "been reset successfully."
                  << std::endl;

    } // try block end
    catch (const std::exception& l_ex)
    {
        // TODO: Enable logging when verbose is enabled.
        std::cerr
            << "Manufacturing reset on system vpd keywords is unsuccessful. Error : "
            << l_ex.what() << std::endl;
    }
    return constants::SUCCESS;
}

bool VpdTool::fetchKeywordInfo(nlohmann::json& io_parsedJsonObj) const noexcept
{
    bool l_returnValue = false;
    try
    {
        if (io_parsedJsonObj.empty() || !io_parsedJsonObj.contains("source") ||
            !io_parsedJsonObj.contains("destination") ||
            !io_parsedJsonObj.contains("backupMap"))
        {
            throw std::runtime_error("Invalid JSON");
        }

        std::string l_srcVpdPath;
        std::string l_dstVpdPath;

        bool l_isSourceOnHardware = false;
        if (l_srcVpdPath = io_parsedJsonObj["source"].value("hardwarePath", "");
            !l_srcVpdPath.empty())
        {
            l_isSourceOnHardware = true;
        }
        else if (l_srcVpdPath =
                     io_parsedJsonObj["source"].value("inventoryPath", "");
                 l_srcVpdPath.empty())
        {
            throw std::runtime_error("Source path is empty in JSON");
        }

        bool l_isDestinationOnHardware = false;
        if (l_dstVpdPath =
                io_parsedJsonObj["destination"].value("hardwarePath", "");
            !l_dstVpdPath.empty())
        {
            l_isDestinationOnHardware = true;
        }
        else if (l_dstVpdPath =
                     io_parsedJsonObj["destination"].value("inventoryPath", "");
                 l_dstVpdPath.empty())
        {
            throw std::runtime_error("Destination path is empty in JSON");
        }

        for (auto& l_aRecordKwInfo : io_parsedJsonObj["backupMap"])
        {
            const std::string& l_srcRecordName =
                l_aRecordKwInfo.value("sourceRecord", "");
            const std::string& l_srcKeywordName =
                l_aRecordKwInfo.value("sourceKeyword", "");
            const std::string& l_dstRecordName =
                l_aRecordKwInfo.value("destinationRecord", "");
            const std::string& l_dstKeywordName =
                l_aRecordKwInfo.value("destinationKeyword", "");

            if (l_srcRecordName.empty() || l_dstRecordName.empty() ||
                l_srcKeywordName.empty() || l_dstKeywordName.empty())
            {
                // TODO: Enable logging when verbose is enabled.
                std::cout << "Record or keyword not found in the JSON."
                          << std::endl;
                continue;
            }

            types::DbusVariantType l_srcKeywordVariant;
            if (l_isSourceOnHardware)
            {
                l_srcKeywordVariant = utils::readKeywordFromHardware(
                    l_srcVpdPath,
                    std::make_tuple(l_srcRecordName, l_srcKeywordName));
            }
            else
            {
                l_srcKeywordVariant = utils::readDbusProperty(
                    constants::inventoryManagerService, l_srcVpdPath,
                    constants::ipzVpdInfPrefix + l_srcRecordName,
                    l_srcKeywordName);
            }

            if (auto l_srcKeywordValue =
                    std::get_if<types::BinaryVector>(&l_srcKeywordVariant);
                l_srcKeywordValue && !l_srcKeywordValue->empty())
            {
                l_aRecordKwInfo["sourcekeywordValue"] = *l_srcKeywordValue;
            }
            else
            {
                // TODO: Enable logging when verbose is enabled.
                std::cout
                    << "Invalid data type or empty data received, for source record: "
                    << l_srcRecordName << ", keyword: " << l_srcKeywordName
                    << std::endl;
                continue;
            }

            types::DbusVariantType l_dstKeywordVariant;
            if (l_isDestinationOnHardware)
            {
                l_dstKeywordVariant = utils::readKeywordFromHardware(
                    l_dstVpdPath,
                    std::make_tuple(l_dstRecordName, l_dstKeywordName));
            }
            else
            {
                l_dstKeywordVariant = utils::readDbusProperty(
                    constants::inventoryManagerService, l_dstVpdPath,
                    constants::ipzVpdInfPrefix + l_dstRecordName,
                    l_dstKeywordName);
            }

            if (auto l_dstKeywordValue =
                    std::get_if<types::BinaryVector>(&l_dstKeywordVariant);
                l_dstKeywordValue && !l_dstKeywordValue->empty())
            {
                l_aRecordKwInfo["destinationkeywordValue"] = *l_dstKeywordValue;
            }
            else
            {
                // TODO: Enable logging when verbose is enabled.
                std::cout
                    << "Invalid data type or empty data received, for destination record: "
                    << l_dstRecordName << ", keyword: " << l_dstKeywordName
                    << std::endl;
                continue;
            }
        }

        l_returnValue = true;
    }
    catch (const std::exception& l_ex)
    {
        // TODO: Enable logging when verbose is enabled.
        std::cerr << l_ex.what() << std::endl;
    }

    return l_returnValue;
}

nlohmann::json VpdTool::getFruTypeProperty(
    const std::string& i_objectPath) const noexcept
{
    nlohmann::json l_resultInJson = nlohmann::json::object({});
    std::vector<std::string> l_pimInfList;

    auto l_serviceInfMap = utils::GetServiceInterfacesForObject(
        i_objectPath, std::vector<std::string>{constants::inventoryItemInf});
    if (l_serviceInfMap.contains(constants::inventoryManagerService))
    {
        l_pimInfList = l_serviceInfMap[constants::inventoryManagerService];

        // iterate through the list and find
        // "xyz.openbmc_project.Inventory.Item.*"
        for (const auto& l_interface : l_pimInfList)
        {
            if (l_interface.find(constants::inventoryItemInf) !=
                    std::string::npos &&
                l_interface.length() >
                    std::string(constants::inventoryItemInf).length())
            {
                l_resultInJson.emplace("type", l_interface);
            }
        }
    }
    return l_resultInJson;
}

bool VpdTool::isFruPresent(const std::string& i_objectPath) const noexcept
{
    bool l_returnValue{false};
    try
    {
        types::DbusVariantType l_keyWordValue;

        l_keyWordValue = utils::readDbusProperty(
            constants::inventoryManagerService, i_objectPath,
            constants::inventoryItemInf, "Present");

        if (const auto l_value = std::get_if<bool>(&l_keyWordValue))
        {
            l_returnValue = *l_value;
        }
    }
    catch (const std::runtime_error& l_ex)
    {
        // TODO: Enable logging when verbose is enabled.
        // std::cerr << "Failed to check \"Present\" property for FRU "
        //           << i_objectPath << " Error: " << l_ex.what() <<
        //           std::endl;
    }
    return l_returnValue;
}

void VpdTool::printFixSystemVpdOption(
    const types::UserOption& i_option) const noexcept
{
    switch (i_option)
    {
        case types::UserOption::Exit:
            std::cout << "Enter 0 => To exit successfully : ";
            break;
        case types::UserOption::UseBackupDataForAll:
            std::cout << "Enter 1 => If you choose the data on backup for all "
                         "mismatching record-keyword pairs"
                      << std::endl;
            break;
        case types::UserOption::UseSystemBackplaneDataForAll:
            std::cout << "Enter 2 => If you choose the data on primary for all "
                         "mismatching record-keyword pairs"
                      << std::endl;
            break;
        case types::UserOption::MoreOptions:
            std::cout << "Enter 3 => If you wish to explore more options"
                      << std::endl;
            break;
        case types::UserOption::UseBackupDataForCurrent:
            std::cout << "Enter 4 => If you choose the data on backup as the "
                         "right value"
                      << std::endl;
            break;
        case types::UserOption::UseSystemBackplaneDataForCurrent:
            std::cout << "Enter 5 => If you choose the data on primary as the "
                         "right value"
                      << std::endl;
            break;
        case types::UserOption::NewValueOnBoth:
            std::cout
                << "Enter 6 => If you wish to enter a new value to update "
                   "both on backup and primary"
                << std::endl;
            break;
        case types::UserOption::SkipCurrent:
            std::cout << "Enter 7 => If you wish to skip the above "
                         "record-keyword pair"
                      << std::endl;
            break;
    }
}

int VpdTool::dumpInventory(bool i_dumpTable) const noexcept
{
    int l_rc{constants::FAILURE};

    try
    {
        // get all object paths under PIM
        const auto l_objectPaths = utils::GetSubTreePaths(
            constants::baseInventoryPath, 0,
            std::vector<std::string>{constants::inventoryItemInf});

        if (!l_objectPaths.empty())
        {
            nlohmann::json l_resultInJson = nlohmann::json::array({});

            std::for_each(l_objectPaths.begin(), l_objectPaths.end(),
                          [&](const auto& l_objectPath) {
                              const auto l_fruJson =
                                  getFruProperties(l_objectPath);
                              if (!l_fruJson.empty())
                              {
                                  if (l_resultInJson.empty())
                                  {
                                      l_resultInJson += l_fruJson;
                                  }
                                  else
                                  {
                                      l_resultInJson.at(0).insert(
                                          l_fruJson.cbegin(), l_fruJson.cend());
                                  }
                              }
                          });

            if (i_dumpTable)
            {
                // create Table object
                utils::Table l_inventoryTable{};

                // columns to be populated in the Inventory table
                const std::vector<types::TableColumnNameSizePair>
                    l_tableColumns = {
                        {"FRU", 100},         {"CC", 6},  {"DR", 20},
                        {"LocationCode", 32}, {"PN", 8},  {"PrettyName", 80},
                        {"SubModel", 10},     {"SN", 15}, {"type", 60}};

                types::TableInputData l_tableData;

                // First prepare the Table Columns
                for (const auto& l_column : l_tableColumns)
                {
                    if (constants::FAILURE ==
                        l_inventoryTable.AddColumn(l_column.first,
                                                   l_column.second))
                    {
                        // TODO: Enable logging when verbose is enabled.
                        std::cerr << "Failed to add column " << l_column.first
                                  << " in Inventory Table." << std::endl;
                    }
                }

                // iterate through the json array
                for (const auto& l_fruEntry : l_resultInJson[0].items())
                {
                    // if object path ends in "unit([0-9][0-9]?)", skip adding
                    // the object path in the table
                    if (std::regex_search(l_fruEntry.key(),
                                          std::regex("unit([0-9][0-9]?)")))
                    {
                        continue;
                    }

                    std::vector<std::string> l_row;
                    for (const auto& l_column : l_tableColumns)
                    {
                        const auto& l_fruJson = l_fruEntry.value();

                        if (l_column.first == "FRU")
                        {
                            l_row.push_back(l_fruEntry.key());
                        }
                        else
                        {
                            if (l_fruJson.contains(l_column.first))
                            {
                                l_row.push_back(l_fruJson[l_column.first]);
                            }
                            else
                            {
                                l_row.push_back("");
                            }
                        }
                    }

                    l_tableData.push_back(l_row);
                }

                l_rc = l_inventoryTable.Print(l_tableData);
            }
            else
            {
                // print JSON to console
                utils::printJson(l_resultInJson);
                l_rc = constants::SUCCESS;
            }
        }
    }
    catch (const std::exception& l_ex)
    {
        // TODO: Enable logging when verbose is enabled.
        std::cerr << "Dump inventory failed. Error: " << l_ex.what()
                  << std::endl;
    }
    return l_rc;
}

void VpdTool::printSystemVpd(
    const nlohmann::json& i_parsedJsonObj) const noexcept
{
    if (i_parsedJsonObj.empty() || !i_parsedJsonObj.contains("backupMap"))
    {
        // TODO: Enable logging when verbose is enabled.
        std::cerr << "Invalid JSON to print system VPD" << std::endl;
    }

    std::string l_outline(191, '=');
    std::cout << "\nRestorable record-keyword pairs and their data on backup & "
                 "primary.\n\n"
              << l_outline << std::endl;

    std::cout << std::left << std::setw(6) << "S.No" << std::left
              << std::setw(8) << "Record" << std::left << std::setw(9)
              << "Keyword" << std::left << std::setw(75) << "Data On Backup"
              << std::left << std::setw(75) << "Data On Primary" << std::left
              << std::setw(14) << "Data Mismatch\n"
              << l_outline << std::endl;

    uint8_t l_slNum = 0;

    for (const auto& l_aRecordKwInfo : i_parsedJsonObj["backupMap"])
    {
        if (l_aRecordKwInfo.contains("sourceRecord") ||
            l_aRecordKwInfo.contains("sourceKeyword") ||
            l_aRecordKwInfo.contains("destinationkeywordValue") ||
            l_aRecordKwInfo.contains("sourcekeywordValue"))
        {
            std::string l_mismatchFound{
                (l_aRecordKwInfo["destinationkeywordValue"] !=
                 l_aRecordKwInfo["sourcekeywordValue"])
                    ? "YES"
                    : "NO"};

            std::string l_splitLine(191, '-');

            try
            {
                std::cout << std::left << std::setw(6)
                          << static_cast<int>(++l_slNum) << std::left
                          << std::setw(8)
                          << l_aRecordKwInfo.value("sourceRecord", "")
                          << std::left << std::setw(9)
                          << l_aRecordKwInfo.value("sourceKeyword", "")
                          << std::left << std::setw(75) << std::setfill(' ')
                          << utils::getPrintableValue(
                                 l_aRecordKwInfo["destinationkeywordValue"])
                          << std::left << std::setw(75) << std::setfill(' ')
                          << utils::getPrintableValue(
                                 l_aRecordKwInfo["sourcekeywordValue"])
                          << std::left << std::setw(14) << l_mismatchFound
                          << '\n'
                          << l_splitLine << std::endl;
            }
            catch (const std::exception& l_ex)
            {
                // TODO: Enable logging when verbose is enabled.
                std::cerr << l_ex.what() << std::endl;
            }
        }
    }
}

int VpdTool::updateAllKeywords(const nlohmann::json& i_parsedJsonObj,
                               bool i_useBackupData) const noexcept
{
    int l_rc = constants::FAILURE;

    if (i_parsedJsonObj.empty() || !i_parsedJsonObj.contains("source") ||
        !i_parsedJsonObj.contains("backupMap"))
    {
        // TODO: Enable logging when verbose is enabled.
        std::cerr << "Invalid JSON" << std::endl;
        return l_rc;
    }

    std::string l_srcVpdPath;
    if (auto l_vpdPath = i_parsedJsonObj["source"].value("hardwarePath", "");
        !l_vpdPath.empty())
    {
        l_srcVpdPath = l_vpdPath;
    }
    else if (auto l_vpdPath =
                 i_parsedJsonObj["source"].value("inventoryPath", "");
             !l_vpdPath.empty())
    {
        l_srcVpdPath = l_vpdPath;
    }
    else
    {
        // TODO: Enable logging when verbose is enabled.
        std::cerr << "source path information is missing in JSON" << std::endl;
        return l_rc;
    }

    bool l_anyMismatchFound = false;
    for (const auto& l_aRecordKwInfo : i_parsedJsonObj["backupMap"])
    {
        if (!l_aRecordKwInfo.contains("sourceRecord") ||
            !l_aRecordKwInfo.contains("sourceKeyword") ||
            !l_aRecordKwInfo.contains("destinationkeywordValue") ||
            !l_aRecordKwInfo.contains("sourcekeywordValue"))
        {
            // TODO: Enable logging when verbose is enabled.
            std::cerr << "Missing required information in the JSON"
                      << std::endl;
            continue;
        }

        if (l_aRecordKwInfo["sourcekeywordValue"] !=
            l_aRecordKwInfo["destinationkeywordValue"])
        {
            l_anyMismatchFound = true;

            auto l_keywordValue =
                i_useBackupData ? l_aRecordKwInfo["destinationkeywordValue"]
                                : l_aRecordKwInfo["sourcekeywordValue"];

            auto l_paramsToWrite = std::make_tuple(
                l_aRecordKwInfo["sourceRecord"],
                l_aRecordKwInfo["sourceKeyword"], l_keywordValue);

            try
            {
                l_rc = utils::writeKeyword(l_srcVpdPath, l_paramsToWrite);
                if (l_rc > 0)
                {
                    l_rc = constants::SUCCESS;
                }
            }
            catch (const std::exception& l_ex)
            {
                // TODO: Enable logging when verbose is enabled.
                std::cerr << "write keyword failed for record: "
                          << l_aRecordKwInfo["sourceRecord"]
                          << ", keyword: " << l_aRecordKwInfo["sourceKeyword"]
                          << ", error: " << l_ex.what() << std::ends;
            }
        }
    }

    std::string l_dataUsed =
        (i_useBackupData ? "data from backup" : "data from primary VPD");
    if (l_anyMismatchFound)
    {
        std::cout << "Data updated successfully for all mismatching "
                     "record-keyword pairs by choosing their corresponding "
                  << l_dataUsed << ". Exit successfully." << std::endl;
    }
    else
    {
        std::cout << "No mismatch found for any of the above mentioned "
                     "record-keyword pair. Exit successfully."
                  << std::endl;
    }

    return l_rc;
}

int VpdTool::handleMoreOption(
    const nlohmann::json& i_parsedJsonObj) const noexcept
{
    int l_rc = constants::FAILURE;

    try
    {
        if (i_parsedJsonObj.empty() || !i_parsedJsonObj.contains("backupMap"))
        {
            throw std::runtime_error("Invalid JSON");
        }

        std::string l_srcVpdPath;

        if (auto l_vpdPath =
                i_parsedJsonObj["source"].value("hardwarePath", "");
            !l_vpdPath.empty())
        {
            l_srcVpdPath = l_vpdPath;
        }
        else if (auto l_vpdPath =
                     i_parsedJsonObj["source"].value("inventoryPath", "");
                 !l_vpdPath.empty())
        {
            l_srcVpdPath = l_vpdPath;
        }
        else
        {
            throw std::runtime_error(
                "source path information is missing in JSON");
        }

        auto updateKeywordValue =
            [](std::string io_vpdPath, const std::string& i_recordName,
               const std::string& i_keywordName,
               const types::BinaryVector& i_keywordValue) -> int {
            int l_rc = constants::FAILURE;

            try
            {
                auto l_paramsToWrite = std::make_tuple(
                    i_recordName, i_keywordName, i_keywordValue);
                l_rc = utils::writeKeyword(io_vpdPath, l_paramsToWrite);

                if (l_rc > 0)
                {
                    std::cout << std::endl
                              << "Data updated successfully." << std::endl;
                }
            }
            catch (const std::exception& l_ex)
            {
                // TODO: Enable log when verbose is enabled.
                std::cerr << l_ex.what() << std::endl;
            }
            return l_rc;
        };

        do
        {
            int l_slNum = 0;
            bool l_exit = false;

            for (const auto& l_aRecordKwInfo : i_parsedJsonObj["backupMap"])
            {
                if (!l_aRecordKwInfo.contains("sourceRecord") ||
                    !l_aRecordKwInfo.contains("sourceKeyword") ||
                    !l_aRecordKwInfo.contains("destinationkeywordValue") ||
                    !l_aRecordKwInfo.contains("sourcekeywordValue"))
                {
                    // TODO: Enable logging when verbose is enabled.
                    std::cerr
                        << "Source or destination information is missing in the JSON."
                        << std::endl;
                    continue;
                }

                const std::string l_mismatchFound{
                    (l_aRecordKwInfo["sourcekeywordValue"] !=
                     l_aRecordKwInfo["destinationkeywordValue"])
                        ? "YES"
                        : "NO"};

                std::cout << std::endl
                          << std::left << std::setw(6) << "S.No" << std::left
                          << std::setw(8) << "Record" << std::left
                          << std::setw(9) << "Keyword" << std::left
                          << std::setw(75) << std::setfill(' ') << "Backup Data"
                          << std::left << std::setw(75) << std::setfill(' ')
                          << "Primary Data" << std::left << std::setw(14)
                          << "Data Mismatch" << std::endl;

                std::cout << std::left << std::setw(6)
                          << static_cast<int>(++l_slNum) << std::left
                          << std::setw(8)
                          << l_aRecordKwInfo.value("sourceRecord", "")
                          << std::left << std::setw(9)
                          << l_aRecordKwInfo.value("sourceKeyword", "")
                          << std::left << std::setw(75) << std::setfill(' ')
                          << utils::getPrintableValue(
                                 l_aRecordKwInfo["destinationkeywordValue"])
                          << std::left << std::setw(75) << std::setfill(' ')
                          << utils::getPrintableValue(
                                 l_aRecordKwInfo["sourcekeywordValue"])
                          << std::left << std::setw(14) << l_mismatchFound
                          << std::endl;

                std::cout << std::string(191, '=') << std::endl;

                if (constants::STR_CMP_SUCCESS ==
                    l_mismatchFound.compare("YES"))
                {
                    printFixSystemVpdOption(
                        types::UserOption::UseBackupDataForCurrent);
                    printFixSystemVpdOption(
                        types::UserOption::UseSystemBackplaneDataForCurrent);
                    printFixSystemVpdOption(types::UserOption::NewValueOnBoth);
                    printFixSystemVpdOption(types::UserOption::SkipCurrent);
                    printFixSystemVpdOption(types::UserOption::Exit);
                }
                else
                {
                    std::cout << "No mismatch found." << std::endl << std::endl;
                    printFixSystemVpdOption(types::UserOption::NewValueOnBoth);
                    printFixSystemVpdOption(types::UserOption::SkipCurrent);
                    printFixSystemVpdOption(types::UserOption::Exit);
                }

                int l_userSelectedOption = types::UserOption::Exit;
                std::cin >> l_userSelectedOption;

                if (types::UserOption::UseBackupDataForCurrent ==
                    l_userSelectedOption)
                {
                    l_rc = updateKeywordValue(
                        l_srcVpdPath, l_aRecordKwInfo["sourceRecord"],
                        l_aRecordKwInfo["sourceKeyword"],
                        l_aRecordKwInfo["destinationkeywordValue"]);
                }
                else if (types::UserOption::UseSystemBackplaneDataForCurrent ==
                         l_userSelectedOption)
                {
                    l_rc = updateKeywordValue(
                        l_srcVpdPath, l_aRecordKwInfo["sourceRecord"],
                        l_aRecordKwInfo["sourceKeyword"],
                        l_aRecordKwInfo["sourcekeywordValue"]);
                }
                else if (types::UserOption::NewValueOnBoth ==
                         l_userSelectedOption)
                {
                    std::string l_newValue;
                    std::cout
                        << std::endl
                        << "Enter the new value to update on both "
                           "primary & backup. Value should be in ASCII or "
                           "in HEX(prefixed with 0x) : ";
                    std::cin >> l_newValue;
                    std::cout << std::endl
                              << std::string(191, '=') << std::endl;

                    try
                    {
                        l_rc = updateKeywordValue(
                            l_srcVpdPath, l_aRecordKwInfo["sourceRecord"],
                            l_aRecordKwInfo["sourceKeyword"],
                            utils::convertToBinary(l_newValue));
                    }
                    catch (const std::exception& l_ex)
                    {
                        // TODO: Enable logging when verbose is enabled.
                        std::cerr << l_ex.what() << std::endl;
                    }
                }
                else if (types::UserOption::SkipCurrent == l_userSelectedOption)
                {
                    std::cout << std::endl
                              << "Skipped the above record-keyword pair. "
                                 "Continue to the next available pair."
                              << std::endl;
                }
                else if (types::UserOption::Exit == l_userSelectedOption)
                {
                    std::cout << "Exit successfully" << std::endl;
                    l_exit = true;
                    break;
                }
                else
                {
                    std::cout << "Provide a valid option. Retrying for the "
                                 "current record-keyword pair"
                              << std::endl;
                }
            }
            if (l_exit)
            {
                l_rc = constants::SUCCESS;
                break;
            }
        } while (true);
    }
    catch (const std::exception& l_ex)
    {
        // TODO: Enable logging when verbose is enabled.
        std::cerr << l_ex.what() << std::endl;
    }

    return l_rc;
}

int VpdTool::resetVpdOnDbus()
{
    // ToDo: Limit this function to lab mode only.

    int l_rc = constants::FAILURE;
    try
    {
        std::string l_vpdManagerStopCmd(
            "systemctl stop " + std::string(constants::vpdManagerProcessName));

        std::cout << std::flush;
        if (auto l_rc = std::system(l_vpdManagerStopCmd.c_str()); l_rc != 0)
        {
            std::cerr << "Failed to stop " << constants::vpdManagerProcessName
                      << " service. Return code [" << l_rc << "]. Exiting."
                      << std::endl;
            return l_rc;
        }

        std::string l_vpdServiceIsActiveCmd(
            "systemctl is-active --quiet " +
            std::string(constants::vpdManagerProcessName));

        std::cout << std::flush;
        if (auto l_rc = std::system(l_vpdServiceIsActiveCmd.c_str()); l_rc == 0)
        {
            std::cerr
                << constants::vpdManagerProcessName
                << " service is still active, can't proceed further. Return code ["
                << l_rc << "]. Exiting." << std::endl;
            return l_rc;
        }

        std::error_code l_ec;
        if (static_cast<std::uintmax_t>(-1) ==
            std::filesystem::remove_all(constants::pimPersistPath, l_ec))
        {
            std::cerr
                << "Error occured while removing the persisted VPD under path ["
                << constants::pimPersistPath << "]." << std::endl;

            if (l_ec)
            {
                std::cerr << "Reason: " << l_ec.message() << std::endl;
            }

            std::cerr << "Reboot BMC to recover the system." << std::endl;
            return l_rc;
        }

        std::string l_pimServiceRestartCmd(
            "systemctl restart " +
            std::string(constants::inventoryManagerService));

        std::cout << std::flush;
        if (auto l_rc = std::system(l_pimServiceRestartCmd.c_str()); l_rc != 0)
        {
            std::cerr << "Failed to restart "
                      << constants::inventoryManagerService
                      << " service. Return code [" << l_rc << "]. Exiting."
                      << std::endl
                      << "Reboot BMC to recover the system." << std::endl;
            return l_rc;
        }

        std::string l_pimServiceIsActiveCmd(
            "systemctl is-active --quiet " +
            std::string(constants::inventoryManagerService));

        std::cout << std::flush;
        if (auto l_rc = std::system(l_pimServiceIsActiveCmd.c_str()); l_rc != 0)
        {
            std::cerr << constants::inventoryManagerService
                      << " service is not active. Return code [" << l_rc
                      << "]. Exiting." << std::endl
                      << "Reboot BMC to recover the system." << std::endl;
            return l_rc;
        }

        std::string l_vpdManagerStartCmd(
            "systemctl start " + std::string(constants::vpdManagerProcessName));

        std::cout << std::flush;
        if (auto l_rc = std::system(l_vpdManagerStartCmd.c_str()); l_rc != 0)
        {
            std::cerr << "Failed to start " << constants::vpdManagerProcessName
                      << " service. Return code [" << l_rc << "]. Exiting."
                      << std::endl
                      << "Reboot BMC to recover the system." << std::endl;
            return l_rc;
        }

        std::cout << std::flush;
        if (auto l_rc = std::system(l_vpdServiceIsActiveCmd.c_str()); l_rc != 0)
        {
            std::cerr << constants::vpdManagerProcessName
                      << " service is not active. Return code [" << l_rc
                      << "]. Exiting." << std::endl
                      << "Reboot BMC to recover the system." << std::endl;
            return l_rc;
        }

        l_rc = constants::SUCCESS;
    }
    catch (const std::exception& l_ex)
    {
        // TODO: Enable logging when verbose is enabled.
        std::cerr << l_ex.what() << std::endl;
    }

    return l_rc;
}

types::BinaryVector VpdTool::getVpdValueInBiosConfigManager(
    [[maybe_unused]] const std::string& i_recordName,
    [[maybe_unused]] const std::string& i_keywordName) const
{
    types::BinaryVector l_result;
    // TODO: Use Record name, Keyword name to identify BIOS attribute.
    //  Get BIOS attribute value from BIOS Config Manager.
    //  Convert BIOS attribute value to VPD format value in binary.
    return l_result;
}
} // namespace vpd
