#pragma once

#include "const.hpp"
#include "store.hpp"
#include "types.hpp"

#include <nlohmann/json.hpp>

#include <iostream>
#include <optional>
#include <variant>

namespace openpower
{
namespace vpd
{

// Map which holds system vpd keywords which can be restored at standby and via
// vpd-tool and also can be used to reset keywords to its defaults at
// manufacturing. The list of keywords for VSYS record is as per the S0 system.
// Should be updated for another type of systems For those keywords whose
// default value is system specific, the default value field is left empty.
// Record : {Keyword, Default value, Is PEL required on restore failure, Is MFG
// reset required, backupVpdRecName, backupVpdKwName}
static const inventory::SystemKeywordsMap svpdKwdMap{
    {"VSYS",
     {inventory::SystemKeywordInfo("BR", Binary(2, 0x20), true, true, "VSBK",
                                   "BR"),
      inventory::SystemKeywordInfo("TM", Binary(8, 0x20), true, true, "VSBK",
                                   "TM"),
      inventory::SystemKeywordInfo("SE", Binary(7, 0x20), true, true, "VSBK",
                                   "SE"),
      inventory::SystemKeywordInfo("SU", Binary(6, 0x20), true, true, "VSBK",
                                   "SU"),
      inventory::SystemKeywordInfo("RB", Binary(4, 0x20), true, true, "VSBK",
                                   "RB"),
      inventory::SystemKeywordInfo("WN", Binary(12, 0x20), true, true, "VSBK",
                                   "WN"),
      inventory::SystemKeywordInfo("RG", Binary(4, 0x20), true, true, "VSBK",
                                   "RG"),
      inventory::SystemKeywordInfo("FV", Binary(32, 0x20), false, true, "VSBK",
                                   "FV")}},
    {"VCEN",
     {inventory::SystemKeywordInfo("FC", Binary(8, 0x20), true, false, "VSBK",
                                   "FC"),
      inventory::SystemKeywordInfo("SE", Binary(7, 0x20), true, true, "VSBK",
                                   "ES")}},
    {"LXR0",
     {inventory::SystemKeywordInfo("LX", Binary(8, 0x00), true, false, "VSBK",
                                   "LX")}},
    {"UTIL",
     {inventory::SystemKeywordInfo("D0", Binary(1, 0x00), true, true, "VSBK",
                                   "D0"),
      inventory::SystemKeywordInfo("D1", Binary(1, 0x00), false, true, "VSBK",
                                   "D1"),
      inventory::SystemKeywordInfo("F0", Binary(8, 0x00), false, true, "VSBK",
                                   "F0"),
      inventory::SystemKeywordInfo("F5", Binary(16, 0x00), false, true, "VSBK",
                                   "F5"),
      inventory::SystemKeywordInfo("F6", Binary(16, 0x00), false, true, "VSBK",
                                   "F6")}}};

/** @brief Return the hex representation of the incoming byte
 *
 * @param [in] c - The input byte
 * @returns The hex representation of the byte as a character.
 */
constexpr auto toHex(size_t c)
{
    constexpr auto map = "0123456789abcdef";
    return map[c];
}

namespace inventory
{
/** @brief API to obtain a dictionary of path -> services
 * where path is in subtree and services is of the type
 * returned by the GetObject method.
 *
 * @param [in] root - Root path for object subtree
 * @param [in] depth - Maximum subtree depth required
 * @param [in] interfaces - Array to interfaces for which
 * result is required.
 * @return A dictionary of Path -> services
 */
MapperResponse
    getObjectSubtreeForInterfaces(const std::string& root, const int32_t depth,
                                  const std::vector<std::string>& interfaces);

/**
 * @brief API to call GetObject API of mapper.
 *
 * @param[in] objectPath - inventory path.
 * @param[in] interfaces - List of interfaces.
 *
 * @return - response of the API call.
 */
MapperGetObjectResponse getObject(const std::string& objectPath,
                                  const std::vector<std::string>& interfaces);

} // namespace inventory

/**@brief This API reads 2 Bytes of data and swap the read data
 * @param[in] iterator- Pointer pointing to the data to be read
 * @return returns 2 Byte data read at the given pointer
 */
openpower::vpd::constants::LE2ByteData
    readUInt16LE(Binary::const_iterator iterator);

/** @brief Encodes a keyword for D-Bus.
 *  @param[in] kw - kwd data in string format
 *  @param[in] encoding - required for kwd data
 */
std::string encodeKeyword(const std::string& kw, const std::string& encoding);

/** @brief Reads a property from the inventory manager given object path,
 *         interface and property.
 *  @param[in] obj - object path
 *  @param[in] inf - interface
 *  @param[in] prop - property whose value is fetched
 *  @return [out] - value of the property
 */
std::string readBusProperty(const std::string& obj, const std::string& inf,
                            const std::string& prop);

/** @brief A templated function to read D-Bus properties.
 *
 *  @param[in] service - Service path
 *  @param[in] object - object path
 *  @param[in] inf - interface
 *  @param[in] prop - property whose value is fetched
 *  @return The property value of its own type.
 */
template <typename T>
T readDBusProperty(const std::string& service, const std::string& object,
                   const std::string& inf, const std::string& prop)
{
    T retVal{};
    try
    {
        auto bus = sdbusplus::bus::new_default();
        auto properties =
            bus.new_method_call(service.c_str(), object.c_str(),
                                "org.freedesktop.DBus.Properties", "Get");
        properties.append(inf);
        properties.append(prop);
        auto result = bus.call(properties);
        result.read(retVal);
    }
    catch (const sdbusplus::exception::SdBusError& e)
    {
        std::cerr << e.what();
    }
    return retVal;
}

/** @brief A templated method to get all D-Bus properties
 *
 * @param[in] service - Service path
 * @param[in] object - Object path
 * @param[in] inf - Interface
 *
 * @return All properties under the given interface.
 */
template <typename T>
T getAllDBusProperty(const std::string& service, const std::string& object,
                     const std::string& inf)
{
    T retVal{};
    try
    {
        auto bus = sdbusplus::bus::new_default();
        auto allProperties =
            bus.new_method_call(service.c_str(), object.c_str(),
                                "org.freedesktop.DBus.Properties", "GetAll");
        allProperties.append(inf);

        auto result = bus.call(allProperties);
        result.read(retVal);
    }
    catch (const sdbusplus::exception::SdBusError& e)
    {
        std::cerr << e.what();
    }
    return retVal;
}

/**
 * @brief API to create PEL entry
 * The api makes synchronous call to phosphor-logging create api.
 * @param[in] additionalData - Map holding the additional data
 * @param[in] sev - Severity
 * @param[in] errIntf - error interface
 */
void createSyncPEL(const std::map<std::string, std::string>& additionalData,
                   const constants::PelSeverity& sev,
                   const std::string& errIntf);

/**
 * @brief Api to create PEL.
 * A wrapper api through which sync/async call to phosphor-logging create api
 * can be made as and when required.
 * sdBus as nullptr will result in sync call else async call will be made with
 * just "DESCRIPTION" key/value pair in additional data.
 * To make asyn call with more fields in additional data call
 * "sd_bus_call_method_async" in place.
 *
 * @param[in] additionalData - Map of additional data.
 * @param[in] sev - severity of the PEL.
 * @param[in] errIntf - Error interface to be used in PEL.
 * @param[in] sdBus - Pointer to Sd-Bus
 */
void createPEL(const std::map<std::string, std::string>& additionalData,
               const constants::PelSeverity& sev, const std::string& errIntf,
               sd_bus* sdBus);

/**
 * @brief getVpdFilePath
 * Get vpd file path corresponding to the given object path.
 * @param[in] - json file path
 * @param[in] - Object path
 * @return - Vpd file path
 */
inventory::VPDfilepath getVpdFilePath(const std::string& jsonFile,
                                      const std::string& ObjPath);

/**
 * @brief isPathInJson
 * API which checks for the presence of the given eeprom path in the given json.
 * @param[in] - eepromPath
 * @return - true if the eeprom is present in the json; false otherwise
 */
bool isPathInJson(const std::string& eepromPath);

/**
 * @brief isRecKwInDbusJson
 * API which checks whether the given keyword under the given record is to be
 * published on dbus or not. Checks against the keywords present in
 * dbus_property.json.
 * @param[in] - record name
 * @param[in] - keyword name
 * @return - true if the record-keyword pair is present in dbus_property.json;
 * false otherwise.
 */
bool isRecKwInDbusJson(const std::string& record, const std::string& keyword);

/**
 * @brief Check the type of VPD.
 *
 * Checks the type of vpd based on the start tag.
 * @param[in] vector - Vpd data in vector format
 *
 * @return enum of type vpdType
 */
constants::vpdType vpdTypeCheck(const Binary& vector);

/*
 * @brief This method does nothing. Just an empty function to return null
 * at the end of variadic template args
 */
inline std::string getCommand()
{
    return "";
}

/**
 * @brief This function to arrange all arguments to make commandy
 * @param[in] arguments to create the command
 * @return cmd - command string
 */
template <typename T, typename... Types>
inline std::string getCommand(T arg1, Types... args)
{
    std::string cmd = " " + arg1 + getCommand(args...);

    return cmd;
}

/**
 * @brief This API takes arguments, creates a shell command line and executes
 * them.
 * @param[in] arguments for command
 * @returns output of that command
 */
template <typename T, typename... Types>
inline std::vector<std::string> executeCmd(T&& path, Types... args)
{
    std::vector<std::string> stdOutput;
    std::array<char, 128> buffer;

    std::string cmd = path + getCommand(args...);

    struct custom_file_deleter
    {
        void operator()(std::FILE* fp)
        {
            pclose(fp);
        }
    };
    using unique_file_custom_deleter =
        std::unique_ptr<std::FILE, custom_file_deleter>;
    unique_file_custom_deleter pipe{popen(cmd.c_str(), "r")};

    if (!pipe)
    {
        throw std::runtime_error("popen() failed!");
    }
    while (fgets(buffer.data(), buffer.size(), pipe.get()) != nullptr)
    {
        stdOutput.emplace_back(buffer.data());
    }

    return stdOutput;
}

/** @brief This API checks for IM and HW keywords, and based
 *         on these values decides which system json to be used.
 *  @param[in] vpdMap -  parsed vpd
 *  @returns System json path
 */
std::string getSystemsJson(const Parsed& vpdMap);

/** @brief Reads HW Keyword from the vpd
 *  @param[in] vpdMap -  parsed vpd
 *  @returns value of HW Keyword
 */
const std::string getHW(const Parsed& vpdMap);

/** @brief Reads IM Keyword from the vpd
 *  @param[in] vpdMap -  parsed vpd
 *  @returns value of IM Keyword
 */
const std::string getIM(const Parsed& vpdMap);

/** @brief Translate udev event generated path to a generic /sys/bus eeprom path
 *  @param[io] file - path generated from udev event.
 *  @param[in] driver - kernel driver used by the device.
 */
void udevToGenericPath(std::string& file, const std::string& driver);

/**
 * @brief API to generate a vpd name in some pattern.
 * This vpd-name denotes name of the bad vpd file.
 * For i2c eeproms - the pattern of the vpd-name will be
 * i2c-<bus-number>-<eeprom-address>. For spi eeproms - the pattern of the
 * vpd-name will be spi-<spi-number>.
 *
 * @param[in] file - file path of the vpd
 * @return the vpd-name.
 */
std::string getBadVpdName(const std::string& file);

/**
 * @brief API which dumps the broken/bad vpd in a directory
 * When the vpd is bad, this api places  the bad vpd file inside
 * "/tmp/bad-vpd" in BMC, in order to collect bad VPD data as a part of user
 * initiated BMC dump.
 *
 * @param[in] file - bad vpd file path
 * @param[in] vpdVector - bad vpd vector
 */
void dumpBadVpd(const std::string& file, const Binary& vpdVector);

/*
 * @brief This function fetches the value for given keyword in the given record
 *        from vpd data and returns this value.
 *
 * @param[in] vpdMap - vpd to find out the data
 * @param[in] rec - Record under which desired keyword exists
 * @param[in] kwd - keyword to read the data from
 *
 * @returns keyword value if record/keyword combination found
 *          empty string if record or keyword is not found.
 */
const std::string getKwVal(const Parsed& vpdMap, const std::string& rec,
                           const std::string& kwd);

/** @brief This creates a complete command using all it's input parameters,
 *         to bind or unbind the driver.
 *  @param[in] devNameAddr - device address on that bus
 *  @param[in] busType - i2c, spi
 *  @param[in] driverType - type of driver like at24
 *  @param[in] bindOrUnbind - either bind or unbind
 *  @returns  Command to bind or unbind the driver.
 */
inline std::string createBindUnbindDriverCmnd(
    const std::string& devNameAddr, const std::string& busType,
    const std::string& driverType, const std::string& bindOrUnbind)
{
    return ("echo " + devNameAddr + " > /sys/bus/" + busType + "/drivers/" +
            driverType + "/" + bindOrUnbind);
}

/**
 * @brief Get Printable Value
 *
 * Checks if the value has non printable characters.
 * Returns hex value if non printable char is found else
 * returns ascii value.
 *
 * @param[in] kwVal - Reference of the input data, Keyword value
 * @return printable value - either in hex or in ascii.
 */
std::string getPrintableValue(const std::variant<Binary, std::string>& kwVal);

/**
 * @brief Convert array to hex string.
 * @param[in] kwVal - input data, Keyword value
 * @return hexadecimal string of bytes.
 */
std::string hexString(const std::variant<Binary, std::string>& kwVal);

/**
 * @brief Return presence of the FRU.
 *
 * This API returns the presence information of the FRU corresponding to the
 * given EEPROM. If the JSON contains no information about presence detect, this
 * will return an empty optional. Else it will get the presence GPIO information
 * from the JSON and return the appropriate present status.
 * In case of GPIO find/read errors, it will return false.
 *
 * @param[in] json - The VPD JSON
 * @param[in] file - EEPROM file path
 * @return Empty optional if there is no presence info. Else returns presence
 * based on the GPIO read.
 */
std::optional<bool> isPresent(const nlohmann::json& json,
                              const std::string& file);

/**
 * @brief Performs any pre-action needed to get the FRU setup for
 * collection.
 *
 * @param[in] json - json object
 * @param[in] file - eeprom file path
 * @return - success or failure
 */
bool executePreAction(const nlohmann::json& json, const std::string& file);

/**
 * @brief This API will be called at the end of VPD collection to perform any
 * post actions.
 *
 * @param[in] json - json object
 * @param[in] file - eeprom file path
 */
void executePostFailAction(const nlohmann::json& json, const std::string& file);

/**
 * @brief Helper function to insert or merge in map.
 *
 * This method checks in the given inventory::InterfaceMap if the given
 * interface key is existing or not. If the interface key already exists, given
 * property map is inserted into it. If the key doesn't exist then given
 * interface and property map pair is newly created. If the property present in
 * propertymap already exist in the InterfaceMap, then the new property value is
 * ignored.
 *
 * @param[in,out] map - map object of type inventory::InterfaceMap only.
 * @param[in] interface - Interface name.
 * @param[in] property - new property map that needs to be emplaced.
 */
void insertOrMerge(inventory::InterfaceMap& map,
                   const inventory::Interface& interface,
                   inventory::PropertyMap&& property);

/**
 * @brief Utility API to set a D-Bus property
 *
 * This calls org.freedesktop.DBus.Properties;Set method with the supplied
 * arguments
 *
 * @tparam T Template type of the D-Bus property
 * @param service[in] - The D-Bus service name.
 * @param object[in] - The D-Bus object on which the property is to be set.
 * @param interface[in] - The D-Bus interface to which the property belongs.
 * @param propertyName[in] - The name of the property to set.
 * @param propertyValue[in] - The value of the property.
 */
template <typename T>
void setBusProperty(const std::string& service, const std::string& object,
                    const std::string& interface,
                    const std::string& propertyName,
                    const std::variant<T>& propertyValue)
{
    try
    {
        auto bus = sdbusplus::bus::new_default();
        auto method =
            bus.new_method_call(service.c_str(), object.c_str(),
                                "org.freedesktop.DBus.Properties", "Set");
        method.append(interface);
        method.append(propertyName);
        method.append(propertyValue);

        bus.call(method);
    }
    catch (const sdbusplus::exception::SdBusError& e)
    {
        std::cerr << e.what() << std::endl;
    }
}

/**
 * @brief Reads BIOS Attribute by name.
 *
 * @param attrName[in] - The BIOS attribute name.
 * @return std::variant<int64_t, std::string> - The BIOS attribute value.
 */
std::variant<int64_t, std::string>
    readBIOSAttribute(const std::string& attrName);

/**
 * @brief Returns the power state for chassis0
 * @return The chassis power state.
 */
std::string getPowerState();

/**
 * @brief Reads VPD from the supplied EEPROM
 *
 * This function reads the given VPD EEPROM file and returns its contents as a
 * byte array. It handles any offsets into the file that need to be taken care
 * of by looking up the VPD JSON for a possible offset key.
 *
 * @param js[in] - The VPD JSON Object
 * @param file[in] - The path to the EEPROM to read
 * @return A byte array containing the raw VPD.
 */
Binary getVpdDataInVector(const nlohmann::json& js, const std::string& file);

/**
 * @brief Get D-bus name for the keyword
 * Some of the VPD keywords has different name in PIM when compared with its
 * name from hardware. This method returns the D-bus name for the given keyword.
 *
 * @param[in] keyword - Keyword name
 * @return D-bus name for the keyword
 */
std::string getDbusNameForThisKw(const std::string& keyword);

/**
 * @brief API to remove VPD data from Dbus on removal of FRU.
 *
 * @param[in] objPath - Inventory path of the FRU.
 * @param[out] interfacesPropMap - Map of interface, property and value.
 */
void clearVpdOnRemoval(const std::string& objPath,
                       inventory::InterfaceMap& interfacesPropMap);

/**
 * @brief Find backup VPD path if any for the system VPD
 *
 * @param[out] backupEepromPath - Backup VPD path
 * @param[out] backupInvPath - Backup inventory path
 * @param[in] js - Inventory JSON object
 */
void findBackupVPDPaths(std::string& backupEepromPath,
                        std::string& backupInvPath, const nlohmann::json& js);

/**
 * @brief Get backup VPD's record and keyword for the given system VPD keyword
 *
 * @param[in,out] record - Record name
 * @param[in,out] keyword - Keyword name
 */
void getBackupRecordKeyword(std::string& record, std::string& keyword);

/**
 * @brief Check if EEPROM of the given VPD path is read only.
 *
 * @param[in] vpdPath - VPD path of the FRU.
 * @param[in] jsObject - Inventory JSON object.
 *
 * @return true if EEPROM is read only, false otherwise.
 */
bool isReadOnlyEEPROM(const std::string& vpdPath,
                      const nlohmann::json& jsObject);
} // namespace vpd
} // namespace openpower
