#include "vpd_tool_impl.hpp"

#include "impl.hpp"
#include "parser_factory.hpp"
#include "vpd_exceptions.hpp"

#include <sdbusplus/bus.hpp>

#include <cstdlib>
#include <filesystem>
#include <iostream>
#include <variant>
#include <vector>

using namespace std;
using namespace openpower::vpd;
using namespace inventory;
using namespace openpower::vpd::manager::editor;
namespace fs = std::filesystem;
using json = nlohmann::json;
using namespace openpower::vpd::exceptions;
using namespace openpower::vpd::parser;
using namespace openpower::vpd::parser::factory;
using namespace openpower::vpd::parser::interface;

bool VpdTool::fileToVector(Binary& data)
{
    try
    {
        std::ifstream file(value, std::ifstream::in);

        if (file)
        {
            std::string line;
            while (std::getline(file, line))
            {
                std::istringstream iss(line);
                std::string byteStr;
                while (iss >> std::setw(2) >> std::hex >> byteStr)
                {
                    uint8_t byte = strtoul(byteStr.c_str(), nullptr, 16);
                    data.emplace(data.end(), byte);
                }
            }
            return true;
        }
        else
        {
            std::cerr << "Unable to open the given file " << value << std::endl;
        }
    }
    catch (std::exception& e)
    {
        std::cerr << e.what();
    }
    return false;
}

bool VpdTool::copyStringToFile(const std::string& input)
{
    try
    {
        std::ofstream outFile(value, std::ofstream::out);

        if (outFile.is_open())
        {
            std::string hexString = input;
            if (input.substr(0, 2) == "0x")
            {
                // truncating prefix 0x
                hexString = input.substr(2);
            }
            outFile.write(hexString.c_str(), hexString.length());
        }
        else
        {
            std::cerr << "Error opening output file " << value << std::endl;
            return false;
        }

        outFile.close();
    }
    catch (std::exception& e)
    {
        std::cerr << e.what();
        return false;
    }
    return true;
}

static void
    getVPDInMap(const std::string& vpdPath,
                std::unordered_map<std::string, DbusPropertyMap>& vpdMap,
                json& js, const std::string& invPath)
{
    auto jsonToParse = INVENTORY_JSON_DEFAULT;
    if (fs::exists(INVENTORY_JSON_SYM_LINK))
    {
        jsonToParse = INVENTORY_JSON_SYM_LINK;
    }

    std::ifstream inventoryJson(jsonToParse);
    if (!inventoryJson)
    {
        throw std::runtime_error("VPD JSON file not found");
    }

    try
    {
        js = json::parse(inventoryJson);
    }
    catch (const json::parse_error& ex)
    {
        throw std::runtime_error("VPD JSON parsing failed");
    }

    Binary vpdVector{};

    uint32_t vpdStartOffset = 0;
    vpdVector = getVpdDataInVector(js, constants::systemVpdFilePath);
    ParserInterface* parser = ParserFactory::getParser(
        vpdVector, invPath, constants::systemVpdFilePath, vpdStartOffset);
    auto parseResult = parser->parse();
    ParserFactory::freeParser(parser);

    if (auto pVal = std::get_if<Store>(&parseResult))
    {
        vpdMap = pVal->getVpdMap();
    }
    else
    {
        std::string err = vpdPath +
                          " is not of type IPZ VPD. Unable to parse the VPD.";
        throw std::runtime_error(err);
    }
}

Binary VpdTool::toBinary(const std::string& value)
{
    Binary val{};
    if (value.find("0x") == string::npos)
    {
        val.assign(value.begin(), value.end());
    }
    else if (value.find("0x") != string::npos)
    {
        stringstream ss;
        ss.str(value.substr(2));
        string byteStr{};

        if (value.length() % 2 != 0)
        {
            throw runtime_error(
                "VPD-TOOL write option accepts 2 digit hex numbers. (Eg. 0x1 "
                "should be given as 0x01). Aborting the write operation.");
        }

        if (value.find_first_not_of("0123456789abcdefABCDEF", 2) !=
            std::string::npos)
        {
            throw runtime_error("Provide a valid hexadecimal input.");
        }

        while (ss >> setw(2) >> byteStr)
        {
            uint8_t byte = strtoul(byteStr.c_str(), nullptr, 16);

            val.push_back(byte);
        }
    }

    else
    {
        throw runtime_error("The value to be updated should be either in ascii "
                            "or in hex. Refer --help option");
    }
    return val;
}

