#pragma once

#include "event_logger.hpp"
#include "exceptions.hpp"
#include "logger.hpp"
#include "types.hpp"

#include <gpiod.hpp>
#include <nlohmann/json.hpp>
#include <utility/common_utility.hpp>

#include <fstream>
#include <type_traits>
#include <unordered_map>

namespace vpd
{
namespace jsonUtility
{

// forward declaration of API for function map.
bool processSystemCmdTag(const nlohmann::json& i_parsedConfigJson,
                         const std::string& i_vpdFilePath,
                         const std::string& i_baseAction,
                         const std::string& i_flagToProcess);

// forward declaration of API for function map.
bool processGpioPresenceTag(
    const nlohmann::json& i_parsedConfigJson, const std::string& i_vpdFilePath,
    const std::string& i_baseAction, const std::string& i_flagToProcess);

// forward declaration of API for function map.
bool procesSetGpioTag(const nlohmann::json& i_parsedConfigJson,
                      const std::string& i_vpdFilePath,
                      const std::string& i_baseAction,
                      const std::string& i_flagToProcess);

// Function pointers to process tags from config JSON.
typedef bool (*functionPtr)(
    const nlohmann::json& i_parsedConfigJson, const std::string& i_vpdFilePath,
    const std::string& i_baseAction, const std::string& i_flagToProcess);

inline std::unordered_map<std::string, functionPtr> funcionMap{
    {"gpioPresence", processGpioPresenceTag},
    {"setGpio", procesSetGpioTag},
    {"systemCmd", processSystemCmdTag}};

/**
 * @brief API to read VPD offset from JSON file.
 *
 * @param[in] i_sysCfgJsonObj - Parsed system config JSON object.
 * @param[in] i_vpdFilePath - VPD file path.
 * @return VPD offset if found in JSON, 0 otherwise.
 */
inline size_t getVPDOffset(const nlohmann::json& i_sysCfgJsonObj,
                           const std::string& i_vpdFilePath)
{
    if (i_vpdFilePath.empty() || (i_sysCfgJsonObj.empty()) ||
        (!i_sysCfgJsonObj.contains("frus")))
    {
        return 0;
    }

    if (i_sysCfgJsonObj["frus"].contains(i_vpdFilePath))
    {
        return i_sysCfgJsonObj["frus"][i_vpdFilePath].at(0).value("offset", 0);
    }

    const nlohmann::json& l_fruList =
        i_sysCfgJsonObj["frus"].get_ref<const nlohmann::json::object_t&>();

    for (const auto& l_fru : l_fruList.items())
    {
        const auto l_fruPath = l_fru.key();

        // check if given path is redundant FRU path
        if (i_vpdFilePath == i_sysCfgJsonObj["frus"][l_fruPath].at(0).value(
                                 "redundantEeprom", ""))
        {
            // Return the offset of redundant EEPROM taken from JSON.
            return i_sysCfgJsonObj["frus"][l_fruPath].at(0).value("offset", 0);
        }
    }

    return 0;
}

/**
 * @brief API to parse respective JSON.
 *
 * @param[in] pathToJson - Path to JSON.
 * @return on success parsed JSON. On failure empty JSON object.
 *
 * Note: Caller has to handle it in case an empty JSON object is received.
 */
inline nlohmann::json getParsedJson(const std::string& pathToJson) noexcept
{
    try
    {
        if (pathToJson.empty())
        {
            throw std::runtime_error("Path to JSON is missing");
        }

        if (!std::filesystem::exists(pathToJson) ||
            std::filesystem::is_empty(pathToJson))
        {
            throw std::runtime_error("Incorrect file Path or empty file");
        }

        std::ifstream l_jsonFile(pathToJson);
        if (!l_jsonFile)
        {
            throw std::runtime_error(
                "Failed to access Json path = " + pathToJson);
        }

        return nlohmann::json::parse(l_jsonFile);
    }
    catch (const std::exception& l_ex)
    {
        logging::logMessage(
            "Failed to parse JSON file, error: " + std::string(l_ex.what()));
    }

    return nlohmann::json{};
}

/**
 * @brief Get inventory object path from system config JSON.
 *
 * Given either D-bus inventory path/FRU EEPROM path/redundant EEPROM path,
 * this API returns D-bus inventory path if present in JSON.
 *
 * @param[in] i_sysCfgJsonObj - System config JSON object
 * @param[in] i_vpdPath - Path to where VPD is stored.
 *
 * @return On success a valid path is returned, on failure an empty string is
 * returned.
 *
 * Note: Caller has to handle it in case an empty string is received.
 */
inline std::string getInventoryObjPathFromJson(
    const nlohmann::json& i_sysCfgJsonObj,
    const std::string& i_vpdPath) noexcept
{
    try
    {
        if (i_vpdPath.empty())
        {
            throw std::runtime_error("Path parameter is empty.");
        }

        if (!i_sysCfgJsonObj.contains("frus"))
        {
            throw std::runtime_error("Missing frus tag in system config JSON.");
        }

        // check if given path is FRU path
        if (i_sysCfgJsonObj["frus"].contains(i_vpdPath))
        {
            return i_sysCfgJsonObj["frus"][i_vpdPath].at(0).value(
                "inventoryPath", "");
        }

        const nlohmann::json& l_fruList =
            i_sysCfgJsonObj["frus"].get_ref<const nlohmann::json::object_t&>();

        for (const auto& l_fru : l_fruList.items())
        {
            const auto l_fruPath = l_fru.key();
            const auto l_invObjPath =
                i_sysCfgJsonObj["frus"][l_fruPath].at(0).value("inventoryPath",
                                                               "");

            // check if given path is redundant FRU path or inventory path
            if (i_vpdPath == i_sysCfgJsonObj["frus"][l_fruPath].at(0).value(
                                 "redundantEeprom", "") ||
                (i_vpdPath == l_invObjPath))
            {
                return l_invObjPath;
            }
        }
    }
    catch (const std::exception& l_ex)
    {
        logging::logMessage(
            "Failed to get inventory object path from json, error: " +
            std::string(l_ex.what()));
    }

    return std::string();
}

/**
 * @brief Process "PostFailAction" defined in config JSON.
 *
 * In case there is some error in the processing of "preAction" execution and a
 * set of procedure needs to be done as a part of post fail action. This base
 * action can be defined in the config JSON for that FRU and it will be handled
 * under this API.
 *
 * @param[in] i_parsedConfigJson - config JSON
 * @param[in] i_vpdFilePath - EEPROM file path
 * @param[in] i_flagToProcess - To identify which flag(s) needs to be processed
 * under PostFailAction tag of config JSON.
 * @return - success or failure
 */
inline bool executePostFailAction(const nlohmann::json& i_parsedConfigJson,
                                  const std::string& i_vpdFilePath,
                                  const std::string& i_flagToProcess)
{
    try
    {
        if (i_parsedConfigJson.empty() || i_vpdFilePath.empty() ||
            i_flagToProcess.empty())
        {
            throw std::runtime_error(
                "Invalid parameters. Abort processing for post fail action");
        }

        if (!(i_parsedConfigJson["frus"][i_vpdFilePath].at(0))["postFailAction"]
                 .contains(i_flagToProcess))
        {
            throw std::runtime_error(
                "Config JSON missing flag " + i_flagToProcess +
                " to execute post fail action for path = " + i_vpdFilePath);
        }

        for (const auto& l_tags : (i_parsedConfigJson["frus"][i_vpdFilePath].at(
                 0))["postFailAction"][i_flagToProcess]
                                      .items())
        {
            auto itrToFunction = funcionMap.find(l_tags.key());
            if (itrToFunction != funcionMap.end())
            {
                if (!itrToFunction->second(i_parsedConfigJson, i_vpdFilePath,
                                           "postFailAction", i_flagToProcess))
                {
                    return false;
                }
            }
        }
    }
    catch (const std::exception& l_ex)
    {
        logging::logMessage("Execute post fail action failed. Error : " +
                            std::string(l_ex.what()));
        return false;
    }

    return true;
}

/**
 * @brief Process "systemCmd" tag for a given FRU.
 *
 * The API will process "systemCmd" tag if it is defined in the config
 * JSON for the given FRU.
 *
 * @param[in] i_parsedConfigJson - config JSON
 * @param[in] i_vpdFilePath - EEPROM file path
 * @param[in] i_baseAction - Base action for which this tag has been called.
 * @param[in] i_flagToProcess - Flag nested under the base action for which this
 * tag has been called.
 * @return Execution status.
 */
inline bool processSystemCmdTag(
    const nlohmann::json& i_parsedConfigJson, const std::string& i_vpdFilePath,
    const std::string& i_baseAction, const std::string& i_flagToProcess)
{
    try
    {
        if (i_vpdFilePath.empty() || i_parsedConfigJson.empty() ||
            i_baseAction.empty() || i_flagToProcess.empty())
        {
            throw std::runtime_error(
                std::string(__FUNCTION__) +
                " Invalid parameter. Abort processing of processSystemCmd.");
        }

        if (!((i_parsedConfigJson["frus"][i_vpdFilePath].at(
                   0)[i_baseAction][i_flagToProcess]["systemCmd"])
                  .contains("cmd")))
        {
            throw JsonException(
                std::string(__FUNCTION__) +
                " Config JSON missing required information to execute system command for EEPROM " +
                i_vpdFilePath);
        }

        const std::string& l_systemCommand =
            i_parsedConfigJson["frus"][i_vpdFilePath].at(
                0)[i_baseAction][i_flagToProcess]["systemCmd"]["cmd"];

        commonUtility::executeCmd(l_systemCommand);
        return true;
    }
    catch (const std::exception& l_ex)
    {
        EventLogger::createSyncPel(
            EventLogger::getErrorType(l_ex), types::SeverityType::Informational,
            __FILE__, __FUNCTION__, 0, EventLogger::getErrorMsg(l_ex),
            std::nullopt, std::nullopt, std::nullopt, std::nullopt);
        return false;
    }
}

/**
 * @brief Checks for presence of a given FRU using GPIO line.
 *
 * This API returns the presence information of the FRU corresponding to the
 * given VPD file path by setting the presence pin.
 *
 * @param[in] i_parsedConfigJson - config JSON
 * @param[in] i_vpdFilePath - EEPROM file path
 * @param[in] i_baseAction - Base action for which this tag has been called.
 * @param[in] i_flagToProcess - Flag nested under the base action for which this
 * tag has been called.
 * @return Execution status.
 */
inline bool processGpioPresenceTag(
    const nlohmann::json& i_parsedConfigJson, const std::string& i_vpdFilePath,
    const std::string& i_baseAction, const std::string& i_flagToProcess)
{
    std::string l_presencePinName;
    try
    {
        if (i_vpdFilePath.empty() || i_parsedConfigJson.empty() ||
            i_baseAction.empty() || i_flagToProcess.empty())
        {
            throw std::runtime_error(
                std::string(__FUNCTION__) +
                "Invalid parameter. Abort processing of processGpioPresence tag");
        }

        if (!(((i_parsedConfigJson["frus"][i_vpdFilePath].at(
                    0)[i_baseAction][i_flagToProcess]["gpioPresence"])
                   .contains("pin")) &&
              ((i_parsedConfigJson["frus"][i_vpdFilePath].at(
                    0)[i_baseAction][i_flagToProcess]["gpioPresence"])
                   .contains("value"))))
        {
            throw JsonException(
                std::string(__FUNCTION__) +
                "Config JSON missing required information to detect presence for EEPROM " +
                i_vpdFilePath);
        }

        // get the pin name
        l_presencePinName = i_parsedConfigJson["frus"][i_vpdFilePath].at(
            0)[i_baseAction][i_flagToProcess]["gpioPresence"]["pin"];

        // get the pin value
        uint8_t l_presencePinValue =
            i_parsedConfigJson["frus"][i_vpdFilePath].at(
                0)[i_baseAction][i_flagToProcess]["gpioPresence"]["value"];

        gpiod::line l_presenceLine = gpiod::find_line(l_presencePinName);

        if (!l_presenceLine)
        {
            throw GpioException("Couldn't find the GPIO line.");
        }

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

        return (l_presencePinValue == l_presenceLine.get_value());
    }
    catch (const std::exception& l_ex)
    {
        if (EventLogger::getErrorType(l_ex) != types::ErrorType::GpioError)
        {
            EventLogger::createSyncPel(
                EventLogger::getErrorType(l_ex),
                types::SeverityType::Informational, __FILE__, __FUNCTION__, 0,
                EventLogger::getErrorMsg(l_ex), std::nullopt, std::nullopt,
                std::nullopt, std::nullopt);
            return false;
        }

        std::string l_errMsg = "Exception on GPIO line: ";
        l_errMsg += l_presencePinName;
        l_errMsg += " Reason: ";
        l_errMsg += l_ex.what();
        l_errMsg += " File: " + i_vpdFilePath + " Pel Logged";

        // ToDo -- Update Internal Rc code.
        EventLogger::createAsyncPelWithInventoryCallout(
            EventLogger::getErrorType(l_ex), types::SeverityType::Informational,
            {{getInventoryObjPathFromJson(i_parsedConfigJson, i_vpdFilePath),
              types::CalloutPriority::High}},
            std::source_location::current().file_name(),
            std::source_location::current().function_name(), 0, l_errMsg,
            std::nullopt, std::nullopt, std::nullopt, std::nullopt);

        logging::logMessage(l_errMsg);

        // Except when GPIO pin value is false, we go and try collecting the
        // FRU VPD as we couldn't able to read GPIO pin value due to some
        // error/exception. So returning true in error scenario.
        return true;
    }
}

/**
 * @brief Process "setGpio" tag for a given FRU.
 *
 * This API enables the GPIO line.
 *
 * @param[in] i_parsedConfigJson - config JSON
 * @param[in] i_vpdFilePath - EEPROM file path
 * @param[in] i_baseAction - Base action for which this tag has been called.
 * @param[in] i_flagToProcess - Flag nested under the base action for which this
 * tag has been called.
 * @return Execution status.
 */
inline bool procesSetGpioTag(
    const nlohmann::json& i_parsedConfigJson, const std::string& i_vpdFilePath,
    const std::string& i_baseAction, const std::string& i_flagToProcess)
{
    std::string l_pinName;
    try
    {
        if (i_vpdFilePath.empty() || i_parsedConfigJson.empty() ||
            i_baseAction.empty() || i_flagToProcess.empty())
        {
            throw std::runtime_error(
                std::string(__FUNCTION__) +
                " Invalid parameter. Abort processing of procesSetGpio.");
        }

        if (!(((i_parsedConfigJson["frus"][i_vpdFilePath].at(
                    0)[i_baseAction][i_flagToProcess]["setGpio"])
                   .contains("pin")) &&
              ((i_parsedConfigJson["frus"][i_vpdFilePath].at(
                    0)[i_baseAction][i_flagToProcess]["setGpio"])
                   .contains("value"))))
        {
            throw JsonException(
                std::string(__FUNCTION__) +
                " Config JSON missing required information to set gpio line for EEPROM " +
                i_vpdFilePath);
        }

        l_pinName = i_parsedConfigJson["frus"][i_vpdFilePath].at(
            0)[i_baseAction][i_flagToProcess]["setGpio"]["pin"];

        // Get the value to set
        uint8_t l_pinValue = i_parsedConfigJson["frus"][i_vpdFilePath].at(
            0)[i_baseAction][i_flagToProcess]["setGpio"]["value"];

        logging::logMessage(
            "Setting GPIO: " + l_pinName + " to " + std::to_string(l_pinValue));

        gpiod::line l_outputLine = gpiod::find_line(l_pinName);

        if (!l_outputLine)
        {
            throw GpioException("Couldn't find GPIO line.");
        }

        l_outputLine.request(
            {"FRU Action", ::gpiod::line_request::DIRECTION_OUTPUT, 0},
            l_pinValue);
        return true;
    }
    catch (const std::exception& l_ex)
    {
        if (EventLogger::getErrorType(l_ex) != types::ErrorType::GpioError)
        {
            EventLogger::createSyncPel(
                EventLogger::getErrorType(l_ex),
                types::SeverityType::Informational, __FILE__, __FUNCTION__, 0,
                EventLogger::getErrorMsg(l_ex), std::nullopt, std::nullopt,
                std::nullopt, std::nullopt);
        }
        else
        {
            std::string l_errMsg = "Exception on GPIO line: ";
            l_errMsg += l_pinName;
            l_errMsg += " Reason: ";
            l_errMsg += l_ex.what();
            l_errMsg += " File: " + i_vpdFilePath + " Pel Logged";

            // ToDo -- Update Internal RC code
            EventLogger::createAsyncPelWithInventoryCallout(
                EventLogger::getErrorType(l_ex),
                types::SeverityType::Informational,
                {{getInventoryObjPathFromJson(i_parsedConfigJson,
                                              i_vpdFilePath),
                  types::CalloutPriority::High}},
                std::source_location::current().file_name(),
                std::source_location::current().function_name(), 0, l_errMsg,
                std::nullopt, std::nullopt, std::nullopt, std::nullopt);

            logging::logMessage(l_errMsg);
        }

        return false;
    }
}

/**
 * @brief Process any action, if defined in config JSON.
 *
 * If any FRU(s) requires any special handling, then this base action can be
 * defined for that FRU in the config JSON, processing of which will be handled
 * in this API.
 * Examples of action - preAction, PostAction etc.
 *
 * @param[in] i_parsedConfigJson - config JSON
 * @param[in] i_action - Base action to be performed.
 * @param[in] i_vpdFilePath - EEPROM file path
 * @param[in] i_flagToProcess - To identify which flag(s) needs to be processed
 * under PreAction tag of config JSON.
 * @return - success or failure
 */
inline bool executeBaseAction(
    const nlohmann::json& i_parsedConfigJson, const std::string& i_action,
    const std::string& i_vpdFilePath, const std::string& i_flagToProcess)
{
    try
    {
        if (i_flagToProcess.empty() || i_action.empty() ||
            i_vpdFilePath.empty() || !i_parsedConfigJson.contains("frus"))
        {
            throw std::runtime_error(
                std::string(__FUNCTION__) + " Invalid parameter");
        }

        if (!i_parsedConfigJson["frus"].contains(i_vpdFilePath))
        {
            throw JsonException(std::string(__FUNCTION__) + " File path: " +
                                i_vpdFilePath + " not found in JSON");
        }

        if (!i_parsedConfigJson["frus"][i_vpdFilePath].at(0).contains(i_action))
        {
            throw JsonException(
                std::string(__FUNCTION__) + " Action [" + i_action +
                "] not defined for file path:" + i_vpdFilePath);
        }

        if (!(i_parsedConfigJson["frus"][i_vpdFilePath].at(0))[i_action]
                 .contains(i_flagToProcess))
        {
            throw JsonException(
                std::string(__FUNCTION__) + "Config JSON missing flag [" +
                i_flagToProcess +
                "] to execute action for path = " + i_vpdFilePath);
        }
    }
    catch (const std::exception& l_ex)
    {
        EventLogger::createSyncPel(
            EventLogger::getErrorType(l_ex), types::SeverityType::Informational,
            __FILE__, __FUNCTION__, 0, EventLogger::getErrorMsg(l_ex),
            std::nullopt, std::nullopt, std::nullopt, std::nullopt);
        return false;
    }

    const nlohmann::json& l_tagsJson =
        (i_parsedConfigJson["frus"][i_vpdFilePath].at(
            0))[i_action][i_flagToProcess];

    for (const auto& l_tag : l_tagsJson.items())
    {
        auto itrToFunction = funcionMap.find(l_tag.key());
        if (itrToFunction != funcionMap.end())
        {
            if (!itrToFunction->second(i_parsedConfigJson, i_vpdFilePath,
                                       i_action, i_flagToProcess))
            {
                // In case any of the tag fails to execute. Mark action
                // as failed for that flag.
                return false;
            }
        }
    }

    return true;
}

/**
 * @brief Get redundant FRU path from system config JSON
 *
 * Given either D-bus inventory path/FRU path/redundant FRU path, this
 * API returns the redundant FRU path taken from "redundantEeprom" tag from
 * system config JSON.
 *
 * @param[in] i_sysCfgJsonObj - System config JSON object.
 * @param[in] i_vpdPath - Path to where VPD is stored.
 *
 * @return On success return valid path, on failure return empty string.
 */
inline std::string getRedundantEepromPathFromJson(
    const nlohmann::json& i_sysCfgJsonObj,
    const std::string& i_vpdPath) noexcept
{
    try
    {
        if (i_vpdPath.empty())
        {
            throw std::runtime_error("Path parameter is empty.");
        }

        if (!i_sysCfgJsonObj.contains("frus"))
        {
            throw std::runtime_error("Missing frus tag in system config JSON.");
        }

        // check if given path is FRU path
        if (i_sysCfgJsonObj["frus"].contains(i_vpdPath))
        {
            return i_sysCfgJsonObj["frus"][i_vpdPath].at(0).value(
                "redundantEeprom", "");
        }

        const nlohmann::json& l_fruList =
            i_sysCfgJsonObj["frus"].get_ref<const nlohmann::json::object_t&>();

        for (const auto& l_fru : l_fruList.items())
        {
            const std::string& l_fruPath = l_fru.key();
            const std::string& l_redundantFruPath =
                i_sysCfgJsonObj["frus"][l_fruPath].at(0).value(
                    "redundantEeprom", "");

            // check if given path is inventory path or redundant FRU path
            if ((i_sysCfgJsonObj["frus"][l_fruPath].at(0).value(
                     "inventoryPath", "") == i_vpdPath) ||
                (l_redundantFruPath == i_vpdPath))
            {
                return l_redundantFruPath;
            }
        }
    }
    catch (const std::exception& l_ex)
    {
        logging::logMessage("Failed to get redundant EEPROM path, error: " +
                            std::string(l_ex.what()));
    }

    return std::string();
}

/**
 * @brief Get FRU EEPROM path from system config JSON
 *
 * Given either D-bus inventory path/FRU EEPROM path/redundant EEPROM path,
 * this API returns FRU EEPROM path if present in JSON.
 *
 * @param[in] i_sysCfgJsonObj - System config JSON object
 * @param[in] i_vpdPath - Path to where VPD is stored.
 *
 * @return On success return valid path, on failure return empty string.
 */
inline std::string getFruPathFromJson(const nlohmann::json& i_sysCfgJsonObj,
                                      const std::string& i_vpdPath) noexcept
{
    try
    {
        if (i_vpdPath.empty())
        {
            throw std::runtime_error("Path parameter is empty.");
        }

        if (!i_sysCfgJsonObj.contains("frus"))
        {
            throw std::runtime_error("Missing frus tag in system config JSON.");
        }

        // check if given path is FRU path
        if (i_sysCfgJsonObj["frus"].contains(i_vpdPath))
        {
            return i_vpdPath;
        }

        const nlohmann::json& l_fruList =
            i_sysCfgJsonObj["frus"].get_ref<const nlohmann::json::object_t&>();

        for (const auto& l_fru : l_fruList.items())
        {
            const auto l_fruPath = l_fru.key();

            // check if given path is redundant FRU path or inventory path
            if (i_vpdPath == i_sysCfgJsonObj["frus"][l_fruPath].at(0).value(
                                 "redundantEeprom", "") ||
                (i_vpdPath == i_sysCfgJsonObj["frus"][l_fruPath].at(0).value(
                                  "inventoryPath", "")))
            {
                return l_fruPath;
            }
        }
    }
    catch (const std::exception& l_ex)
    {
        logging::logMessage("Failed to get FRU path from JSON, error: " +
                            std::string(l_ex.what()));
    }

    return std::string();
}

/**
 * @brief An API to check backup and restore VPD is required.
 *
 * The API checks if there is provision for backup and restore mentioned in the
 * system config JSON, by looking "backupRestoreConfigPath" tag.
 * Checks if the path mentioned is a hardware path, by checking if the file path
 * exists and size of contents in the path.
 *
 * @param[in] i_sysCfgJsonObj - System config JSON object.
 *
 * @return true if backup and restore is required, false otherwise.
 */
inline bool isBackupAndRestoreRequired(const nlohmann::json& i_sysCfgJsonObj)
{
    try
    {
        const std::string& l_backupAndRestoreCfgFilePath =
            i_sysCfgJsonObj.value("backupRestoreConfigPath", "");
        if (!l_backupAndRestoreCfgFilePath.empty() &&
            std::filesystem::exists(l_backupAndRestoreCfgFilePath) &&
            !std::filesystem::is_empty(l_backupAndRestoreCfgFilePath))
        {
            return true;
        }
    }
    catch (std::exception& ex)
    {
        logging::logMessage(ex.what());
    }
    return false;
}

/** @brief API to check if an action is required for given EEPROM path.
 *
 * System config JSON can contain pre-action, post-action etc. like actions
 * defined for an EEPROM path. The API will check if any such action is defined
 * for the EEPROM.
 *
 * @param[in] i_sysCfgJsonObj - System config JSON object.
 * @param[in] i_vpdFruPath - EEPROM path.
 * @param[in] i_action - Action to be checked.
 * @param[in] i_flowFlag - Denotes the flow w.r.t which the action should be
 * triggered.
 * @return - True if action is defined for the flow, false otherwise.
 */
inline bool isActionRequired(
    const nlohmann::json& i_sysCfgJsonObj, const std::string& i_vpdFruPath,
    const std::string& i_action, const std::string& i_flowFlag)
{
    if (i_vpdFruPath.empty() || i_action.empty() || i_flowFlag.empty())
    {
        logging::logMessage("Invalid parameters recieved.");
        return false;
    }

    if (!i_sysCfgJsonObj.contains("frus"))
    {
        logging::logMessage("Invalid JSON object recieved.");
        return false;
    }

    if (!i_sysCfgJsonObj["frus"].contains(i_vpdFruPath))
    {
        logging::logMessage(
            "JSON object does not contain EEPROM path " + i_vpdFruPath);
        return false;
    }

    if ((i_sysCfgJsonObj["frus"][i_vpdFruPath].at(0)).contains(i_action))
    {
        if ((i_sysCfgJsonObj["frus"][i_vpdFruPath].at(0))[i_action].contains(
                i_flowFlag))
        {
            return true;
        }

        logging::logMessage("Flow flag: [" + i_flowFlag +
                            "], not found in JSON for path: " + i_vpdFruPath);
        return false;
    }
    return false;
}

/**
 * @brief An API to return list of FRUs that needs GPIO polling.
 *
 * An API that checks for the FRUs that requires GPIO polling and returns
 * a list of FRUs that needs polling. Returns an empty list if there are
 * no FRUs that requires polling.
 *
 * @param[in] i_sysCfgJsonObj - System config JSON object.
 *
 * @return On success list of FRUs parameters that needs polling. On failure,
 * empty list.
 */
inline std::vector<std::string> getListOfGpioPollingFrus(
    const nlohmann::json& i_sysCfgJsonObj) noexcept
{
    std::vector<std::string> l_gpioPollingRequiredFrusList;

    try
    {
        if (i_sysCfgJsonObj.empty())
        {
            throw std::runtime_error("Invalid Parameters");
        }

        if (!i_sysCfgJsonObj.contains("frus"))
        {
            throw std::runtime_error(
                "Missing frus section in system config JSON");
        }

        for (const auto& l_fru : i_sysCfgJsonObj["frus"].items())
        {
            const auto l_fruPath = l_fru.key();

            if (isActionRequired(i_sysCfgJsonObj, l_fruPath, "pollingRequired",
                                 "hotPlugging"))
            {
                if (i_sysCfgJsonObj["frus"][l_fruPath]
                        .at(0)["pollingRequired"]["hotPlugging"]
                        .contains("gpioPresence"))
                {
                    l_gpioPollingRequiredFrusList.push_back(l_fruPath);
                }
            }
        }
    }
    catch (const std::exception& l_ex)
    {
        logging::logMessage("Failed to get list of GPIO polling FRUs, error: " +
                            std::string(l_ex.what()));
    }

    return l_gpioPollingRequiredFrusList;
}

/**
 * @brief Get all related path(s) to update keyword value.
 *
 * Given FRU EEPROM path/Inventory path needs keyword's value update, this API
 * returns tuple of FRU EEPROM path, inventory path and redundant EEPROM path if
 * exists in the system config JSON.
 *
 * Note: If the inventory object path or redundant EEPROM path(s) are not found
 * in the system config JSON, corresponding fields will have empty value in the
 * returning tuple.
 *
 * @param[in] i_sysCfgJsonObj - System config JSON object.
 * @param[in,out] io_vpdPath - Inventory object path or FRU EEPROM path.
 *
 * @return On success returns tuple of EEPROM path, inventory path & redundant
 * path, on failure returns tuple with given input path alone.
 */
inline std::tuple<std::string, std::string, std::string>
    getAllPathsToUpdateKeyword(const nlohmann::json& i_sysCfgJsonObj,
                               std::string io_vpdPath)
{
    types::Path l_inventoryObjPath;
    types::Path l_redundantFruPath;
    try
    {
        if (!i_sysCfgJsonObj.empty())
        {
            // Get hardware path from system config JSON.
            const types::Path l_fruPath =
                jsonUtility::getFruPathFromJson(i_sysCfgJsonObj, io_vpdPath);

            if (!l_fruPath.empty())
            {
                io_vpdPath = l_fruPath;

                // Get inventory object path from system config JSON
                l_inventoryObjPath = jsonUtility::getInventoryObjPathFromJson(
                    i_sysCfgJsonObj, l_fruPath);

                // Get redundant hardware path if present in system config JSON
                l_redundantFruPath =
                    jsonUtility::getRedundantEepromPathFromJson(i_sysCfgJsonObj,
                                                                l_fruPath);
            }
        }
    }
    catch (const std::exception& l_exception)
    {
        logging::logMessage(
            "Failed to get all paths to update keyword value, error " +
            std::string(l_exception.what()));
    }
    return std::make_tuple(io_vpdPath, l_inventoryObjPath, l_redundantFruPath);
}

/**
 * @brief An API to get DBus service name.
 *
 * Given DBus inventory path, this API returns DBus service name if present in
 * the JSON.
 *
 * @param[in] i_sysCfgJsonObj - System config JSON object.
 * @param[in] l_inventoryPath - DBus inventory path.
 *
 * @return On success returns the service name present in the system config
 * JSON, otherwise empty string.
 *
 * Note: Caller has to handle in case of empty string received.
 */
inline std::string getServiceName(const nlohmann::json& i_sysCfgJsonObj,
                                  const std::string& l_inventoryPath)
{
    try
    {
        if (l_inventoryPath.empty())
        {
            throw std::runtime_error("Path parameter is empty.");
        }

        if (!i_sysCfgJsonObj.contains("frus"))
        {
            throw std::runtime_error("Missing frus tag in system config JSON.");
        }

        const nlohmann::json& l_listOfFrus =
            i_sysCfgJsonObj["frus"].get_ref<const nlohmann::json::object_t&>();

        for (const auto& l_frus : l_listOfFrus.items())
        {
            for (const auto& l_inventoryItem : l_frus.value())
            {
                if (l_inventoryPath.compare(l_inventoryItem["inventoryPath"]) ==
                    constants::STR_CMP_SUCCESS)
                {
                    return l_inventoryItem["serviceName"];
                }
            }
        }
        throw std::runtime_error(
            "Inventory path not found in the system config JSON");
    }
    catch (const std::exception& l_exception)
    {
        logging::logMessage(
            "Error while getting DBus service name for given path " +
            l_inventoryPath + ", error: " + std::string(l_exception.what()));
        // TODO:log PEL
    }
    return std::string{};
}

/**
 * @brief An API to check if a FRU is tagged as "powerOffOnly"
 *
 * Given the system config JSON and VPD FRU path, this API checks if the FRU
 * VPD can be collected at Chassis Power Off state only.
 *
 * @param[in] i_sysCfgJsonObj - System config JSON object.
 * @param[in] i_vpdFruPath - EEPROM path.
 * @return - True if FRU VPD can be collected at Chassis Power Off state only.
 *           False otherwise
 */
inline bool isFruPowerOffOnly(const nlohmann::json& i_sysCfgJsonObj,
                              const std::string& i_vpdFruPath)
{
    if (i_vpdFruPath.empty())
    {
        logging::logMessage("FRU path is empty.");
        return false;
    }

    if (!i_sysCfgJsonObj.contains("frus"))
    {
        logging::logMessage("Missing frus tag in system config JSON.");
        return false;
    }

    if (!i_sysCfgJsonObj["frus"].contains(i_vpdFruPath))
    {
        logging::logMessage("JSON object does not contain EEPROM path \'" +
                            i_vpdFruPath + "\'");
        return false;
    }

    return ((i_sysCfgJsonObj["frus"][i_vpdFruPath].at(0))
                .contains("powerOffOnly") &&
            (i_sysCfgJsonObj["frus"][i_vpdFruPath].at(0)["powerOffOnly"]));
}

/**
 * @brief API which tells if the FRU is replaceable at runtime
 *
 * @param[in] i_sysCfgJsonObj - System config JSON object.
 * @param[in] i_vpdFruPath - EEPROM path.
 *
 * @return true if FRU is replaceable at runtime. false otherwise.
 */
inline bool isFruReplaceableAtRuntime(const nlohmann::json& i_sysCfgJsonObj,
                                      const std::string& i_vpdFruPath)
{
    try
    {
        if (i_vpdFruPath.empty())
        {
            throw std::runtime_error("Given FRU path is empty.");
        }

        if (i_sysCfgJsonObj.empty() || (!i_sysCfgJsonObj.contains("frus")))
        {
            throw std::runtime_error("Invalid system config JSON object.");
        }

        return ((i_sysCfgJsonObj["frus"][i_vpdFruPath].at(0))
                    .contains("replaceableAtRuntime") &&
                (i_sysCfgJsonObj["frus"][i_vpdFruPath].at(
                    0)["replaceableAtRuntime"]));
    }
    catch (const std::exception& l_error)
    {
        // TODO: Log PEL
        logging::logMessage(l_error.what());
    }

    return false;
}

/**
 * @brief API which tells if the FRU is replaceable at standby
 *
 * @param[in] i_sysCfgJsonObj - System config JSON object.
 * @param[in] i_vpdFruPath - EEPROM path.
 *
 * @return true if FRU is replaceable at standby. false otherwise.
 */
inline bool isFruReplaceableAtStandby(const nlohmann::json& i_sysCfgJsonObj,
                                      const std::string& i_vpdFruPath)
{
    try
    {
        if (i_vpdFruPath.empty())
        {
            throw std::runtime_error("Given FRU path is empty.");
        }

        if (i_sysCfgJsonObj.empty() || (!i_sysCfgJsonObj.contains("frus")))
        {
            throw std::runtime_error("Invalid system config JSON object.");
        }

        return ((i_sysCfgJsonObj["frus"][i_vpdFruPath].at(0))
                    .contains("replaceableAtStandby") &&
                (i_sysCfgJsonObj["frus"][i_vpdFruPath].at(
                    0)["replaceableAtStandby"]));
    }
    catch (const std::exception& l_error)
    {
        // TODO: Log PEL
        logging::logMessage(l_error.what());
    }

    return false;
}

/**
 * @brief API to get list of FRUs replaceable at standby from JSON.
 *
 * The API will return a vector of FRUs inventory path which are replaceable at
 * standby.
 *
 * @param[in] i_sysCfgJsonObj - System config JSON object.
 *
 * @return - On success, list of FRUs replaceable at standby. On failure, empty
 * vector.
 */
inline std::vector<std::string> getListOfFrusReplaceableAtStandby(
    const nlohmann::json& i_sysCfgJsonObj) noexcept
{
    std::vector<std::string> l_frusReplaceableAtStandby;

    try
    {
        if (!i_sysCfgJsonObj.contains("frus"))
        {
            throw std::runtime_error("Missing frus tag in system config JSON.");
        }

        const nlohmann::json& l_fruList =
            i_sysCfgJsonObj["frus"].get_ref<const nlohmann::json::object_t&>();

        for (const auto& l_fru : l_fruList.items())
        {
            if (i_sysCfgJsonObj["frus"][l_fru.key()].at(0).value(
                    "replaceableAtStandby", false))
            {
                const std::string& l_inventoryObjectPath =
                    i_sysCfgJsonObj["frus"][l_fru.key()].at(0).value(
                        "inventoryPath", "");

                if (!l_inventoryObjectPath.empty())
                {
                    l_frusReplaceableAtStandby.emplace_back(
                        l_inventoryObjectPath);
                }
            }
        }
    }
    catch (const std::exception& l_ex)
    {
        logging::logMessage(
            "Failed to get list of FRUs replaceable at standby, error: " +
            std::string(l_ex.what()));
    }

    return l_frusReplaceableAtStandby;
}

/**
 * @brief API to select powerVS JSON based on system IM.
 *
 * The API selects respective JSON based on system IM, parse it and return the
 * JSON object. Empty JSON will be returned in case of any error. Caller needs
 * to handle empty value.
 *
 * @param[in] i_imValue - IM value of the system.
 * @return Parsed JSON object, empty JSON otherwise.
 */
inline nlohmann::json getPowerVsJson(const types::BinaryVector& i_imValue)
{
    try
    {
        if ((i_imValue.at(0) == constants::HEX_VALUE_50) &&
            (i_imValue.at(1) == constants::HEX_VALUE_00) &&
            (i_imValue.at(2) == constants::HEX_VALUE_30))
        {
            return jsonUtility::getParsedJson(constants::power_vs_50003_json);
        }
        else if (i_imValue.at(0) == constants::HEX_VALUE_50 &&
                 (i_imValue.at(1) == constants::HEX_VALUE_00) &&
                 (i_imValue.at(2) == constants::HEX_VALUE_10))
        {
            return jsonUtility::getParsedJson(constants::power_vs_50001_json);
        }
        return nlohmann::json{};
    }
    catch (const std::exception& l_ex)
    {
        return nlohmann::json{};
    }
}
} // namespace jsonUtility
} // namespace vpd
