#pragma once

#include "tool_utils.hpp"

#include <nlohmann/json.hpp>

#include <optional>
#include <string>

namespace vpd
{
/**
 * @brief Class to support operations on VPD.
 *
 * The class provides API's to,
 * Read keyword value from DBus/hardware.
 * Update keyword value to DBus/hardware.
 * Dump DBus object's critical information.
 * Fix system VPD if any mismatch between DBus and hardware data.
 * Reset specific system VPD keywords to its default value.
 * Force VPD collection for hardware.
 */
class VpdTool
{
  private:
    /**
     * @brief Get specific properties of a FRU in JSON format.
     *
     * For a given object path of a FRU, this API returns the following
     * properties of the FRU in JSON format:
     * - Pretty Name, Location Code, Sub Model
     * - SN, PN, CC, FN, DR keywords under VINI record.
     *
     * @param[in] i_objectPath - DBus object path
     *
     * @return On success, returns the properties of the FRU in JSON format,
     * otherwise returns an empty JSON.
     * If FRU's "Present" property is false, this API returns an empty JSON.
     * Note: The caller of this API should handle empty JSON.
     *
     * @throw json::exception, std::out_of_range, std::bad_alloc
     */
    nlohmann::json getFruProperties(const std::string& i_objectPath) const;

    /**
     * @brief API to populate FRU JSON.
     *
     * The API will create FRUs JSON, which will have property value pairs for
     * all the interfaces required for that particular FRU.
     *
     * @param[in] i_inventoryObjPath - FRU inventory path.
     * @param[in, out] io_fruJsonObject - JSON object.
     * @param[in] i_interfaceList - list of interfaces implemented by the FRU on
     * Dbus.
     */
    void populateFruJson(const std::string& i_inventoryObjPath,
                         nlohmann::json& io_fruJsonObject,
                         const std::vector<std::string>& i_interfaceList) const;

    /**
     * @brief API to populate JSON for an interface.
     *
     * The API will create interface JSON, which will have property value pairs
     * for all the properties required under that interface.
     *
     * @param[in] i_inventoryObjPath - FRU inventory path.
     * @param[in] i_infName - interface whose JSON need to be populated.
     * @param[in] i_propList - List of properties needed in the JSON.
     * @param[in, out] io_fruJsonObject - JSON object.
     */
    template <typename PropertyType>
    void populateInterfaceJson(const std::string& i_inventoryObjPath,
                               const std::string& i_infName,
                               const std::vector<std::string>& i_propList,
                               nlohmann::json& io_fruJsonObject) const;

    /**
     * @brief Get any inventory property in JSON.
     *
     * API to get any property of a FRU in JSON format. Given an object path,
     * interface and property name, this API does a D-Bus read property on PIM
     * to get the value of that property and returns it in JSON format. This API
     * returns empty JSON in case of failure. The caller of the API must check
     * for empty JSON.
     *
     * @param[in] i_objectPath - DBus object path
     * @param[in] i_interface - Interface name
     * @param[in] i_propertyName - Property name
     *
     * @return On success, returns the property and its value in JSON format,
     * otherwise return empty JSON.
     * {"SN" : "ABCD"}
     */
    template <typename PropertyType>
    nlohmann::json getInventoryPropertyJson(
        const std::string& i_objectPath, const std::string& i_interface,
        const std::string& i_propertyName) const noexcept;

    /**
     * @brief Get the "type" property for a FRU.
     *
     * Given a FRU path, and parsed System Config JSON, this API returns the
     * "type" property for the FRU in JSON format. This API gets
     * these properties from Phosphor Inventory Manager.
     *
     * @param[in] i_objectPath - DBus object path.
     *
     * @return On success, returns the "type" property in JSON
     * format, otherwise returns empty JSON. The caller of this API should
     * handle empty JSON.
     */
    nlohmann::json getFruTypeProperty(
        const std::string& i_objectPath) const noexcept;

    /**
     * @brief Check if a FRU is present in the system.
     *
     * Given a FRU's object path, this API checks if the FRU is present in the
     * system by reading the "Present" property of the FRU.
     *
     * @param[in] i_objectPath - DBus object path.
     *
     * @return true if FRU's "Present" property is true, false otherwise.
     */
    bool isFruPresent(const std::string& i_objectPath) const noexcept;