void VpdTool::printReturnCode(int returnCode)
{
    if (returnCode)
    {
        cout << "\n Command failed with the return code " << returnCode
             << ". Continuing the execution. " << endl;
    }
}

void VpdTool::eraseInventoryPath(string& fru)
{
    // Power supply frupath comes with INVENTORY_PATH appended in prefix.
    // Stripping it off inorder to avoid INVENTORY_PATH duplication
    // during getVINIProperties() execution.
    fru.erase(0, sizeof(INVENTORY_PATH) - 1);
}

void VpdTool::debugger(json output)
{
    cout << output.dump(4) << '\n';
}

auto VpdTool::makeDBusCall(const string& objectName, const string& interface,
                           const string& kw)
{
    auto bus = sdbusplus::bus::new_default();
    auto properties =
        bus.new_method_call(INVENTORY_MANAGER_SERVICE, objectName.c_str(),
                            "org.freedesktop.DBus.Properties", "Get");
    properties.append(interface);
    properties.append(kw);
    auto result = bus.call(properties);

    if (result.is_method_error())
    {
        throw runtime_error("Get api failed");
    }
    return result;
}

json VpdTool::getVINIProperties(string invPath)
{
    variant<Binary> response;
    json kwVal = json::object({});

    vector<string> keyword{"CC", "SN", "PN", "FN", "DR"};
    string interface = "com.ibm.ipzvpd.VINI";
    string objectName = {};

    if (invPath.find(INVENTORY_PATH) != string::npos)
    {
        objectName = invPath;
        eraseInventoryPath(invPath);
    }
    else
    {
        objectName = INVENTORY_PATH + invPath;
    }
    for (string kw : keyword)
    {
        try
        {
            makeDBusCall(objectName, interface, kw).read(response);

            if (auto vec = get_if<Binary>(&response))
            {
                string printableVal = getPrintableValue(*vec);
                kwVal.emplace(kw, printableVal);
            }
        }
        catch (const sdbusplus::exception_t& e)
        {
            if (string(e.name()) ==
                string("org.freedesktop.DBus.Error.UnknownObject"))
            {
                kwVal.emplace(invPath, json::object({}));
                objFound = false;
                break;
            }
        }
    }

    return kwVal;
}

void VpdTool::getExtraInterfaceProperties(const string& invPath,
                                          const string& extraInterface,
                                          const json& prop, json& output)
{
    variant<string> response;

    string objectName = INVENTORY_PATH + invPath;

    for (const auto& itProp : prop.items())
    {
        string kw = itProp.key();
        try
        {
            makeDBusCall(objectName, extraInterface, kw).read(response);

            if (auto str = get_if<string>(&response))
            {
                output.emplace(kw, *str);
            }
        }
        catch (const sdbusplus::exception_t& e)
        {
            if (std::string(e.name()) ==
                std::string("org.freedesktop.DBus.Error.UnknownObject"))
            {
                objFound = false;
                break;
            }
            else if (std::string(e.name()) ==
                     std::string("org.freedesktop.DBus.Error.UnknownProperty"))
            {
                output.emplace(kw, "");
            }
        }
    }
}

