#include "config.h"

#include "common_utility.hpp"
#include "defines.hpp"
#include "ibm_vpd_utils.hpp"
#include "ipz_parser.hpp"
#include "keyword_vpd_parser.hpp"
#include "memory_vpd_parser.hpp"
#include "parser_factory.hpp"
#include "vpd_exceptions.hpp"

#include <assert.h>
#include <ctype.h>

#include <CLI/CLI.hpp>
#include <algorithm>
#include <boost/algorithm/string.hpp>
#include <cstdarg>
#include <exception>
#include <filesystem>
#include <fstream>
#include <gpiod.hpp>
#include <iostream>
#include <iterator>
#include <nlohmann/json.hpp>
#include <phosphor-logging/log.hpp>
#include <regex>
#include <thread>

using namespace std;
using namespace openpower::vpd;
using namespace CLI;
using namespace vpd::keyword::parser;
using namespace openpower::vpd::constants;
namespace fs = filesystem;
using json = nlohmann::json;
using namespace openpower::vpd::parser::factory;
using namespace openpower::vpd::inventory;
using namespace openpower::vpd::memory::parser;
using namespace openpower::vpd::parser::interface;
using namespace openpower::vpd::exceptions;
using namespace phosphor::logging;

/**
 * @brief Returns the BMC state
 */
static auto getBMCState()
{
    std::string bmcState;
    try
    {
        auto bus = sdbusplus::bus::new_default();
        auto properties = bus.new_method_call(
            "xyz.openbmc_project.State.BMC", "/xyz/openbmc_project/state/bmc0",
            "org.freedesktop.DBus.Properties", "Get");
        properties.append("xyz.openbmc_project.State.BMC");
        properties.append("CurrentBMCState");
        auto result = bus.call(properties);
        std::variant<std::string> val;
        result.read(val);
        if (auto pVal = std::get_if<std::string>(&val))
        {
            bmcState = *pVal;
        }
    }
    catch (const sdbusplus::exception::SdBusError& e)
    {
        // Ignore any error
        std::cerr << "Failed to get BMC state: " << e.what() << "\n";
    }
    return bmcState;
}

/**
 * @brief Check if the FRU is in the cache
 *
 * Checks if the FRU associated with the supplied D-Bus object path is already
 * on D-Bus. This can be used to test if a VPD collection is required for this
 * FRU. It uses the "xyz.openbmc_project.Inventory.Item, Present" property to
 * determine the presence of a FRU in the cache.
 *
 * @param objectPath - The D-Bus object path without the PIM prefix.
 * @return true if the object exists on D-Bus, false otherwise.
 */
static auto isFruInVpdCache(const std::string& objectPath)
{
    try
    {
        auto bus = sdbusplus::bus::new_default();
        auto invPath = std::string{pimPath} + objectPath;
        auto props = bus.new_method_call(
            "xyz.openbmc_project.Inventory.Manager", invPath.c_str(),
            "org.freedesktop.DBus.Properties", "Get");
        props.append("xyz.openbmc_project.Inventory.Item");
        props.append("Present");
        auto result = bus.call(props);
        std::variant<bool> present;
        result.read(present);
        if (auto pVal = std::get_if<bool>(&present))
        {
            return *pVal;
        }
        return false;
    }
    catch (const sdbusplus::exception::SdBusError& e)
    {
        std::cout << "FRU: " << objectPath << " not in D-Bus\n";
        // Assume not present in case of an error
        return false;
    }
}

/**
 * @brief Check if VPD recollection is needed for the given EEPROM
 *
 * Not all FRUs can be swapped at BMC ready state. This function does the
 * following:
 * -- Check if the FRU is marked as "pluggableAtStandby" OR
 *    "concurrentlyMaintainable". If so, return true.
 * -- Check if we are at BMC NotReady state. If we are, then return true.
 * -- Else check if the FRU is not present in the VPD cache (to cover for VPD
 *    force collection). If not found in the cache, return true.
 * -- Else return false.
 *
 * @param js - JSON Object.
 * @param filePath - The EEPROM file.
 * @return true if collection should be attempted, false otherwise.
 */
static auto needsRecollection(const nlohmann::json& js, const string& filePath)
{
    if (js["frus"][filePath].at(0).value("pluggableAtStandby", false) ||
        js["frus"][filePath].at(0).value("concurrentlyMaintainable", false))
    {
        return true;
    }
    if (getBMCState() == "xyz.openbmc_project.State.BMC.BMCState.NotReady")
    {
        return true;
    }
    if (!isFruInVpdCache(js["frus"][filePath].at(0).value("inventoryPath", "")))
    {
        return true;
    }
    return false;
}

/**
 * @brief Expands location codes
 */
static auto expandLocationCode(const string& unexpanded, const Parsed& vpdMap,
                               bool isSystemVpd)
{
    auto expanded{unexpanded};
    static constexpr auto SYSTEM_OBJECT = "/system/chassis/motherboard";
    static constexpr auto VCEN_IF = "com.ibm.ipzvpd.VCEN";
    static constexpr auto VSYS_IF = "com.ibm.ipzvpd.VSYS";
    size_t idx = expanded.find("fcs");
    try
    {
        if (idx != string::npos)
        {
            string fc{};
            string se{};
            if (isSystemVpd)
            {
                const auto& fcData = vpdMap.at("VCEN").at("FC");
                const auto& seData = vpdMap.at("VCEN").at("SE");
                fc = string(fcData.data(), fcData.size());
                se = string(seData.data(), seData.size());
            }
            else
            {
                fc = readBusProperty(SYSTEM_OBJECT, VCEN_IF, "FC");
                se = readBusProperty(SYSTEM_OBJECT, VCEN_IF, "SE");
            }

            // TODO: See if ND0 can be placed in the JSON
            expanded.replace(idx, 3, fc.substr(0, 4) + ".ND0." + se);
        }
        else
        {
            idx = expanded.find("mts");
            if (idx != string::npos)
            {
                string mt{};
                string se{};
                if (isSystemVpd)
                {
                    const auto& mtData = vpdMap.at("VSYS").at("TM");
                    const auto& seData = vpdMap.at("VSYS").at("SE");
                    mt = string(mtData.data(), mtData.size());
                    se = string(seData.data(), seData.size());
                }
                else
                {
                    mt = readBusProperty(SYSTEM_OBJECT, VSYS_IF, "TM");
                    se = readBusProperty(SYSTEM_OBJECT, VSYS_IF, "SE");
                }

                replace(mt.begin(), mt.end(), '-', '.');
                expanded.replace(idx, 3, mt + "." + se);
            }
        }
    }
    catch (const exception& e)
    {
        cerr << "Failed to expand location code with exception: " << e.what()
             << "\n";
    }
    return expanded;
}