    /**
     * @brief An API to get backup-restore config JSON of the system.
     *
     * API gets this file by prasing system config JSON file and reading
     * backupRestoreConfigPath tag.
     *
     * @return On success returns valid JSON object, otherwise returns empty
     * JSON object.
     *
     * Note: The caller of this API should verify, is received JSON object is
     * empty or not.
     */
    nlohmann::json getBackupRestoreCfgJsonObj() const noexcept;

    /**
     * @brief Prints the user options for fix system VPD command.
     *
     * @param[in] i_option - Option to use.
     */
    void printFixSystemVpdOption(
        const types::UserOption& i_option) const noexcept;

    /**
     * @brief API to update source and destination keyword's value.
     *
     * API fetches source and destination keyword's value,
     * for each keyword entries found in the input JSON object and updates the
     * JSON object. If the path(source / destination) in JSON object is
     * inventory object path, API sends the request to Inventory.Manager DBus
     * service. Otherwise if its a hardware path, API sends the request to
     * vpd-manager DBus service to get the keyword's value.
     *
     * @param[in,out] io_parsedJsonObj - Parsed JSON object.
     *
     * @return true on success, false in case of any error.
     */
    bool fetchKeywordInfo(nlohmann::json& io_parsedJsonObj) const noexcept;

    /**
     * @brief API to print system VPD keyword's information.
     *
     * The API prints source and destination keyword's information in the table
     * format, found in the JSON object.
     *
     * @param[in] i_parsedJsonObj - Parsed JSON object.
     */
    void printSystemVpd(const nlohmann::json& i_parsedJsonObj) const noexcept;

    /**
     * @brief API to update keyword's value.
     *
     * API iterates the given JSON object for all record-keyword pairs, if there
     * is any mismatch between source and destination keyword's value, API calls
     * the utils::writeKeyword API to update keyword's value.
     *
     * Note: writeKeyword API, internally updates primary, backup, redundant
     * EEPROM paths(if exists) with the given keyword's value.
     *
     * @param i_parsedJsonObj - Parsed JSON object.
     * @param i_useBackupData - Specifies whether to use source or destination
     * keyword's value to update the keyword's value.
     *
     * @return On success return 0, otherwise return -1.
     */
    int updateAllKeywords(const nlohmann::json& i_parsedJsonObj,
                          bool i_useBackupData) const noexcept;

    /**
     * @brief API to handle more option for fix system VPD command.
     *
     * @param i_parsedJsonObj - Parsed JSON object.
     *
     * @return On success return 0, otherwise return -1.
     */
    int handleMoreOption(const nlohmann::json& i_parsedJsonObj) const noexcept;

    /**
     * @brief API to get VPD value of keyword in BIOS Config Manager.
     *
     * For a given record and keyword, this API gets the associated BIOS
     * attribute current value from BIOS Config Manager, by reading the
     * attribute value from BIOS Config Manager, converts the BIOS attribute
     * value to VPD format, and returns it.
     *
     * @param[in] i_recordName - Record name.
     * @param[in] i_keywordName - Keyword name.
     *
     * @return On success returns the resultant keyword value in binary
     * format, else returns empty value.
     *
     * @throw std::terminate, std::bad_alloc
     */
    types::BinaryVector getVpdValueInBiosConfigManager(
        const std::string& i_recordName,
        const std::string& i_keywordName) const;

    /**
     * @brief VPD keyword to BIOS attribute map
     *
     * This map specifies which VPD keyword is used to backup which BIOS
     * attribute.
     * {Record, Keyword} -> {attribute name, number of bits in keyword, starting
     * bit position, enabled value, disabled value}
     *
     */
    static const types::BiosAttributeKeywordMap m_biosAttributeVpdKeywordMap;

  public:
    /**
     * @brief Read keyword value.
     *
     * API to read VPD keyword's value from the given input path.
     * If the provided i_onHardware option is true, read keyword's value from
     * the hardware. Otherwise read keyword's value from DBus.
     *
     * @param[in] i_vpdPath - DBus object path or EEPROM path.
     * @param[in] i_recordName - Record name.
     * @param[in] i_keywordName - Keyword name.
     * @param[in] i_onHardware - True if i_vpdPath is EEPROM path, false
     * otherwise.
     * @param[in] i_fileToSave - File path to save keyword's value, if not given
     * result will redirect to a console.
     *
     * @return On success return 0, otherwise return -1.
     */
    int readKeyword(const std::string& i_vpdPath,
                    const std::string& i_recordName,
                    const std::string& i_keywordName, const bool i_onHardware,
                    const std::string& i_fileToSave = {});