json VpdTool::interfaceDecider(json& itemEEPROM)
{
    if (itemEEPROM.find("inventoryPath") == itemEEPROM.end())
    {
        throw runtime_error("Inventory Path not found");
    }

    if (itemEEPROM.find("extraInterfaces") == itemEEPROM.end())
    {
        throw runtime_error("Extra Interfaces not found");
    }

    json subOutput = json::object({});
    fruType = "FRU";

    json j;
    objFound = true;
    string invPath = itemEEPROM.at("inventoryPath");

    j = getVINIProperties(invPath);

    if (objFound)
    {
        subOutput.insert(j.begin(), j.end());
        json js;
        if (itemEEPROM.find("type") != itemEEPROM.end())
        {
            fruType = itemEEPROM.at("type");
        }
        js.emplace("TYPE", fruType);

        if (invPath.find("powersupply") != string::npos)
        {
            js.emplace("type", POWER_SUPPLY_TYPE_INTERFACE);
        }
        else if (invPath.find("fan") != string::npos)
        {
            js.emplace("type", FAN_INTERFACE);
        }

        for (const auto& ex : itemEEPROM["extraInterfaces"].items())
        {
            if (!(ex.value().is_null()))
            {
                // TODO: Remove this if condition check once inventory json is
                // updated with xyz location code interface.
                if (ex.key() == "com.ibm.ipzvpd.Location")
                {
                    getExtraInterfaceProperties(
                        invPath,
                        "xyz.openbmc_project.Inventory.Decorator.LocationCode",
                        ex.value(), js);
                }
                else
                {
                    getExtraInterfaceProperties(invPath, ex.key(), ex.value(),
                                                js);
                }
            }
            if ((ex.key().find("Item") != string::npos) &&
                (ex.value().is_null()))
            {
                js.emplace("type", ex.key());
            }
            subOutput.insert(js.begin(), js.end());
        }
    }
    return subOutput;
}

json VpdTool::getPresentPropJson(const std::string& invPath)
{
    std::variant<bool> response;
    std::string presence = "Unknown";

    try
    {
        makeDBusCall(invPath, "xyz.openbmc_project.Inventory.Item", "Present")
            .read(response);

        if (auto pVal = get_if<bool>(&response))
        {
            presence = *pVal ? "true" : "false";
        }
    }
    catch (const sdbusplus::exception::SdBusError& e)
    {
        presence = "Unknown";
    }

    json js;
    js.emplace("Present", presence);
    return js;
}

json VpdTool::parseInvJson(const json& jsObject, char flag, string fruPath)
{
    json output = json::object({});
    bool validObject = false;

    if (jsObject.find("frus") == jsObject.end())
    {
        throw runtime_error("Frus missing in Inventory json");
    }
    else
    {
        for (const auto& itemFRUS : jsObject["frus"].items())
        {
            for (auto itemEEPROM : itemFRUS.value())
            {
                json subOutput = json::object({});
                try
                {
                    if (flag == 'O')
                    {
                        if (itemEEPROM.find("inventoryPath") ==
                            itemEEPROM.end())
                        {
                            throw runtime_error("Inventory Path not found");
                        }
                        else if (itemEEPROM.at("inventoryPath") == fruPath)
                        {
                            validObject = true;
                            subOutput = interfaceDecider(itemEEPROM);
                            json presentJs = getPresentPropJson(
                                "/xyz/openbmc_project/inventory" + fruPath);
                            subOutput.insert(presentJs.begin(),
                                             presentJs.end());
                            output.emplace(fruPath, subOutput);
                            return output;
                        }
                    }
                    else
                    {
                        subOutput = interfaceDecider(itemEEPROM);
                        json presentJs = getPresentPropJson(
                            "/xyz/openbmc_project/inventory" +
                            string(itemEEPROM.at("inventoryPath")));
                        subOutput.insert(presentJs.begin(), presentJs.end());
                        output.emplace(string(itemEEPROM.at("inventoryPath")),
                                       subOutput);
                    }
                }
                catch (const exception& e)
                {
                    cerr << e.what();
                }
            }
        }
        if ((flag == 'O') && (!validObject))
        {
            throw runtime_error(
                "Invalid object path. Refer --dumpInventory/-i option.");
        }
    }
    return output;
}

void VpdTool::dumpInventory(const nlohmann::basic_json<>& jsObject)
{
    char flag = 'I';
    json output = json::array({});
    output.emplace_back(parseInvJson(jsObject, flag, ""));
    debugger(output);
}