/**
 * @brief Populate FRU specific interfaces.
 *
 * This is a common method which handles both
 * ipz and keyword specific interfaces thus,
 * reducing the code redundancy.
 * @param[in] map - Reference to the innermost keyword-value map.
 * @param[in] preIntrStr - Reference to the interface string.
 * @param[out] interfaces - Reference to interface map.
 */
template <typename T>
static void populateFruSpecificInterfaces(const T& map,
                                          const string& preIntrStr,
                                          inventory::InterfaceMap& interfaces)
{
    inventory::PropertyMap prop;

    for (const auto& kwVal : map)
    {
        auto kw = kwVal.first;

        if (kw[0] == '#')
        {
            kw = string("PD_") + kw[1];
        }
        else if (isdigit(kw[0]))
        {
            kw = string("N_") + kw;
        }
        if constexpr (is_same<T, KeywordVpdMap>::value)
        {
            if (get_if<Binary>(&kwVal.second))
            {
                Binary vec(get_if<Binary>(&kwVal.second)->begin(),
                           get_if<Binary>(&kwVal.second)->end());
                prop.emplace(move(kw), move(vec));
            }
            else
            {
                if (kw == "MemorySizeInKB")
                {
                    inventory::PropertyMap memProp;
                    auto memVal = get_if<size_t>(&kwVal.second);
                    if (memVal)
                    {
                        memProp.emplace(move(kw),
                                        ((*memVal) * CONVERT_MB_TO_KB));
                        interfaces.emplace(
                            "xyz.openbmc_project.Inventory.Item.Dimm",
                            move(memProp));
                    }
                    else
                    {
                        cerr << "MemorySizeInKB value not found in vpd map\n";
                    }
                }
            }
        }
        else
        {
            Binary vec(kwVal.second.begin(), kwVal.second.end());
            prop.emplace(move(kw), move(vec));
        }
    }

    interfaces.emplace(preIntrStr, move(prop));
}

/**
 * @brief Populate Interfaces.
 *
 * This method populates common and extra interfaces to dbus.
 * @param[in] js - json object
 * @param[out] interfaces - Reference to interface map
 * @param[in] vpdMap - Reference to the parsed vpd map.
 * @param[in] isSystemVpd - Denotes whether we are collecting the system VPD.
 */
template <typename T>
static void populateInterfaces(const nlohmann::json& js,
                               inventory::InterfaceMap& interfaces,
                               const T& vpdMap, bool isSystemVpd)
{
    for (const auto& ifs : js.items())
    {
        string inf = ifs.key();
        inventory::PropertyMap props;

        for (const auto& itr : ifs.value().items())
        {
            const string& busProp = itr.key();

            if (itr.value().is_boolean())
            {
                props.emplace(busProp, itr.value().get<bool>());
            }
            else if (itr.value().is_string())
            {
                if (busProp == "LocationCode" && inf == IBM_LOCATION_CODE_INF)
                {
                    std::string prop;
                    if constexpr (is_same<T, Parsed>::value)
                    {
                        // TODO deprecate the com.ibm interface later
                        prop = expandLocationCode(itr.value().get<string>(),
                                                  vpdMap, isSystemVpd);
                    }
                    else if constexpr (is_same<T, KeywordVpdMap>::value)
                    {
                        // Send empty Parsed object to expandLocationCode api.
                        prop = expandLocationCode(itr.value().get<string>(),
                                                  Parsed{}, false);
                    }
                    props.emplace(busProp, prop);
                    interfaces.emplace(XYZ_LOCATION_CODE_INF, props);
                    interfaces.emplace(IBM_LOCATION_CODE_INF, props);
                }
                else
                {
                    props.emplace(busProp, itr.value().get<string>());
                }
            }
            else if (itr.value().is_array())
            {
                try
                {
                    props.emplace(busProp, itr.value().get<Binary>());
                }
                catch (const nlohmann::detail::type_error& e)
                {
                    std::cerr << "Type exception: " << e.what() << "\n";
                    // Ignore any type errors
                }
            }
            else if (itr.value().is_object())
            {
                const string& rec = itr.value().value("recordName", "");
                const string& kw = itr.value().value("keywordName", "");
                const string& encoding = itr.value().value("encoding", "");

                if constexpr (is_same<T, Parsed>::value)
                {
                    if (!rec.empty() && !kw.empty() && vpdMap.count(rec) &&
                        vpdMap.at(rec).count(kw))
                    {
                        auto encoded =
                            encodeKeyword(vpdMap.at(rec).at(kw), encoding);
                        props.emplace(busProp, encoded);
                    }
                }
                else if constexpr (is_same<T, KeywordVpdMap>::value)
                {
                    if (!kw.empty() && vpdMap.count(kw))
                    {
                        auto kwValue = get_if<Binary>(&vpdMap.at(kw));
                        auto uintValue = get_if<size_t>(&vpdMap.at(kw));

                        if (kwValue)
                        {
                            auto prop =
                                string((*kwValue).begin(), (*kwValue).end());

                            auto encoded = encodeKeyword(prop, encoding);

                            props.emplace(busProp, encoded);
                        }
                        else if (uintValue)
                        {
                            props.emplace(busProp, *uintValue);
                        }
                    }
                }
            }
            else if (itr.value().is_number())
            {
                // For now assume the value is a size_t.  In the future it would
                // be nice to come up with a way to get the type from the JSON.
                props.emplace(busProp, itr.value().get<size_t>());
            }
        }
        insertOrMerge(interfaces, inf, move(props));
    }
}