    /**
     * @brief Dump the given inventory object in JSON format to console.
     *
     * For a given object path of a FRU, this API dumps the following properties
     * of the FRU in JSON format to console:
     * - Pretty Name, Location Code, Sub Model
     * - SN, PN, CC, FN, DR keywords under VINI record.
     * If the FRU's "Present" property is not true, the above properties are not
     * dumped to console.
     *
     * @param[in] i_fruPath - DBus object path.
     *
     * @return On success returns 0, otherwise returns -1.
     */
    int dumpObject(std::string i_fruPath) const noexcept;

    /**
     * @brief API to fix system VPD keywords.
     *
     * The API to fix the system VPD keywords. Mainly used when there
     * is a mismatch between the primary and backup(secondary) VPD. User can
     * choose option to update all primary keywords value with corresponding
     * backup keywords value or can choose primary keyword value to sync
     * secondary VPD. Otherwise, user can also interactively choose different
     * action for individual keyword.
     *
     * @return On success returns 0, otherwise returns -1.
     */
    int fixSystemVpd() const noexcept;

    /**
     * @brief Write keyword's value.
     *
     * API to update VPD keyword's value to the given input path.
     * If i_onHardware value in true, i_vpdPath is considered has hardware path
     * otherwise it will be considered as DBus object path.
     *
     * For provided DBus object path both primary path or secondary path will
     * get updated, also redundant EEPROM(if any) path with new keyword's value.
     *
     * In case of hardware path, only given hardware path gets updated with new
     * keyword’s value, any backup or redundant EEPROM (if exists) paths won't
     * get updated.
     *
     * @param[in] i_vpdPath - DBus object path or EEPROM path.
     * @param[in] i_recordName - Record name.
     * @param[in] i_keywordName - Keyword name.
     * @param[in] i_keywordValue - Keyword value.
     * @param[in] i_onHardware - True if i_vpdPath is EEPROM path, false
     * otherwise.
     *
     * @return On success returns 0, otherwise returns -1.
     */
    int writeKeyword(std::string i_vpdPath, const std::string& i_recordName,
                     const std::string& i_keywordName,
                     const std::string& i_keywordValue,
                     const bool i_onHardware) noexcept;

    /**
     * @brief Reset specific keywords on System VPD to default value.
     *
     * This API resets specific System VPD keywords to default value. The
     * keyword values are reset on:
     * 1. Primary EEPROM path.
     * 2. Secondary EEPROM path.
     * 3. D-Bus cache.
     * 4. Backup path.
     *
     * @param[in] i_syncBiosAttributesRequired - Flag which specifies whether
     * BIOS attribute related keywords need to be synced from BIOS Config
     * Manager instead of being reset to default value.
     *
     * @return On success returns 0, otherwise returns -1.
     */
    int cleanSystemVpd(
        bool i_syncBiosAttributesRequired = false) const noexcept;

    /**
     * @brief Dump all the inventory objects in JSON or table format to console.
     *
     * This API dumps specific properties of all the inventory objects to
     * console in JSON or table format to console. The inventory object paths
     * are extracted from PIM. For each object, the following properties are
     * dumped to console:
     * - Present property, Pretty Name, Location Code, Sub Model
     * - SN, PN, CC, FN, DR keywords under VINI record.
     * If the "Present" property of a FRU is false, the FRU is not dumped to
     * console.
     * FRUs whose object path end in "unit([0-9][0-9]?)" are also not dumped to
     * console.
     *
     * @param[in] i_dumpTable - Flag which specifies if the inventory should be
     * dumped in table format or not.
     *
     * @return On success returns 0, otherwise returns -1.
     */
    int dumpInventory(bool i_dumpTable = false) const noexcept;

    /**
     * @brief Resets the VPD on DBus for all the Frus.
     *
     * API clears the inventory persisted data and restarts the phosphor
     * inventory manager(PIM) DBus service and the VPD manager service. VPD
     * manager service collects the VPD for all the FRU's listed on the system
     * config JSON and calls PIM to publish VPD on DBus.
     *
     * @return On success returns 0, otherwise returns -1.
     */
    int resetVpdOnDbus();

    /**
     * @brief API to clear vpd dump directory
     *
     * This API deletes all the files inside vpd dump directory and then deletes
     * the directory from the filesystem
     */
    void clearVpdDumpDir() const noexcept;
};
} // namespace vpd