void VpdTool::dumpObject(const nlohmann::basic_json<>& jsObject)
{
    char flag = 'O';
    json output = json::array({});
    output.emplace_back(parseInvJson(jsObject, flag, fruPath));
    debugger(output);
}

void VpdTool::readKeyword()
{
    const std::string& kw = getDbusNameForThisKw(keyword);

    string interface = "com.ibm.ipzvpd.";
    variant<Binary> response;

    try
    {
        makeDBusCall(INVENTORY_PATH + fruPath, interface + recordName, kw)
            .read(response);

        string printableVal{};
        if (auto vec = get_if<Binary>(&response))
        {
            printableVal = getPrintableValue(*vec);
        }

        if (!value.empty())
        {
            if (copyStringToFile(printableVal))
            {
                std::cout << "Value read is saved in the file " << value
                          << std::endl;
                return;
            }
            else
            {
                std::cerr << "Error while saving the read value in file. "
                             "Displaying the read value on console"
                          << std::endl;
            }
        }

        json output = json::object({});
        json kwVal = json::object({});
        kwVal.emplace(keyword, printableVal);

        output.emplace(fruPath, kwVal);

        debugger(output);
    }
    catch (const json::exception& e)
    {
        std::cout << "Keyword Value: " << keyword << std::endl;
        std::cout << e.what() << std::endl;
    }
}

int VpdTool::updateKeyword()
{
    Binary val;

    if (std::filesystem::exists(value))
    {
        if (!fileToVector(val))
        {
            std::cout << "Keyword " << keyword << " update failed."
                      << std::endl;
            return 1;
        }
    }
    else
    {
        val = toBinary(value);
    }

    auto bus = sdbusplus::bus::new_default();
    auto properties = bus.new_method_call(BUSNAME, OBJPATH, IFACE,
                                          "WriteKeyword");
    properties.append(static_cast<sdbusplus::message::object_path>(fruPath));
    properties.append(recordName);
    properties.append(keyword);
    properties.append(val);

    // When there is a request to write 10K bytes, there occurs a delay in dbus
    // call which leads to dbus timeout exception. To avoid such exceptions
    // increase the timeout period from default 25 seconds to 60 seconds.
    auto timeoutInMicroSeconds = 60 * 1000000L;
    auto result = bus.call(properties, timeoutInMicroSeconds);

    if (result.is_method_error())
    {
        throw runtime_error("Get api failed");
    }
    std::cout << "Data updated successfully " << std::endl;
    return 0;
}

void VpdTool::forceReset(const nlohmann::basic_json<>& jsObject)
{
    for (const auto& itemFRUS : jsObject["frus"].items())
    {
        for (const auto& itemEEPROM : itemFRUS.value().items())
        {
            string fru = itemEEPROM.value().at("inventoryPath");

            fs::path fruCachePath = INVENTORY_MANAGER_CACHE;
            fruCachePath += INVENTORY_PATH;
            fruCachePath += fru;

            try
            {
                for (const auto& it : fs::directory_iterator(fruCachePath))
                {
                    if (fs::is_regular_file(it.status()))
                    {
                        fs::remove(it);
                    }
                }
            }
            catch (const fs::filesystem_error& e)
            {}
        }
    }

    cout.flush();
    string udevRemove = "udevadm trigger -c remove -s \"*nvmem*\" -v";
    int returnCode = system(udevRemove.c_str());
    printReturnCode(returnCode);

    string invManagerRestart =
        "systemctl restart xyz.openbmc_project.Inventory.Manager.service";
    returnCode = system(invManagerRestart.c_str());
    printReturnCode(returnCode);

    string sysVpdRestart = "systemctl restart system-vpd.service";
    returnCode = system(sysVpdRestart.c_str());
    printReturnCode(returnCode);

    string udevAdd = "udevadm trigger -c add -s \"*nvmem*\" -v";
    returnCode = system(udevAdd.c_str());
    printReturnCode(returnCode);
}