/**
 * @brief This API checks if this FRU is pcie_devices. If yes then it further
 *        checks whether it is PASS1 planar.
 */
static bool isThisPcieOnPass1planar(const nlohmann::json& js,
                                    const string& file)
{
    auto isThisPCIeDev = false;
    auto isPASS1 = false;

    // Check if it is a PCIE device
    if (js["frus"].find(file) != js["frus"].end())
    {
        if ((js["frus"][file].at(0).find("extraInterfaces") !=
             js["frus"][file].at(0).end()))
        {
            if (js["frus"][file].at(0)["extraInterfaces"].find(
                    "xyz.openbmc_project.Inventory.Item.PCIeDevice") !=
                js["frus"][file].at(0)["extraInterfaces"].end())
            {
                isThisPCIeDev = true;
            }
        }
    }

    if (isThisPCIeDev)
    {
        // Collect HW version and SystemType to know if it is PASS1 planar.
        auto bus = sdbusplus::bus::new_default();
        auto property1 = bus.new_method_call(
            INVENTORY_MANAGER_SERVICE,
            "/xyz/openbmc_project/inventory/system/chassis/motherboard",
            "org.freedesktop.DBus.Properties", "Get");
        property1.append("com.ibm.ipzvpd.VINI");
        property1.append("HW");
        auto result1 = bus.call(property1);
        inventory::Value hwVal;
        result1.read(hwVal);

        // SystemType
        auto property2 = bus.new_method_call(
            INVENTORY_MANAGER_SERVICE,
            "/xyz/openbmc_project/inventory/system/chassis/motherboard",
            "org.freedesktop.DBus.Properties", "Get");
        property2.append("com.ibm.ipzvpd.VSBP");
        property2.append("IM");
        auto result2 = bus.call(property2);
        inventory::Value imVal;
        result2.read(imVal);

        auto pVal1 = get_if<Binary>(&hwVal);
        auto pVal2 = get_if<Binary>(&imVal);

        if (pVal1 && pVal2)
        {
            auto hwVersion = *pVal1;
            auto systemType = *pVal2;

            // IM kw for Everest
            Binary everestSystem{80, 00, 48, 00};

            if (systemType == everestSystem)
            {
                if (hwVersion[1] < 21)
                {
                    isPASS1 = true;
                }
            }
            else if (hwVersion[1] < 2)
            {
                isPASS1 = true;
            }
        }
    }

    return (isThisPCIeDev && isPASS1);
}

/** Performs any pre-action needed to get the FRU setup for collection.
 *
 * @param[in] json - json object
 * @param[in] file - eeprom file path
 */
