#include "config.h"

#include "ibm_vpd_utils.hpp"

#include "common_utility.hpp"
#include "defines.hpp"
#include "vpd_exceptions.hpp"

#include <boost/algorithm/string.hpp>
#include <filesystem>
#include <fstream>
#include <gpiod.hpp>
#include <iomanip>
#include <nlohmann/json.hpp>
#include <phosphor-logging/elog-errors.hpp>
#include <phosphor-logging/log.hpp>
#include <regex>
#include <sdbusplus/server.hpp>
#include <sstream>
#include <vector>
#include <xyz/openbmc_project/Common/error.hpp>

using json = nlohmann::json;

namespace openpower
{
namespace vpd
{
using namespace openpower::vpd::constants;
using namespace inventory;
using namespace phosphor::logging;
using namespace sdbusplus::xyz::openbmc_project::Common::Error;
using namespace record;
using namespace openpower::vpd::exceptions;
using namespace common::utility;
using Severity = openpower::vpd::constants::PelSeverity;
namespace fs = std::filesystem;

// mapping of severity enum to severity interface
static std::unordered_map<Severity, std::string> sevMap = {
    {Severity::INFORMATIONAL,
     "xyz.openbmc_project.Logging.Entry.Level.Informational"},
    {Severity::DEBUG, "xyz.openbmc_project.Logging.Entry.Level.Debug"},
    {Severity::NOTICE, "xyz.openbmc_project.Logging.Entry.Level.Notice"},
    {Severity::WARNING, "xyz.openbmc_project.Logging.Entry.Level.Warning"},
    {Severity::CRITICAL, "xyz.openbmc_project.Logging.Entry.Level.Critical"},
    {Severity::EMERGENCY, "xyz.openbmc_project.Logging.Entry.Level.Emergency"},
    {Severity::ERROR, "xyz.openbmc_project.Logging.Entry.Level.Error"},
    {Severity::ALERT, "xyz.openbmc_project.Logging.Entry.Level.Alert"}};

namespace inventory
{

MapperResponse
    getObjectSubtreeForInterfaces(const std::string& root, const int32_t depth,
                                  const std::vector<std::string>& interfaces)
{
    auto bus = sdbusplus::bus::new_default();
    auto mapperCall = bus.new_method_call(mapperDestination, mapperObjectPath,
                                          mapperInterface, "GetSubTree");
    mapperCall.append(root);
    mapperCall.append(depth);
    mapperCall.append(interfaces);

    MapperResponse result = {};

    try
    {
        auto response = bus.call(mapperCall);

        response.read(result);
    }
    catch (const sdbusplus::exception_t& e)
    {
        log<level::ERR>("Error in mapper GetSubTree",
                        entry("ERROR=%s", e.what()));
    }

    return result;
}

} // namespace inventory

LE2ByteData readUInt16LE(Binary::const_iterator iterator)
{
    LE2ByteData lowByte = *iterator;
    LE2ByteData highByte = *(iterator + 1);
    lowByte |= (highByte << 8);
    return lowByte;
}

/** @brief Encodes a keyword for D-Bus.
 */
std::string encodeKeyword(const std::string& kw, const std::string& encoding)
{
    if (encoding == "MAC")
    {
        std::string res{};
        size_t first = kw[0];
        res += toHex(first >> 4);
        res += toHex(first & 0x0f);
        for (size_t i = 1; i < kw.size(); ++i)
        {
            res += ":";
            res += toHex(kw[i] >> 4);
            res += toHex(kw[i] & 0x0f);
        }
        return res;
    }
    else if (encoding == "DATE")
    {
        // Date, represent as
        // <year>-<month>-<day> <hour>:<min>
        std::string res{};
        static constexpr uint8_t skipPrefix = 3;

        auto strItr = kw.begin();
        advance(strItr, skipPrefix);
        for_each(strItr, kw.end(), [&res](size_t c) { res += c; });

        res.insert(BD_YEAR_END, 1, '-');
        res.insert(BD_MONTH_END, 1, '-');
        res.insert(BD_DAY_END, 1, ' ');
        res.insert(BD_HOUR_END, 1, ':');

        return res;
    }
    else // default to string encoding
    {
        return std::string(kw.begin(), kw.end());
    }
}

std::string readBusProperty(const std::string& obj, const std::string& inf,
                            const std::string& prop)
{
    std::string propVal{};
    std::string object = INVENTORY_PATH + obj;
    auto bus = sdbusplus::bus::new_default();
    auto properties = bus.new_method_call(
        "xyz.openbmc_project.Inventory.Manager", object.c_str(),
        "org.freedesktop.DBus.Properties", "Get");
    properties.append(inf);
    properties.append(prop);
    auto result = bus.call(properties);
    if (!result.is_method_error())
    {
        inventory::Value val;
        result.read(val);
        if (auto pVal = std::get_if<Binary>(&val))
        {
            propVal.assign(reinterpret_cast<const char*>(pVal->data()),
                           pVal->size());
        }
        else if (auto pVal = std::get_if<std::string>(&val))
        {
            propVal.assign(pVal->data(), pVal->size());
        }
        else if (auto pVal = get_if<bool>(&val))
        {
            if (*pVal == false)
            {
                propVal = "false";
            }
            else
            {
                propVal = "true";
            }
        }
    }
    return propVal;
}

void createPEL(const std::map<std::string, std::string>& additionalData,
               const Severity& sev, const std::string& errIntf, sd_bus* sdBus)
{
    // This pointer will be NULL in case the call is made from ibm-read-vpd. In
    // that case a sync call will do.
    if (sdBus == nullptr)
    {
        createSyncPEL(additionalData, sev, errIntf);
    }
    else
    {
        std::string errDescription{};
        auto pos = additionalData.find("DESCRIPTION");
        if (pos != additionalData.end())
        {
            errDescription = pos->second;
        }
        else
        {
            errDescription = "Description field missing in additional data";
        }

        std::string pelSeverity =
            "xyz.openbmc_project.Logging.Entry.Level.Error";
        auto itr = sevMap.find(sev);
        if (itr != sevMap.end())
        {
            pelSeverity = itr->second;
        }

        // Implies this is a call from Manager. Hence we need to make an async
        // call to avoid deadlock with Phosphor-logging.
        auto rc = sd_bus_call_method_async(
            sdBus, NULL, loggerService, loggerObjectPath, loggerCreateInterface,
            "Create", NULL, NULL, "ssa{ss}", errIntf.c_str(),
            pelSeverity.c_str(), 1, "DESCRIPTION", errDescription.c_str());

        if (rc < 0)
        {
            log<level::ERR>("Error calling sd_bus_call_method_async",
                            entry("RC=%d", rc), entry("MSG=%s", strerror(-rc)));
        }
    }
}

void createSyncPEL(const std::map<std::string, std::string>& additionalData,
                   const Severity& sev, const std::string& errIntf)
{
    try
    {
        std::string pelSeverity =
            "xyz.openbmc_project.Logging.Entry.Level.Error";
        auto bus = sdbusplus::bus::new_default();
        auto service = getService(bus, loggerObjectPath, loggerCreateInterface);
        auto method = bus.new_method_call(service.c_str(), loggerObjectPath,
                                          loggerCreateInterface, "Create");

        auto itr = sevMap.find(sev);
        if (itr != sevMap.end())
        {
            pelSeverity = itr->second;
        }

        method.append(errIntf, pelSeverity, additionalData);
        auto resp = bus.call(method);
    }
    catch (const sdbusplus::exception_t& e)
    {
        std::cerr << "Dbus call to phosphor-logging Create failed. Reason:"
                  << e.what();
    }
}

inventory::VPDfilepath getVpdFilePath(const std::string& jsonFile,
                                      const std::string& ObjPath)
{
    std::ifstream inventoryJson(jsonFile);
    const auto& jsonObject = json::parse(inventoryJson);
    inventory::VPDfilepath filePath{};

    if (jsonObject.find("frus") == jsonObject.end())
    {
        throw(VpdJsonException(
            "Invalid JSON structure - frus{} object not found in ", jsonFile));
    }

    const nlohmann::json& groupFRUS =
        jsonObject["frus"].get_ref<const nlohmann::json::object_t&>();
    for (const auto& itemFRUS : groupFRUS.items())
    {
        const std::vector<nlohmann::json>& groupEEPROM =
            itemFRUS.value().get_ref<const nlohmann::json::array_t&>();
        for (const auto& itemEEPROM : groupEEPROM)
        {
            if (itemEEPROM["inventoryPath"]
                    .get_ref<const nlohmann::json::string_t&>() == ObjPath)
            {
                filePath = itemFRUS.key();
                return filePath;
            }
        }
    }

    return filePath;
}

bool isPathInJson(const std::string& eepromPath)
{
    bool present = false;
    std::ifstream inventoryJson(INVENTORY_JSON_SYM_LINK);

    try
    {
        auto js = json::parse(inventoryJson);
        if (js.find("frus") == js.end())
        {
            throw(VpdJsonException(
                "Invalid JSON structure - frus{} object not found in ",
                INVENTORY_JSON_SYM_LINK));
        }
        json fruJson = js["frus"];

        if (fruJson.find(eepromPath) != fruJson.end())
        {
            present = true;
        }
    }
    catch (const json::parse_error& ex)
    {
        throw(VpdJsonException("Json Parsing failed", INVENTORY_JSON_SYM_LINK));
    }
    return present;
}

bool isRecKwInDbusJson(const std::string& recordName,
                       const std::string& keyword)
{
    std::ifstream propertyJson(DBUS_PROP_JSON);
    json dbusProperty;
    bool present = false;

    if (propertyJson.is_open())
    {
        try
        {
            auto dbusPropertyJson = json::parse(propertyJson);
            if (dbusPropertyJson.find("dbusProperties") ==
                dbusPropertyJson.end())
            {
                throw(VpdJsonException("dbusProperties{} object not found in "
                                       "DbusProperties json : ",
                                       DBUS_PROP_JSON));
            }

            dbusProperty = dbusPropertyJson["dbusProperties"];
            if (dbusProperty.contains(recordName))
            {
                const std::vector<std::string>& kwdsToPublish =
                    dbusProperty[recordName];
                if (find(kwdsToPublish.begin(), kwdsToPublish.end(), keyword) !=
                    kwdsToPublish.end()) // present
                {
                    present = true;
                }
            }
        }
        catch (const json::parse_error& ex)
        {
            throw(VpdJsonException("Json Parsing failed", DBUS_PROP_JSON));
        }
    }
    else
    {
        // If dbus properties json is not available, we assume the given
        // record-keyword is part of dbus-properties json. So setting the bool
        // variable to true.
        present = true;
    }
    return present;
}

vpdType vpdTypeCheck(const Binary& vpdVector)
{
    // Read first 3 Bytes to check the 11S bar code format
    std::string is11SFormat = "";
    for (uint8_t i = 0; i < FORMAT_11S_LEN; i++)
    {
        is11SFormat += vpdVector[MEMORY_VPD_DATA_START + i];
    }

    if (vpdVector[IPZ_DATA_START] == KW_VAL_PAIR_START_TAG)
    {
        // IPZ VPD FORMAT
        return vpdType::IPZ_VPD;
    }
    else if (vpdVector[KW_VPD_DATA_START] == KW_VPD_START_TAG)
    {
        // KEYWORD VPD FORMAT
        return vpdType::KEYWORD_VPD;
    }
    else if (is11SFormat.compare(MEMORY_VPD_START_TAG) == 0)
    {
        // Memory VPD format
        return vpdType::MEMORY_VPD;
    }

    // INVALID VPD FORMAT
    return vpdType::INVALID_VPD_FORMAT;
}

const std::string getIM(const Parsed& vpdMap)
{
    Binary imVal;
    auto property = vpdMap.find("VSBP");
    if (property != vpdMap.end())
    {
        auto kw = (property->second).find("IM");
        if (kw != (property->second).end())
        {
            copy(kw->second.begin(), kw->second.end(), back_inserter(imVal));
        }
    }

    std::ostringstream oss;
    for (auto& i : imVal)
    {
        oss << std::setw(2) << std::setfill('0') << std::hex
            << static_cast<int>(i);
    }

    return oss.str();
}

const std::string getHW(const Parsed& vpdMap)
{
    Binary hwVal;
    auto prop = vpdMap.find("VINI");
    if (prop != vpdMap.end())
    {
        auto kw = (prop->second).find("HW");
        if (kw != (prop->second).end())
        {
            copy(kw->second.begin(), kw->second.end(), back_inserter(hwVal));
        }
    }

    // The planar pass only comes from the LSB of the HW keyword,
    // where as the MSB is used for other purposes such as signifying clock
    // termination.
    hwVal[0] = 0x00;

    std::ostringstream hwString;
    for (auto& i : hwVal)
    {
        hwString << std::setw(2) << std::setfill('0') << std::hex
                 << static_cast<int>(i);
    }

    return hwString.str();
}

std::string getSystemsJson(const Parsed& vpdMap)
{
    std::string jsonPath = "/usr/share/vpd/";
    std::string jsonName{};

    std::ifstream systemJson(SYSTEM_JSON);
    if (!systemJson)
    {
        throw((VpdJsonException("Failed to access Json path", SYSTEM_JSON)));
    }

    try
    {
        auto js = json::parse(systemJson);

        std::string hwKeyword = getHW(vpdMap);
        const std::string imKeyword = getIM(vpdMap);

        transform(hwKeyword.begin(), hwKeyword.end(), hwKeyword.begin(),
                  ::toupper);

        if (js.find("system") == js.end())
        {
            throw std::runtime_error("Invalid systems Json");
        }

        if (js["system"].find(imKeyword) == js["system"].end())
        {
            throw std::runtime_error(
                "Invalid system. This system type is not present "
                "in the systemsJson. IM: " +
                imKeyword);
        }

        if ((js["system"][imKeyword].find("constraint") !=
             js["system"][imKeyword].end()) &&
            js["system"][imKeyword]["constraint"].find("HW") !=
                js["system"][imKeyword]["constraint"].end())
        {
            // collect hw versions from json, and check hwKeyword  is part of it
            // if hwKeyword is found there then load respective json
            // otherwise load default one.
            for (const auto& hwVersion :
                 js["system"][imKeyword]["constraint"]["HW"])
            {
                std::string hw = hwVersion;
                transform(hw.begin(), hw.end(), hw.begin(), ::toupper);

                if (hw == hwKeyword)
                {
                    jsonName = js["system"][imKeyword]["constraint"]["json"];
                    break;
                }
            }

            if (jsonName.empty() && js["system"][imKeyword].find("default") !=
                                        js["system"][imKeyword].end())
            {
                jsonName = js["system"][imKeyword]["default"];
            }
        }
        else if (js["system"][imKeyword].find("default") !=
                 js["system"][imKeyword].end())
        {
            jsonName = js["system"][imKeyword]["default"];
        }
        else
        {
            throw std::runtime_error(
                "Bad System json. Neither constraint nor default found");
        }

        jsonPath += jsonName;
    }

    catch (const json::parse_error& ex)
    {
        throw(VpdJsonException("Json Parsing failed", SYSTEM_JSON));
    }
    return jsonPath;
}

void udevToGenericPath(std::string& file)
{
    // Sample udevEvent i2c path :
    // "/sys/devices/platform/ahb/ahb:apb/ahb:apb:bus@1e78a000/1e78a480.i2c-bus/i2c-8/8-0051/8-00510/nvmem"
    // find if the path contains the word i2c in it.
    if (file.find("i2c") != std::string::npos)
    {
        std::string i2cBusAddr{};

        // Every udev i2c path should have the common pattern
        // "i2c-bus_number/bus_number-vpd_address". Search for
        // "bus_number-vpd_address".
        std::regex i2cPattern("((i2c)-[0-9]+\\/)([0-9]+-[0-9]{4})");
        std::smatch match;
        if (std::regex_search(file, match, i2cPattern))
        {
            i2cBusAddr = match.str(3);
        }
        else
        {
            std::cerr << "The given udev path < " << file
                      << " > doesn't match the required pattern. Skipping VPD "
                         "collection."
                      << std::endl;
            exit(EXIT_SUCCESS);
        }
        // Forming the generic file path
        file = i2cPathPrefix + i2cBusAddr + "/eeprom";
    }
    // Sample udevEvent spi path :
    // "/sys/devices/platform/ahb/ahb:apb/1e79b000.fsi/fsi-master/fsi0/slave@00:00/00:00:00:04/spi_master/spi2/spi2.0/spi2.00/nvmem"
    // find if the path contains the word spi in it.
    else if (file.find("spi") != std::string::npos)
    {
        // Every udev spi path will have common pattern "spi<Digit>/", which
        // describes the spi bus number at which the fru is connected; Followed
        // by a slash following the vpd address of the fru. Taking the above
        // input as a common key, we try to search for the pattern "spi<Digit>/"
        // using regular expression.
        std::regex spiPattern("((spi)[0-9]+)(\\/)");
        std::string spiBus{};
        std::smatch match;
        if (std::regex_search(file, match, spiPattern))
        {
            spiBus = match.str(1);
        }
        else
        {
            std::cerr << "The given udev path < " << file
                      << " > doesn't match the required pattern. Skipping VPD "
                         "collection."
                      << std::endl;
            exit(EXIT_SUCCESS);
        }
        // Forming the generic path
        file = spiPathPrefix + spiBus + ".0/eeprom";
    }
    else
    {
        std::cerr << "\n The given EEPROM path < " << file
                  << " > is not valid. It's neither I2C nor "
                     "SPI path. Skipping VPD collection.."
                  << std::endl;
        exit(EXIT_SUCCESS);
    }
}
std::string getBadVpdName(const std::string& file)
{
    std::string badVpd = BAD_VPD_DIR;
    if (file.find("i2c") != std::string::npos)
    {
        badVpd += "i2c-";
        std::regex i2cPattern("(at24/)([0-9]+-[0-9]+)\\/");
        std::smatch match;
        if (std::regex_search(file, match, i2cPattern))
        {
            badVpd += match.str(2);
        }
    }
    else if (file.find("spi") != std::string::npos)
    {
        std::regex spiPattern("((spi)[0-9]+)(.0)");
        std::smatch match;
        if (std::regex_search(file, match, spiPattern))
        {
            badVpd += match.str(1);
        }
    }
    return badVpd;
}

void dumpBadVpd(const std::string& file, const Binary& vpdVector)
{
    fs::path badVpdDir = BAD_VPD_DIR;
    fs::create_directory(badVpdDir);
    std::string badVpdPath = getBadVpdName(file);
    if (fs::exists(badVpdPath))
    {
        std::error_code ec;
        fs::remove(badVpdPath, ec);
        if (ec) // error code
        {
            std::string error = "Error removing the existing broken vpd in ";
            error += badVpdPath;
            error += ". Error code : ";
            error += ec.value();
            error += ". Error message : ";
            error += ec.message();
            throw std::runtime_error(error);
        }
    }
    std::ofstream badVpdFileStream(badVpdPath, std::ofstream::binary);
    if (!badVpdFileStream)
    {
        throw std::runtime_error(
            "Failed to open bad vpd file path in /tmp/bad-vpd. "
            "Unable to dump the broken/bad vpd file.");
    }
    badVpdFileStream.write(reinterpret_cast<const char*>(vpdVector.data()),
                           vpdVector.size());
}

const std::string getKwVal(const Parsed& vpdMap, const std::string& rec,
                           const std::string& kwd)
{
    std::string kwVal{};

    auto findRec = vpdMap.find(rec);

    // check if record is found in map we got by parser
    if (findRec != vpdMap.end())
    {
        auto findKwd = findRec->second.find(kwd);

        if (findKwd != findRec->second.end())
        {
            kwVal = findKwd->second;
        }
    }

    return kwVal;
}

std::string byteArrayToHexString(const Binary& vec)
{
    std::stringstream ss;
    std::string hexRep = "0x";
    ss << hexRep;
    std::string str = ss.str();

    // convert Decimal to Hex string
    for (auto& v : vec)
    {
        ss << std::setfill('0') << std::setw(2) << std::hex << (int)v;
        str = ss.str();
    }
    return str;
}

std::string getPrintableValue(const Binary& vec)
{
    std::string str{};

    // find for a non printable value in the vector
    const auto it = std::find_if(vec.begin(), vec.end(),
                                 [](const auto& ele) { return !isprint(ele); });

    if (it != vec.end()) // if the given vector has any non printable value
    {
        for (auto itr = it; itr != vec.end(); itr++)
        {
            if (*itr != 0x00)
            {
                str = byteArrayToHexString(vec);
                return str;
            }
        }
        str = std::string(vec.begin(), it);
    }
    else
    {
        str = std::string(vec.begin(), vec.end());
    }
    return str;
}

void executePostFailAction(const nlohmann::json& json, const std::string& file)
{
    if ((json["frus"][file].at(0)).find("postActionFail") ==
        json["frus"][file].at(0).end())
    {
        return;
    }

    uint8_t pinValue = 0;
    std::string pinName;

    for (const auto& postAction :
         (json["frus"][file].at(0))["postActionFail"].items())
    {
        if (postAction.key() == "pin")
        {
            pinName = postAction.value();
        }
        else if (postAction.key() == "value")
        {
            // Get the value to set
            pinValue = postAction.value();
        }
    }

    std::cout << "Setting GPIO: " << pinName << " to " << (int)pinValue
              << std::endl;

    try
    {
        gpiod::line outputLine = gpiod::find_line(pinName);

        if (!outputLine)
        {
            throw GpioException(
                "Couldn't find output line for the GPIO. Skipping "
                "this GPIO action.");
        }
        outputLine.request(
            {"Disable line", ::gpiod::line_request::DIRECTION_OUTPUT, 0},
            pinValue);
    }
    catch (const std::exception& e)
    {
        std::string i2cBusAddr;
        std::string errMsg = e.what();
        errMsg += "\nGPIO: " + pinName;

        if ((json["frus"][file].at(0)["postActionFail"].find(
                "gpioI2CAddress")) !=
            json["frus"][file].at(0)["postActionFail"].end())
        {
            i2cBusAddr =
                json["frus"][file].at(0)["postActionFail"]["gpioI2CAddress"];
            errMsg += " i2cBusAddress: " + i2cBusAddr;
        }

        throw GpioException(e.what());
    }

    return;
}

std::optional<bool> isPresent(const nlohmann::json& json,
                              const std::string& file)

{
    if ((json["frus"][file].at(0)).find("presence") !=
        json["frus"][file].at(0).end())
    {
        if (((json["frus"][file].at(0)["presence"]).find("pin") !=
             json["frus"][file].at(0)["presence"].end()) &&
            ((json["frus"][file].at(0)["presence"]).find("value") !=
             json["frus"][file].at(0)["presence"].end()))
        {
            std::string presPinName =
                json["frus"][file].at(0)["presence"]["pin"];
            Byte presPinValue = json["frus"][file].at(0)["presence"]["value"];

            try
            {
                gpiod::line presenceLine = gpiod::find_line(presPinName);

                if (!presenceLine)
                {
                    std::cerr << "Couldn't find the presence line for - "
                              << presPinName << std::endl;

                    throw GpioException(
                        "Couldn't find the presence line for the "
                        "GPIO. Skipping this GPIO action.");
                }

                presenceLine.request({"Read the presence line",
                                      gpiod::line_request::DIRECTION_INPUT, 0});

                Byte gpioData = presenceLine.get_value();

                return (gpioData == presPinValue);
            }
            catch (const std::exception& e)
            {
                std::string i2cBusAddr;
                std::string errMsg = e.what();
                errMsg += " GPIO : " + presPinName;

                if ((json["frus"][file].at(0)["presence"])
                        .find("gpioI2CAddress") !=
                    json["frus"][file].at(0)["presence"].end())
                {
                    i2cBusAddr =
                        json["frus"][file].at(0)["presence"]["gpioI2CAddress"];
                    errMsg += " i2cBusAddress: " + i2cBusAddr;
                }

                // Take failure postAction
                executePostFailAction(json, file);
                throw GpioException(errMsg);
            }
        }
        else
        {
            // missing required informations
            std::cerr
                << "VPD inventory JSON missing basic informations of presence "
                   "for this FRU : ["
                << file << "]. Executing executePostFailAction." << std::endl;

            // Take failure postAction
            executePostFailAction(json, file);

            return false;
        }
    }
    return std::optional<bool>{};
}

bool executePreAction(const nlohmann::json& json, const std::string& file)
{
    auto present = isPresent(json, file);
    if (present && !present.value())
    {
        executePostFailAction(json, file);
        return false;
    }

    if ((json["frus"][file].at(0)).find("preAction") !=
        json["frus"][file].at(0).end())
    {
        if (((json["frus"][file].at(0)["preAction"]).find("pin") !=
             json["frus"][file].at(0)["preAction"].end()) &&
            ((json["frus"][file].at(0)["preAction"]).find("value") !=
             json["frus"][file].at(0)["preAction"].end()))
        {
            std::string pinName = json["frus"][file].at(0)["preAction"]["pin"];
            // Get the value to set
            Byte pinValue = json["frus"][file].at(0)["preAction"]["value"];

            std::cout << "Setting GPIO: " << pinName << " to " << (int)pinValue
                      << std::endl;
            try
            {
                gpiod::line outputLine = gpiod::find_line(pinName);

                if (!outputLine)
                {
                    std::cerr << "Couldn't find the line for output pin - "
                              << pinName << std::endl;
                    throw GpioException(
                        "Couldn't find output line for the GPIO. "
                        "Skipping this GPIO action.");
                }
                outputLine.request({"FRU pre-action",
                                    ::gpiod::line_request::DIRECTION_OUTPUT, 0},
                                   pinValue);
            }
            catch (const std::exception& e)
            {
                std::string i2cBusAddr;
                std::string errMsg = e.what();
                errMsg += " GPIO : " + pinName;

                if ((json["frus"][file].at(0)["preAction"])
                        .find("gpioI2CAddress") !=
                    json["frus"][file].at(0)["preAction"].end())
                {
                    i2cBusAddr =
                        json["frus"][file].at(0)["preAction"]["gpioI2CAddress"];
                    errMsg += " i2cBusAddress: " + i2cBusAddr;
                }

                // Take failure postAction
                executePostFailAction(json, file);
                throw GpioException(errMsg);
            }
        }
        else
        {
            // missing required informations
            std::cerr
                << "VPD inventory JSON missing basic informations of preAction "
                   "for this FRU : ["
                << file << "]. Executing executePostFailAction." << std::endl;

            // Take failure postAction
            executePostFailAction(json, file);
            return false;
        }
    }
    return true;
}

void insertOrMerge(inventory::InterfaceMap& map,
                   const inventory::Interface& interface,
                   inventory::PropertyMap&& property)
{
    if (map.find(interface) != map.end())
    {
        auto& prop = map.at(interface);
        prop.insert(property.begin(), property.end());
    }
    else
    {
        map.emplace(interface, property);
    }
}

BIOSAttrValueType readBIOSAttribute(const std::string& attrName)
{
    std::tuple<std::string, BIOSAttrValueType, BIOSAttrValueType> attrVal;
    auto bus = sdbusplus::bus::new_default();
    auto method = bus.new_method_call(
        "xyz.openbmc_project.BIOSConfigManager",
        "/xyz/openbmc_project/bios_config/manager",
        "xyz.openbmc_project.BIOSConfig.Manager", "GetAttribute");
    method.append(attrName);
    try
    {
        auto result = bus.call(method);
        result.read(std::get<0>(attrVal), std::get<1>(attrVal),
                    std::get<2>(attrVal));
    }
    catch (const sdbusplus::exception::SdBusError& e)
    {
        std::cerr << "Failed to read BIOS Attribute: " << attrName << std::endl;
        std::cerr << e.what() << std::endl;
    }
    return std::get<1>(attrVal);
}

std::string getPowerState()
{
    // TODO: How do we handle multiple chassis?
    std::string powerState{};
    auto bus = sdbusplus::bus::new_default();
    auto properties =
        bus.new_method_call("xyz.openbmc_project.State.Chassis",
                            "/xyz/openbmc_project/state/chassis0",
                            "org.freedesktop.DBus.Properties", "Get");
    properties.append("xyz.openbmc_project.State.Chassis");
    properties.append("CurrentPowerState");
    auto result = bus.call(properties);
    if (!result.is_method_error())
    {
        std::variant<std::string> val;
        result.read(val);
        if (auto pVal = std::get_if<std::string>(&val))
        {
            powerState = *pVal;
        }
    }
    std::cout << "Power state is: " << powerState << std::endl;
    return powerState;
}

Binary getVpdDataInVector(const nlohmann::json& js, const std::string& file)
{
    uint32_t offset = 0;
    // check if offset present?
    for (const auto& item : js["frus"][file])
    {
        if (item.find("offset") != item.end())
        {
            offset = item["offset"];
        }
    }

    // TODO: Figure out a better way to get max possible VPD size.
    auto maxVPDSize = std::min(std::filesystem::file_size(file),
                               static_cast<uintmax_t>(65504));

    Binary vpdVector;
    vpdVector.resize(maxVPDSize);
    std::ifstream vpdFile;
    vpdFile.open(file, std::ios::binary);

    vpdFile.seekg(offset, std::ios_base::cur);
    vpdFile.read(reinterpret_cast<char*>(&vpdVector[0]), maxVPDSize);
    vpdVector.resize(vpdFile.gcount());

    // Make sure we reset the EEPROM pointer to a "safe" location if it was DIMM
    // SPD that we just read.
    for (const auto& item : js["frus"][file])
    {
        if (item.find("extraInterfaces") != item.end())
        {
            if (item["extraInterfaces"].find(
                    "xyz.openbmc_project.Inventory.Item.Dimm") !=
                item["extraInterfaces"].end())
            {
                // moves the EEPROM pointer to 2048 'th byte.
                vpdFile.seekg(2047, std::ios::beg);
                // Read that byte and discard - to affirm the move
                // operation.
                char ch;
                vpdFile.read(&ch, sizeof(ch));
                break;
            }
        }
    }

    return vpdVector;
}
} // namespace vpd
} // namespace openpower