int VpdTool::updateHardware(const uint32_t offset)
{
    int rc = 0;
    Binary val;
    if (std::filesystem::exists(value))
    {
        if (!fileToVector(val))
        {
            std::cout << "Keyword " << keyword << " update failed."
                      << std::endl;
            return 1;
        }
    }
    else
    {
        val = toBinary(value);
    }

    ifstream inventoryJson(INVENTORY_JSON_SYM_LINK);
    try
    {
        auto json = nlohmann::json::parse(inventoryJson);
        EditorImpl edit(fruPath, json, recordName, keyword);

        edit.updateKeyword(val, offset, false);
    }
    catch (const json::parse_error& ex)
    {
        throw(VpdJsonException("Json Parsing failed", INVENTORY_JSON_SYM_LINK));
    }
    std::cout << "Data updated successfully " << std::endl;
    return rc;
}

void VpdTool::readKwFromHw(const uint32_t& startOffset)
{
    ifstream inventoryJson(INVENTORY_JSON_SYM_LINK);
    auto jsonFile = nlohmann::json::parse(inventoryJson);

    Binary completeVPDFile;
    completeVPDFile.resize(65504);
    fstream vpdFileStream;
    vpdFileStream.open(fruPath,
                       std::ios::in | std::ios::out | std::ios::binary);

    vpdFileStream.seekg(startOffset, ios_base::cur);
    vpdFileStream.read(reinterpret_cast<char*>(&completeVPDFile[0]), 65504);
    completeVPDFile.resize(vpdFileStream.gcount());
    vpdFileStream.clear(std::ios_base::eofbit);

    if (completeVPDFile.empty())
    {
        throw std::runtime_error("Invalid File");
    }

    const std::string& inventoryPath =
        jsonFile["frus"][fruPath][0]["inventoryPath"];

    uint32_t vpdStartOffset = 0;
    for (const auto& item : jsonFile["frus"][fruPath])
    {
        if (item.find("offset") != item.end())
        {
            vpdStartOffset = item["offset"];
        }
    }

    Impl obj(completeVPDFile, (constants::pimPath + inventoryPath), fruPath,
             vpdStartOffset);
    std::string keywordVal = obj.readKwFromHw(recordName, keyword);

    keywordVal = getPrintableValue(keywordVal);

    if (keywordVal.empty())
    {
        std::cerr << "The given keyword " << keyword << " or record "
                  << recordName
                  << " or both are not present in the given FRU path "
                  << fruPath << std::endl;
        return;
    }

    if (!value.empty())
    {
        if (copyStringToFile(keywordVal))
        {
            std::cout << "Value read is saved in the file " << value
                      << std::endl;
            return;
        }
        else
        {
            std::cerr
                << "Error while saving the read value in file. Displaying "
                   "the read value on console"
                << std::endl;
        }
    }

    json output = json::object({});
    json kwVal = json::object({});
    kwVal.emplace(keyword, keywordVal);
    output.emplace(fruPath, kwVal);
    debugger(output);
}

void VpdTool::printFixSystemVPDOption(UserOption option)
{
    switch (option)
    {
        case VpdTool::EXIT:
            cout << "\nEnter 0 => To exit successfully : ";
            break;
        case VpdTool::BACKUP_DATA_FOR_ALL:
            cout << "\n\nEnter 1 => If you choose the data on backup for all "
                    "mismatching record-keyword pairs";
            break;
        case VpdTool::SYSTEM_BACKPLANE_DATA_FOR_ALL:
            cout << "\nEnter 2 => If you choose the data on primary for all "
                    "mismatching record-keyword pairs";
            break;
        case VpdTool::MORE_OPTIONS:
            cout << "\nEnter 3 => If you wish to explore more options";
            break;
        case VpdTool::BACKUP_DATA_FOR_CURRENT:
            cout << "\nEnter 4 => If you choose the data on backup as the "
                    "right value";
            break;
        case VpdTool::SYSTEM_BACKPLANE_DATA_FOR_CURRENT:
            cout << "\nEnter 5 => If you choose the data on primary as the "
                    "right value";
            break;
        case VpdTool::NEW_VALUE_ON_BOTH:
            cout << "\nEnter 6 => If you wish to enter a new value to update "
                    "both on backup and primary";
            break;
        case VpdTool::SKIP_CURRENT:
            cout << "\nEnter 7 => If you wish to skip the above "
                    "record-keyword pair";
            break;
    }
}