static void preAction(const nlohmann::json& json, const string& file)
{
    if ((json["frus"][file].at(0)).find("preAction") ==
        json["frus"][file].at(0).end())
    {
        return;
    }

    if (executePreAction(json, file))
    {
        if (json["frus"][file].at(0).find("devAddress") !=
            json["frus"][file].at(0).end())
        {
            // Now bind the device
            string bind = json["frus"][file].at(0).value("devAddress", "");
            cout << "Binding device " << bind << endl;
            string bindCmd = string("echo \"") + bind +
                             string("\" > /sys/bus/i2c/drivers/at24/bind");
            cout << bindCmd << endl;
            executeCmd(bindCmd);

            // Check if device showed up (test for file)
            if (!fs::exists(file))
            {
                cerr << "EEPROM " << file
                     << " does not exist. Take failure action" << endl;
                // If not, then take failure postAction
                executePostFailAction(json, file);
            }
        }
        else
        {
            // missing required informations
            cerr
                << "VPD inventory JSON missing basic informations of preAction "
                   "for this FRU : ["
                << file << "]. Executing executePostFailAction." << endl;

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

/**
 * @brief Fills the Decorator.AssetTag property into the interfaces map
 *
 * This function should only be called in cases where we did not find a JSON
 * symlink. A missing symlink in /var/lib will be considered as a factory reset
 * and this function will be used to default the AssetTag property.
 *
 * @param interfaces A possibly pre-populated map of inetrfaces to properties.
 * @param vpdMap A VPD map of the system VPD data.
 */
static void fillAssetTag(inventory::InterfaceMap& interfaces,
                         const Parsed& vpdMap)
{
    // Read the system serial number and MTM
    // Default asset tag is Server-MTM-System Serial
    inventory::Interface assetIntf{
        "xyz.openbmc_project.Inventory.Decorator.AssetTag"};
    inventory::PropertyMap assetTagProps;
    std::string defaultAssetTag =
        std::string{"Server-"} + getKwVal(vpdMap, "VSYS", "TM") +
        std::string{"-"} + getKwVal(vpdMap, "VSYS", "SE");
    assetTagProps.emplace("AssetTag", defaultAssetTag);
    insertOrMerge(interfaces, assetIntf, std::move(assetTagProps));
}

/**
 * @brief Set certain one time properties in the inventory
 * Use this function to insert the Functional and Enabled properties into the
 * inventory map. This function first checks if the object in question already
 * has these properties hosted on D-Bus, if the property is already there, it is
 * not modified, hence the name "one time". If the property is not already
 * present, it will be added to the map with a suitable default value (true for
 * Functional and false for Enabled)
 *
 * @param[in] object - The inventory D-Bus obejct without the inventory prefix.
 * @param[inout] interfaces - Reference to a map of inventory interfaces to
 * which the properties will be attached.
 */
static void setOneTimeProperties(const std::string& object,
                                 inventory::InterfaceMap& interfaces)
{
    auto bus = sdbusplus::bus::new_default();
    auto objectPath = INVENTORY_PATH + object;
    auto prop = bus.new_method_call("xyz.openbmc_project.Inventory.Manager",
                                    objectPath.c_str(),
                                    "org.freedesktop.DBus.Properties", "Get");
    prop.append("xyz.openbmc_project.State.Decorator.OperationalStatus");
    prop.append("Functional");
    try
    {
        auto result = bus.call(prop);
    }
    catch (const sdbusplus::exception::SdBusError& e)
    {
        // Treat as property unavailable
        inventory::PropertyMap prop;
        prop.emplace("Functional", true);
        interfaces.emplace(
            "xyz.openbmc_project.State.Decorator.OperationalStatus",
            move(prop));
    }
    prop = bus.new_method_call("xyz.openbmc_project.Inventory.Manager",
                               objectPath.c_str(),
                               "org.freedesktop.DBus.Properties", "Get");
    prop.append("xyz.openbmc_project.Object.Enable");
    prop.append("Enabled");
    try
    {
        auto result = bus.call(prop);
    }
    catch (const sdbusplus::exception::SdBusError& e)
    {
        // Treat as property unavailable
        inventory::PropertyMap prop;
        prop.emplace("Enabled", false);
        interfaces.emplace("xyz.openbmc_project.Object.Enable", move(prop));
    }
}

/**
 * @brief Prime the Inventory
 * Prime the inventory by populating only the location code,
 * type interface and the inventory object for the frus
 * which are not system vpd fru.
 *
 * @param[in] jsObject - Reference to vpd inventory json object
 * @param[in] vpdMap -  Reference to the parsed vpd map
 *
 * @returns Map of items in extraInterface.
 */
template <typename T>
inventory::ObjectMap primeInventory(const nlohmann::json& jsObject,
                                    const T& vpdMap)
{
    inventory::ObjectMap objects;

    for (auto& itemFRUS : jsObject["frus"].items())
    {
        for (auto& itemEEPROM : itemFRUS.value())
        {
            // Take pre actions if needed
            if (itemEEPROM.find("preAction") != itemEEPROM.end())
            {
                preAction(jsObject, itemFRUS.key());
            }

            inventory::InterfaceMap interfaces;
            inventory::Object object(itemEEPROM.at("inventoryPath"));

            if ((itemFRUS.key() != systemVpdFilePath) &&
                !itemEEPROM.value("noprime", false))
            {
                inventory::PropertyMap presProp;

                // Do not populate Present property for frus whose
                // synthesized=true. synthesized=true says the fru is owned by
                // some other component and not by vpd.
                if (!itemEEPROM.value("synthesized", false))
                {
                    presProp.emplace("Present", false);
                    interfaces.emplace("xyz.openbmc_project.Inventory.Item",
                                       presProp);
                }
                setOneTimeProperties(object, interfaces);
                if (itemEEPROM.find("extraInterfaces") != itemEEPROM.end())
                {
                    for (const auto& eI : itemEEPROM["extraInterfaces"].items())
                    {
                        inventory::PropertyMap props;
                        if (eI.key() == IBM_LOCATION_CODE_INF)
                        {
                            if constexpr (std::is_same<T, Parsed>::value)
                            {
                                for (auto& lC : eI.value().items())
                                {
                                    auto propVal = expandLocationCode(
                                        lC.value().get<string>(), vpdMap, true);

                                    props.emplace(move(lC.key()),
                                                  move(propVal));
                                    interfaces.emplace(XYZ_LOCATION_CODE_INF,
                                                       props);
                                    interfaces.emplace(move(eI.key()),
                                                       move(props));
                                }
                            }
                        }
                        else if (eI.key().find("Inventory.Item.") !=
                                 string::npos)
                        {
                            interfaces.emplace(move(eI.key()), move(props));
                        }
                        else if (eI.key() ==
                                 "xyz.openbmc_project.Inventory.Item")
                        {
                            for (auto& val : eI.value().items())
                            {
                                if (val.key() == "PrettyName")
                                {
                                    presProp.emplace(val.key(),
                                                     val.value().get<string>());
                                }
                            }
                            // Use insert_or_assign here as we may already have
                            // inserted the present property only earlier in
                            // this function under this same interface.
                            interfaces.insert_or_assign(eI.key(),
                                                        move(presProp));
                        }
                    }
                }
                objects.emplace(move(object), move(interfaces));
            }
        }
    }
    return objects;
}

/**
 * @brief This API executes command to set environment variable
 *        And then reboot the system
 * @param[in] key   -env key to set new value
 * @param[in] value -value to set.
 */
void setEnvAndReboot(const string& key, const string& value)
{
    // set env and reboot and break.
    executeCmd("/sbin/fw_setenv", key, value);
    log<level::INFO>("Rebooting BMC to pick up new device tree");
    // make dbus call to reboot
    auto bus = sdbusplus::bus::new_default_system();
    auto method = bus.new_method_call(
        "org.freedesktop.systemd1", "/org/freedesktop/systemd1",
        "org.freedesktop.systemd1.Manager", "Reboot");
    bus.call_noreply(method);
}

/*
 * @brief This API checks for env var fitconfig.
 *        If not initialised OR updated as per the current system type,
 *        update this env var and reboot the system.
 *
 * @param[in] systemType IM kwd in vpd tells about which system type it is.
 * */
void setDevTreeEnv(const string& systemType)
{
    // Init with default dtb
    string newDeviceTree = "conf-aspeed-bmc-ibm-rainier-p1.dtb";
    static const deviceTreeMap deviceTreeSystemTypeMap = {
        {RAINIER_2U, "conf-aspeed-bmc-ibm-rainier-p1.dtb"},
        {RAINIER_2U_V2, "conf-aspeed-bmc-ibm-rainier.dtb"},
        {RAINIER_4U, "conf-aspeed-bmc-ibm-rainier-4u-p1.dtb"},
        {RAINIER_4U_V2, "conf-aspeed-bmc-ibm-rainier-4u.dtb"},
        {RAINIER_1S4U, "conf-aspeed-bmc-ibm-rainier-1s4u.dtb"},
        {EVEREST, "conf-aspeed-bmc-ibm-everest.dtb"},
        {EVEREST_V2, "conf-aspeed-bmc-ibm-everest.dtb"}};

    if (deviceTreeSystemTypeMap.find(systemType) !=
        deviceTreeSystemTypeMap.end())
    {
        newDeviceTree = deviceTreeSystemTypeMap.at(systemType);
    }
    else
    {
        // System type not supported
        string err = "This System type not found/supported in dtb table " +
                     systemType +
                     ".Please check the HW and IM keywords in the system "
                     "VPD.Breaking...";

        // map to hold additional data in case of logging pel
        PelAdditionalData additionalData{};
        additionalData.emplace("DESCRIPTION", err);
        createPEL(additionalData, PelSeverity::WARNING,
                  errIntfForInvalidSystemType);
        exit(-1);
    }

    string readVarValue;
    bool envVarFound = false;

    vector<string> output = executeCmd("/sbin/fw_printenv");
    for (const auto& entry : output)
    {
        size_t pos = entry.find("=");
        string key = entry.substr(0, pos);
        if (key != "fitconfig")
        {
            continue;
        }

        envVarFound = true;
        if (pos + 1 < entry.size())
        {
            readVarValue = entry.substr(pos + 1);
            if (readVarValue.find(newDeviceTree) != string::npos)
            {
                // fitconfig is Updated. No action needed
                break;
            }
        }
        // set env and reboot and break.
        setEnvAndReboot(key, newDeviceTree);
        exit(0);
    }

    // check If env var Not found
    if (!envVarFound)
    {
        setEnvAndReboot("fitconfig", newDeviceTree);
    }
}

/**
 * @brief API to check if we need to restore system VPD
 * This functionality is only applicable for IPZ VPD data.
 * @param[in] vpdMap - IPZ vpd map
 * @param[in] objectPath - Object path for the FRU
 */
void restoreSystemVPD(Parsed& vpdMap, const string& objectPath)
{
    for (const auto& systemRecKwdPair : svpdKwdMap)
    {
        auto it = vpdMap.find(systemRecKwdPair.first);

        // check if record is found in map we got by parser
        if (it != vpdMap.end())
        {
            const auto& kwdListForRecord = systemRecKwdPair.second;
            for (const auto& keyword : kwdListForRecord)
            {
                DbusPropertyMap& kwdValMap = it->second;
                auto iterator = kwdValMap.find(keyword);

                if (iterator != kwdValMap.end())
                {
                    string& kwdValue = iterator->second;

                    // check bus data
                    const string& recordName = systemRecKwdPair.first;
                    const string& busValue = readBusProperty(
                        objectPath, ipzVpdInf + recordName, keyword);

                    std::string defaultValue{' '};

                    // Explicit check for D0 is required as this keyword will
                    // never be blank and 0x00 should be treated as no value in
                    // this case.
                    if (recordName == "UTIL" && keyword == "D0")
                    {
                        // default value of kwd D0 is 0x00. This kwd will never
                        // be blank.
                        defaultValue = '\0';
                    }

                    if (busValue.find_first_not_of(defaultValue) !=
                        string::npos)
                    {
                        if (kwdValue.find_first_not_of(defaultValue) !=
                            string::npos)
                        {
                            // both the data are present, check for mismatch
                            if (busValue != kwdValue)
                            {
                                string errMsg = "VPD data mismatch on cache "
                                                "and hardware for record: ";
                                errMsg += (*it).first;
                                errMsg += " and keyword: ";
                                errMsg += keyword;

                                // data mismatch
                                PelAdditionalData additionalData;
                                additionalData.emplace("CALLOUT_INVENTORY_PATH",
                                                       objectPath);

                                additionalData.emplace("DESCRIPTION", errMsg);

                                createPEL(additionalData, PelSeverity::WARNING,
                                          errIntfForInvalidVPD);
                            }
                        }
                        else
                        {
                            // implies hardware data is blank
                            // update the map
                            Binary busData(busValue.begin(), busValue.end());

                            // update the map as well, so that cache data is not
                            // updated as blank while populating VPD map on Dbus
                            // in populateDBus Api
                            kwdValue = busValue;
                        }
                    }
                    else if (kwdValue.find_first_not_of(defaultValue) ==
                             string::npos)
                    {
                        string errMsg = "VPD is blank on both cache and "
                                        "hardware for record: ";
                        errMsg += (*it).first;
                        errMsg += " and keyword: ";
                        errMsg += keyword;
                        errMsg += ". SSR need to update hardware VPD.";

                        // both the data are blanks, log PEL
                        PelAdditionalData additionalData;
                        additionalData.emplace("CALLOUT_INVENTORY_PATH",
                                               objectPath);

                        additionalData.emplace("DESCRIPTION", errMsg);

                        // log PEL TODO: Block IPL
                        createPEL(additionalData, PelSeverity::ERROR,
                                  errIntfForBlankSystemVPD);
                        continue;
                    }
                }
            }
        }
    }
}

/**
 * @brief This checks for is this FRU a processor
 *        And if yes, then checks for is this primary
 *
 * @param[in] js- vpd json to get the information about this FRU
 * @param[in] filePath- FRU vpd
 *
 * @return true/false
 */
bool isThisPrimaryProcessor(nlohmann::json& js, const string& filePath)
{
    bool isProcessor = false;
    bool isPrimary = false;

    for (const auto& item : js["frus"][filePath])
    {
        if (item.find("extraInterfaces") != item.end())
        {
            for (const auto& eI : item["extraInterfaces"].items())
            {
                if (eI.key().find("Inventory.Item.Cpu") != string::npos)
                {
                    isProcessor = true;
                }
            }
        }

        if (isProcessor)
        {
            string cpuType = item.value("cpuType", "");
            if (cpuType == "primary")
            {
                isPrimary = true;
            }
        }
    }

    return (isProcessor && isPrimary);
}

/**
 * @brief This finds DIMM vpd in vpd json and enables them by binding the device
 *        driver
 * @param[in] js- vpd json to iterate through and take action if it is DIMM
 */
void doEnableAllDimms(nlohmann::json& js)
{
    // iterate over each fru
    for (const auto& eachFru : js["frus"].items())
    {
        // skip the driver binding if eeprom already exists
        if (fs::exists(eachFru.key()))
        {
            continue;
        }

        for (const auto& eachInventory : eachFru.value())
        {
            if (eachInventory.find("extraInterfaces") != eachInventory.end())
            {
                for (const auto& eI : eachInventory["extraInterfaces"].items())
                {
                    if (eI.key().find("Inventory.Item.Dimm") != string::npos)
                    {
                        string dimmVpd = eachFru.key();
                        // fetch it from
                        // "/sys/bus/i2c/drivers/at24/414-0050/eeprom"

                        regex matchPatern("([0-9]+-[0-9]{4})");
                        smatch matchFound;
                        if (regex_search(dimmVpd, matchFound, matchPatern))
                        {
                            vector<string> i2cReg;
                            boost::split(i2cReg, matchFound.str(0),
                                         boost::is_any_of("-"));

                            // remove 0s from begining
                            const regex pattern("^0+(?!$)");
                            for (auto& i : i2cReg)
                            {
                                i = regex_replace(i, pattern, "");
                            }

                            if (i2cReg.size() == 2)
                            {
                                // echo 24c32 0x50 >
                                // /sys/bus/i2c/devices/i2c-16/new_device
                                string cmnd = "echo 24c32 0x" + i2cReg[1] +
                                              " > /sys/bus/i2c/devices/i2c-" +
                                              i2cReg[0] + "/new_device";

                                executeCmd(cmnd);
                            }
                        }
                    }
                }
            }
        }
    }
}

/**
 * @brief Check if the given CPU is an IO only chip.
 * The CPU is termed as IO, whose all of the cores are bad and can never be
 * used. Those CPU chips can be used for IO purpose like connecting PCIe devices
 * etc., The CPU whose every cores are bad, can be identified from the CP00
 * record's PG keyword, only if all of the 8 EQs' value equals 0xE7F9FF. (1EQ
 * has 4 cores grouped together by sharing its cache memory.)
 * @param [in] pgKeyword - PG Keyword of CPU.
 * @return true if the given cpu is an IO, false otherwise.
 */
static bool isCPUIOGoodOnly(const string& pgKeyword)
{
    const unsigned char io[] = {0xE7, 0xF9, 0xFF, 0xE7, 0xF9, 0xFF, 0xE7, 0xF9,
                                0xFF, 0xE7, 0xF9, 0xFF, 0xE7, 0xF9, 0xFF, 0xE7,
                                0xF9, 0xFF, 0xE7, 0xF9, 0xFF, 0xE7, 0xF9, 0xFF};
    // EQ0 index (in PG keyword) starts at 97 (with offset starting from 0).
    // Each EQ carries 3 bytes of data. Totally there are 8 EQs. If all EQs'
    // value equals 0xE7F9FF, then the cpu has no good cores and its treated as
    // IO.
    if (memcmp(io, pgKeyword.data() + 97, 24) == 0)
    {
        return true;
    }

    // The CPU is not an IO
    return false;
}

/**
 * @brief Populate Dbus.
 * This method invokes all the populateInterface functions
 * and notifies PIM about dbus object.
 * @param[in] vpdMap - Either IPZ vpd map or Keyword vpd map based on the
 * input.
 * @param[in] js - Inventory json object
 * @param[in] filePath - Path of the vpd file
 * @param[in] preIntrStr - Interface string
 */
template <typename T>
static void populateDbus(T& vpdMap, nlohmann::json& js, const string& filePath)
{
    inventory::InterfaceMap interfaces;
    inventory::ObjectMap objects;
    inventory::PropertyMap prop;
    string ccinFromVpd;

    bool isSystemVpd = (filePath == systemVpdFilePath);
    if constexpr (is_same<T, Parsed>::value)
    {
        ccinFromVpd = getKwVal(vpdMap, "VINI", "CC");
        transform(ccinFromVpd.begin(), ccinFromVpd.end(), ccinFromVpd.begin(),
                  ::toupper);

        if (isSystemVpd)
        {
            std::vector<std::string> interfaces = {motherBoardInterface};
            // call mapper to check for object path creation
            MapperResponse subTree =
                getObjectSubtreeForInterfaces(pimPath, 0, interfaces);
            string mboardPath =
                js["frus"][filePath].at(0).value("inventoryPath", "");

            // Attempt system VPD restore if we have a motherboard
            // object in the inventory.
            if ((subTree.size() != 0) &&
                (subTree.find(pimPath + mboardPath) != subTree.end()))
            {
                restoreSystemVPD(vpdMap, mboardPath);
            }
            else
            {
                log<level::ERR>("No object path found");
            }
        }
        else
        {
            // check if it is processor vpd.
            auto isPrimaryCpu = isThisPrimaryProcessor(js, filePath);

            if (isPrimaryCpu)
            {
                auto ddVersion = getKwVal(vpdMap, "CRP0", "DD");

                auto chipVersion = atoi(ddVersion.substr(1, 2).c_str());

                if (chipVersion >= 2)
                {
                    doEnableAllDimms(js);
                    // Sleep for a few seconds to let the DIMM parses start
                    using namespace std::chrono_literals;
                    std::this_thread::sleep_for(5s);
                }
            }
        }
    }

    auto processFactoryReset = false;

    if (isSystemVpd)
    {
        string systemJsonName{};
        if constexpr (is_same<T, Parsed>::value)
        {
            // pick the right system json
            systemJsonName = getSystemsJson(vpdMap);
        }

        fs::path target = systemJsonName;
        fs::path link = INVENTORY_JSON_SYM_LINK;

        // If the symlink does not exist, we treat that as a factory reset
        processFactoryReset = !fs::exists(INVENTORY_JSON_SYM_LINK);

        // Create the directory for hosting the symlink
        fs::create_directories(VPD_FILES_PATH);
        // unlink the symlink previously created (if any)
        remove(INVENTORY_JSON_SYM_LINK);
        // create a new symlink based on the system
        fs::create_symlink(target, link);

        // Reloading the json
        ifstream inventoryJson(link);
        js = json::parse(inventoryJson);
        inventoryJson.close();
    }

    for (const auto& item : js["frus"][filePath])
    {
        const auto& objectPath = item["inventoryPath"];
        sdbusplus::message::object_path object(objectPath);

        vector<string> ccinList;
        if (item.find("ccin") != item.end())
        {
            for (const auto& cc : item["ccin"])
            {
                string ccin = cc;
                transform(ccin.begin(), ccin.end(), ccin.begin(), ::toupper);
                ccinList.push_back(ccin);
            }
        }

        if (!ccinFromVpd.empty() && !ccinList.empty() &&
            (find(ccinList.begin(), ccinList.end(), ccinFromVpd) ==
             ccinList.end()))
        {
            continue;
        }

        if ((isSystemVpd) || (item.value("noprime", false)))
        {

            // Populate one time properties for the system VPD and its sub-frus
            // and for other non-primeable frus.
            // For the remaining FRUs, this will get handled as a part of
            // priming the inventory.
            setOneTimeProperties(objectPath, interfaces);
        }

        // Populate the VPD keywords and the common interfaces only if we
        // are asked to inherit that data from the VPD, else only add the
        // extraInterfaces.
        if (item.value("inherit", true))
        {
            if constexpr (is_same<T, Parsed>::value)
            {
                // Each record in the VPD becomes an interface and all
                // keyword within the record are properties under that
                // interface.
                for (const auto& record : vpdMap)
                {
                    populateFruSpecificInterfaces(
                        record.second, ipzVpdInf + record.first, interfaces);
                }
            }
            else if constexpr (is_same<T, KeywordVpdMap>::value)
            {
                populateFruSpecificInterfaces(vpdMap, kwdVpdInf, interfaces);
            }
            if (js.find("commonInterfaces") != js.end())
            {
                populateInterfaces(js["commonInterfaces"], interfaces, vpdMap,
                                   isSystemVpd);
            }
        }
        else
        {
            // Check if we have been asked to inherit specific record(s)
            if constexpr (is_same<T, Parsed>::value)
            {
                if (item.find("copyRecords") != item.end())
                {
                    for (const auto& record : item["copyRecords"])
                    {
                        const string& recordName = record;
                        if (vpdMap.find(recordName) != vpdMap.end())
                        {
                            populateFruSpecificInterfaces(
                                vpdMap.at(recordName), ipzVpdInf + recordName,
                                interfaces);
                        }
                    }
                }
            }
        }
        // Populate interfaces and properties that are common to every FRU
        // and additional interface that might be defined on a per-FRU
        // basis.
        if (item.find("extraInterfaces") != item.end())
        {
            populateInterfaces(item["extraInterfaces"], interfaces, vpdMap,
                               isSystemVpd);
            if constexpr (is_same<T, Parsed>::value)
            {
                if (item["extraInterfaces"].find(
                        "xyz.openbmc_project.Inventory.Item.Cpu") !=
                    item["extraInterfaces"].end())
                {
                    if (isCPUIOGoodOnly(getKwVal(vpdMap, "CP00", "PG")))
                    {
                        interfaces[invItemIntf]["PrettyName"] = "IO Module";
                    }
                }
            }
        }

        // embedded property(true or false) says whether the subfru is embedded
        // into the parent fru (or) not. VPD sets Present property only for
        // embedded frus. If the subfru is not an embedded FRU, the subfru may
        // or may not be physically present. Those non embedded frus will always
        // have Present=false irrespective of its physical presence or absence.
        // Eg: nvme drive in nvme slot is not an embedded FRU. So don't set
        // Present to true for such sub frus.
        // Eg: ethernet port is embedded into bmc card. So set Present to true
        // for such sub frus. Also donot populate present property for embedded
        // subfru which is synthesized. Currently there is no subfru which are
        // both embedded and synthesized. But still the case is handled here.
        if ((item.value("embedded", true)) &&
            (!item.value("synthesized", false)))
        {
            inventory::PropertyMap presProp;
            presProp.emplace("Present", true);
            insertOrMerge(interfaces, invItemIntf, move(presProp));
        }

        if constexpr (is_same<T, Parsed>::value)
        {
            // Restore asset tag, if needed
            if (processFactoryReset && objectPath == "/system")
            {
                fillAssetTag(interfaces, vpdMap);
            }
        }

        objects.emplace(move(object), move(interfaces));
    }

    if (isSystemVpd)
    {
        inventory::ObjectMap primeObject = primeInventory(js, vpdMap);
        objects.insert(primeObject.begin(), primeObject.end());

        // set the U-boot environment variable for device-tree
        if constexpr (is_same<T, Parsed>::value)
        {
            setDevTreeEnv(fs::path(getSystemsJson(vpdMap)).filename());
        }
    }

    // Notify PIM
    common::utility::callPIM(move(objects));
}

int main(int argc, char** argv)
{
    int rc = 0;
    json js{};
    Binary vpdVector{};
    string file{};
    // map to hold additional data in case of logging pel
    PelAdditionalData additionalData{};

    // this is needed to hold base fru inventory path in case there is ECC or
    // vpd exception while parsing the file
    std::string baseFruInventoryPath = {};

    // severity for PEL
    PelSeverity pelSeverity = PelSeverity::WARNING;

    try
    {
        App app{"ibm-read-vpd - App to read IPZ format VPD, parse it and store "
                "in DBUS"};

        app.add_option("-f, --file", file, "File containing VPD (IPZ/KEYWORD)")
            ->required();

        CLI11_PARSE(app, argc, argv);

        // PEL severity should be ERROR in case of any system VPD failure
        if (file == systemVpdFilePath)
        {
            pelSeverity = PelSeverity::ERROR;
        }

        auto jsonToParse = INVENTORY_JSON_DEFAULT;

        // If the symlink exists, it means it has been setup for us, switch the
        // path
        if (fs::exists(INVENTORY_JSON_SYM_LINK))
        {
            jsonToParse = INVENTORY_JSON_SYM_LINK;
        }

        // Make sure that the file path we get is for a supported EEPROM
        ifstream inventoryJson(jsonToParse);
        if (!inventoryJson)
        {
            throw(VpdJsonException("Failed to access Json path", jsonToParse));
        }

        try
        {
            js = json::parse(inventoryJson);
        }
        catch (const json::parse_error& ex)
        {
            throw(VpdJsonException("Json parsing failed", jsonToParse));
        }

        // Do we have the mandatory "frus" section?
        if (js.find("frus") == js.end())
        {
            throw(VpdJsonException("FRUs section not found in JSON",
                                   jsonToParse));
        }

        // Check if it's a udev path - patterned as(/ahb/ahb:apb/ahb:apb:bus@)
        if (file.find("/ahb:apb") != string::npos)
        {
            // Translate udev path to a generic /sys/bus/.. file path.
            udevToGenericPath(file);

            if ((js["frus"].find(file) != js["frus"].end()) &&
                (file == systemVpdFilePath))
            {
                // We have already collected system VPD, skip.
                return 0;
            }
        }

        if (file.empty())
        {
            cerr << "The EEPROM path <" << file << "> is not valid.";
            return 0;
        }
        if (js["frus"].find(file) == js["frus"].end())
        {
            return 0;
        }

        if (!fs::exists(file))
        {
            cout << "Device path: " << file
                 << " does not exist. Spurious udev event? Exiting." << endl;
            return 0;
        }

        baseFruInventoryPath = js["frus"][file][0]["inventoryPath"];
        // Check if we can read the VPD file based on the power state
        // We skip reading VPD when the power is ON in two scenarios:
        // 1) The eeprom we are trying to read is that of the system VPD and the
        // JSON symlink is already setup (the symlink's existence tells us we
        // are not coming out of a factory reset)
        // 2) The JSON tells us that the FRU EEPROM cannot be
        // read when we are powered ON.
        if (js["frus"][file].at(0).value("powerOffOnly", false) ||
            (file == systemVpdFilePath && fs::exists(INVENTORY_JSON_SYM_LINK)))
        {
            if ("xyz.openbmc_project.State.Chassis.PowerState.On" ==
                getPowerState())
            {
                cout << "This VPD cannot be read when power is ON" << endl;
                return 0;
            }
        }

        // Check if this VPD should be recollected at all
        if (!needsRecollection(js, file))
        {
            cout << "Skip VPD recollection for: " << file << endl;
            return 0;
        }

        try
        {
            vpdVector = getVpdDataInVector(js, file);
            ParserInterface* parser = ParserFactory::getParser(vpdVector);
            variant<KeywordVpdMap, Store> parseResult;
            parseResult = parser->parse();

            if (auto pVal = get_if<Store>(&parseResult))
            {
                populateDbus(pVal->getVpdMap(), js, file);
            }
            else if (auto pVal = get_if<KeywordVpdMap>(&parseResult))
            {
                populateDbus(*pVal, js, file);
            }

            // release the parser object
            ParserFactory::freeParser(parser);
        }
        catch (const exception& e)
        {
            executePostFailAction(js, file);
            throw;
        }
    }
    catch (const VpdJsonException& ex)
    {
        additionalData.emplace("JSON_PATH", ex.getJsonPath());
        additionalData.emplace("DESCRIPTION", ex.what());
        createPEL(additionalData, pelSeverity, errIntfForJsonFailure);

        cerr << ex.what() << "\n";
        rc = -1;
    }
    catch (const VpdEccException& ex)
    {
        additionalData.emplace("DESCRIPTION", "ECC check failed");
        additionalData.emplace("CALLOUT_INVENTORY_PATH",
                               INVENTORY_PATH + baseFruInventoryPath);
        createPEL(additionalData, pelSeverity, errIntfForEccCheckFail);
        dumpBadVpd(file, vpdVector);
        cerr << ex.what() << "\n";
        rc = -1;
    }
    catch (const VpdDataException& ex)
    {
        if (isThisPcieOnPass1planar(js, file))
        {
            cout << "Pcie_device  [" << file
                 << "]'s VPD is not valid on PASS1 planar.Ignoring.\n";
            rc = 0;
        }
        else if (!(isPresent(js, file).value_or(true)))
        {
            cout << "FRU at: " << file
                 << " is not detected present. Ignore parser error.\n";
            rc = 0;
        }
        else
        {
            string errorMsg =
                "VPD file is either empty or invalid. Parser failed for [";
            errorMsg += file;
            errorMsg += "], with error = " + std::string(ex.what());

            additionalData.emplace("DESCRIPTION", errorMsg);
            additionalData.emplace("CALLOUT_INVENTORY_PATH",
                                   INVENTORY_PATH + baseFruInventoryPath);
            createPEL(additionalData, pelSeverity, errIntfForInvalidVPD);

            rc = -1;
        }
    }
    catch (const exception& e)
    {
        dumpBadVpd(file, vpdVector);
        cerr << e.what() << "\n";
        rc = -1;
    }

    return rc;
}