void VpdTool::getSystemDataFromCache(IntfPropMap& svpdBusData)
{
    const auto vsys = getAllDBusProperty<GetAllResultType>(
        constants::pimIntf,
        "/xyz/openbmc_project/inventory/system/chassis/motherboard",
        "com.ibm.ipzvpd.VSYS");
    svpdBusData.emplace("VSYS", vsys);

    const auto vcen = getAllDBusProperty<GetAllResultType>(
        constants::pimIntf,
        "/xyz/openbmc_project/inventory/system/chassis/motherboard",
        "com.ibm.ipzvpd.VCEN");
    svpdBusData.emplace("VCEN", vcen);

    const auto lxr0 = getAllDBusProperty<GetAllResultType>(
        constants::pimIntf,
        "/xyz/openbmc_project/inventory/system/chassis/motherboard",
        "com.ibm.ipzvpd.LXR0");
    svpdBusData.emplace("LXR0", lxr0);

    const auto util = getAllDBusProperty<GetAllResultType>(
        constants::pimIntf,
        "/xyz/openbmc_project/inventory/system/chassis/motherboard",
        "com.ibm.ipzvpd.UTIL");
    svpdBusData.emplace("UTIL", util);
}

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

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

    int num = 0;

    // Get system VPD data in map
    unordered_map<string, DbusPropertyMap> vpdMap;
    json js;
    getVPDInMap(constants::systemVpdFilePath, vpdMap, js,
                constants::pimPath +
                    static_cast<std::string>(constants::SYSTEM_OBJECT));

    // Get system VPD D-Bus Data in a map
    IntfPropMap svpdBusData;
    getSystemDataFromCache(svpdBusData);

    for (const auto& recordKw : svpdKwdMap)
    {
        string record = recordKw.first;

        // Extract specific record data from the svpdBusData map.
        const auto& rec = svpdBusData.find(record);

        if (rec == svpdBusData.end())
        {
            std::cerr << record << " not a part of critical system VPD records."
                      << std::endl;
            continue;
        }

        const auto& recData = svpdBusData.find(record)->second;

        string busStr{}, hwValStr{};

        for (const auto& keywordInfo : recordKw.second)
        {
            const auto& keyword = get<0>(keywordInfo);
            string mismatch = "NO"; // no mismatch
            string hardwareValue{};
            auto recItr = vpdMap.find(record);

            if (recItr != vpdMap.end())
            {
                DbusPropertyMap& kwValMap = recItr->second;
                auto kwItr = kwValMap.find(keyword);
                if (kwItr != kwValMap.end())
                {
                    hardwareValue = kwItr->second;
                }
            }

            inventory::Value kwValue;
            for (auto& kwData : recData)
            {
                if (kwData.first == keyword)
                {
                    kwValue = kwData.second;
                    break;
                }
            }

            if (keyword != "SE") // SE to display in Hex string only
            {
                ostringstream hwValStream;
                hwValStream << "0x";
                hwValStr = hwValStream.str();

                for (uint16_t byte : hardwareValue)
                {
                    hwValStream << setfill('0') << setw(2) << hex << byte;
                    hwValStr = hwValStream.str();
                }

                if (const auto value = get_if<Binary>(&kwValue))
                {
                    busStr = hexString(*value);
                }
                if (busStr != hwValStr)
                {
                    mismatch = "YES";
                }
            }
            else
            {
                if (const auto value = get_if<Binary>(&kwValue))
                {
                    busStr = getPrintableValue(*value);
                }
                if (busStr != hardwareValue)
                {
                    mismatch = "YES";
                }
                hwValStr = hardwareValue;
            }
            recKwData.push_back(
                make_tuple(++num, record, keyword, busStr, hwValStr, mismatch));

            std::string splitLine(191, '-');
            cout << left << setw(6) << num << left << setw(8) << record << left
                 << setw(9) << keyword << left << setw(75) << setfill(' ')
                 << busStr << left << setw(75) << setfill(' ') << hwValStr
                 << left << setw(14) << mismatch << '\n'
                 << splitLine << endl;
        }
    }
    parseSVPDOptions(js);
    return 0;
}

void VpdTool::parseSVPDOptions(const nlohmann::json& json)
{
    do
    {
        printFixSystemVPDOption(VpdTool::BACKUP_DATA_FOR_ALL);
        printFixSystemVPDOption(VpdTool::SYSTEM_BACKPLANE_DATA_FOR_ALL);
        printFixSystemVPDOption(VpdTool::MORE_OPTIONS);
        printFixSystemVPDOption(VpdTool::EXIT);

        int option = 0;
        cin >> option;

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

        if (json.find("frus") == json.end())
        {
            throw runtime_error("Frus not found in json");
        }

        bool mismatchFound = false;

        if (option == VpdTool::BACKUP_DATA_FOR_ALL)
        {
            for (const auto& data : recKwData)
            {
                if (get<5>(data) == "YES")
                {
                    EditorImpl edit(constants::systemVpdFilePath, json,
                                    get<1>(data), get<2>(data));
                    edit.updateKeyword(toBinary(get<3>(data)), 0, true);
                    mismatchFound = true;
                }
            }

            if (mismatchFound)
            {
                cout << "\nData updated successfully for all mismatching "
                        "record-keyword pairs by choosing their corresponding "
                        "data from backup. Exit successfully.\n"
                     << endl;
            }
            else
            {
                cout << "\nNo mismatch found for any of the above mentioned "
                        "record-keyword pair. Exit successfully.\n";
            }

            exit(0);
        }
        else if (option == VpdTool::SYSTEM_BACKPLANE_DATA_FOR_ALL)
        {
            for (const auto& data : recKwData)
            {
                if (get<5>(data) == "YES")
                {
                    EditorImpl edit(constants::systemVpdFilePath, json,
                                    get<1>(data), get<2>(data));
                    edit.updateKeyword(toBinary(get<4>(data)), 0, true);
                    mismatchFound = true;
                }
            }

            if (mismatchFound)
            {
                cout << "\nData updated successfully for all mismatching "
                        "record-keyword pairs by choosing their corresponding "
                        "data from primary VPD.\n"
                     << endl;
            }
            else
            {
                cout << "\nNo mismatch found for any of the above mentioned "
                        "record-keyword pair. Exit successfully.\n";
            }

            exit(0);
        }
        else if (option == VpdTool::MORE_OPTIONS)
        {
            cout << "\nIterate through all restorable record-keyword pairs\n";

            for (const auto& data : recKwData)
            {
                do
                {
                    cout << '\n' << outline << endl;

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

                    cout << left << setw(6) << get<0>(data) << left << setw(8)
                         << get<1>(data) << left << setw(9) << get<2>(data)
                         << left << setw(75) << setfill(' ') << get<3>(data)
                         << left << setw(75) << setfill(' ') << get<4>(data)
                         << left << setw(14) << get<5>(data);

                    cout << '\n' << outline << endl;

                    if (get<5>(data) == "NO")
                    {
                        cout << "\nNo mismatch found.\n";
                        printFixSystemVPDOption(VpdTool::NEW_VALUE_ON_BOTH);
                        printFixSystemVPDOption(VpdTool::SKIP_CURRENT);
                        printFixSystemVPDOption(VpdTool::EXIT);
                    }
                    else
                    {
                        printFixSystemVPDOption(
                            VpdTool::BACKUP_DATA_FOR_CURRENT);
                        printFixSystemVPDOption(
                            VpdTool::SYSTEM_BACKPLANE_DATA_FOR_CURRENT);
                        printFixSystemVPDOption(VpdTool::NEW_VALUE_ON_BOTH);
                        printFixSystemVPDOption(VpdTool::SKIP_CURRENT);
                        printFixSystemVPDOption(VpdTool::EXIT);
                    }

                    cin >> option;
                    cout << '\n' << outline << endl;

                    EditorImpl edit(constants::systemVpdFilePath, json,
                                    get<1>(data), get<2>(data));

                    if (option == VpdTool::BACKUP_DATA_FOR_CURRENT)
                    {
                        edit.updateKeyword(toBinary(get<3>(data)), 0, true);
                        cout << "\nData updated successfully.\n";
                        break;
                    }
                    else if (option ==
                             VpdTool::SYSTEM_BACKPLANE_DATA_FOR_CURRENT)
                    {
                        edit.updateKeyword(toBinary(get<4>(data)), 0, true);
                        cout << "\nData updated successfully.\n";
                        break;
                    }
                    else if (option == VpdTool::NEW_VALUE_ON_BOTH)
                    {
                        string value;
                        cout << "\nEnter the new value to update on both "
                                "primary & backup. Value should be in ASCII or "
                                "in HEX(prefixed with 0x) : ";
                        cin >> value;
                        cout << '\n' << outline << endl;

                        edit.updateKeyword(toBinary(value), 0, true);
                        cout << "\nData updated successfully.\n";
                        break;
                    }
                    else if (option == VpdTool::SKIP_CURRENT)
                    {
                        cout << "\nSkipped the above record-keyword pair. "
                                "Continue to the next available pair.\n";
                        break;
                    }
                    else if (option == VpdTool::EXIT)
                    {
                        cout << "\nExit successfully\n";
                        exit(0);
                    }
                    else
                    {
                        cout << "\nProvide a valid option. Retrying for the "
                                "current record-keyword pair\n";
                    }
                } while (1);
            }
            exit(0);
        }
        else if (option == VpdTool::EXIT)
        {
            cout << "\nExit successfully";
            exit(0);
        }
        else
        {
            cout << "\nProvide a valid option. Retry.";
            continue;
        }

    } while (true);
}

int VpdTool::cleanSystemVPD()
{
    try
    {
        // Get system VPD hardware data in map
        unordered_map<string, DbusPropertyMap> vpdMap;
        json js;
        getVPDInMap(constants::systemVpdFilePath, vpdMap, js,
                    constants::pimPath +
                        static_cast<std::string>(constants::SYSTEM_OBJECT));

        RecKwValMap kwdsToBeUpdated;

        for (auto recordMap : svpdKwdMap)
        {
            const auto& record = recordMap.first;
            std::unordered_map<std::string, Binary> kwDefault;
            for (auto keywordMap : recordMap.second)
            {
                // Skip those keywords which cannot be reset at manufacturing
                if (!std::get<3>(keywordMap))
                {
                    continue;
                }
                const auto& keyword = std::get<0>(keywordMap);

                // Get hardware value for this keyword from vpdMap
                Binary hardwareValue;

                auto recItr = vpdMap.find(record);

                if (recItr != vpdMap.end())
                {
                    DbusPropertyMap& kwValMap = recItr->second;
                    auto kwItr = kwValMap.find(keyword);
                    if (kwItr != kwValMap.end())
                    {
                        hardwareValue = toBinary(kwItr->second);
                    }
                }

                // compare hardware value with the keyword's default value
                auto defaultValue = std::get<1>(keywordMap);
                if (hardwareValue != defaultValue)
                {
                    EditorImpl edit(constants::systemVpdFilePath, js, record,
                                    keyword);
                    edit.updateKeyword(defaultValue, 0, true);
                }
            }
        }

        std::cout << "\n The critical keywords from system backplane VPD has "
                     "been reset successfully."
                  << std::endl;
    }
    catch (const std::exception& e)
    {
        std::cerr << e.what();
        std::cerr
            << "\nManufacturing reset on system vpd keywords is unsuccessful";
    }
    return 0;
}
