#include "config.h"

#include "editor_impl.hpp"
#include "ibm_vpd_utils.hpp"
#include "types.hpp"

#include <nlohmann/json.hpp>
#include <string>

using json = nlohmann::json;

// <S.no, Record, Keyword, D-Bus value, HW value, Data mismatch>
using SystemCriticalData =
    std::vector<std::tuple<int, std::string, std::string, std::string,
                           std::string, std::string>>;

class VpdTool
{
  private:
    const std::string fruPath;
    const std::string recordName;
    const std::string keyword;
    const std::string value;
    bool objFound = true;
    SystemCriticalData recKwData;

    // Store Type of FRU
    std::string fruType;

    /**
     * @brief Debugger
     * Displays the output in JSON.
     *
     * @param[in] output - json output to be displayed
     */
    void debugger(json output);

    /**
     * @brief make Dbus Call
     *
     * @param[in] objectName - dbus Object
     * @param[in] interface - dbus Interface
     * @param[in] kw - keyword under the interface
     *
     * @return dbus call response
     */
    auto makeDBusCall(const std::string& objectName,
                      const std::string& interface, const std::string& kw);

    /**
     * @brief Get VINI properties
     * Making a dbus call for properties [SN, PN, CC, FN, DR]
     * under VINI interface.
     *
     * @param[in] invPath - Value of inventory Path
     *
     * @return json output which gives the properties under invPath's VINI
     * interface
     */
    json getVINIProperties(std::string invPath);

    /**
     * @brief Get ExtraInterface Properties
     * Making a dbus call for those properties under extraInterfaces.
     *
     * @param[in] invPath - Value of inventory path
     * @param[in] extraInterface - One of the invPath's extraInterfaces whose
     * value is not null
     * @param[in] prop - All properties of the extraInterface.
     * @param[out] output - output json which has the properties under invPath's
     * extra interface.
     */
    void getExtraInterfaceProperties(const std::string& invPath,
                                     const std::string& extraInterface,
                                     const json& prop, json& output);

    /**
     * @brief Interface Decider
     * Decides whether to make the dbus call for
     * getting properites from extraInterface or from
     * VINI interface, depending on the value of
     * extraInterfaces object in the inventory json.
     *
     * @param[in] itemEEPROM - holds the reference of one of the EEPROM objects.
     *
     * @return json output for one of the EEPROM objects.
     */
    json interfaceDecider(json& itemEEPROM);

    /**
     * @brief Parse Inventory JSON
     * Parses the complete inventory json and depending upon
     * the user option makes the dbuscall for the frus
     * via interfaceDecider function.
     *
     * @param[in] jsObject - Inventory json object
     * @param[in] flag - flag which tells about the user option(either
     * dumpInventory or dumpObject)
     * @param[in] fruPath - fruPath is empty for dumpInventory option and holds
     *                      valid fruPath for dumpObject option.
     *
     * @return output json
     */
    json parseInvJson(const json& jsObject, char flag, std::string fruPath);

    /**
     * @brief eraseInventoryPath
     * Remove the INVENTORY_PATH - "/xyz/openbmc_project/inventory"
     * for code convenience.
     *
     * @param[out] fru - Reference to the fru path whose INVENTORY_PATH is
     * stripped off.
     */
    void eraseInventoryPath(std::string& fru);

    /**
     * @brief printReturnCode
     * Prints the return code of the program in console output, whenever
     * the program fails to exit successfully.
     *
     * @param[in] returnCode - return code of the program.
     */
    void printReturnCode(int returnCode);

    /**
     * @brief Convert hex/ascii values to Binary
     * @param[in] - value in hex/ascii.
     * @param[out] - value in binary.
     */
    openpower::vpd::Binary toBinary(const std::string& value);

    /**
     * @brief Get the json which has Present property value of the given fru.
     * @param[in] invPath - inventory path of the fru.
     * @param[out] parentPresence - Update the parent fru's present property.
     * @return output json which has the Present property value.
     */
    json getPresentPropJson(const std::string& invPath,
                            std::string& parentPresence);

    /**
     * @brief Parse through the options to fix system VPD
     *
     * @param[in] json - Inventory JSON
     */
    void parseSVPDOptions(const nlohmann::json& json);

    /**
     * @brief List of user options that can be used to fix system VPD keywords.
     */
    enum UserOption
    {
        EXIT = 0,
        BMC_DATA_FOR_ALL = 1,
        SYSTEM_BACKPLANE_DATA_FOR_ALL = 2,
        MORE_OPTIONS = 3,
        BMC_DATA_FOR_CURRENT = 4,
        SYSTEM_BACKPLANE_DATA_FOR_CURRENT = 5,
        NEW_VALUE_ON_BOTH = 6,
        SKIP_CURRENT = 7
    };

    /**
     * @brief Print options to fix system VPD.
     * @param[in] option - Option to use.
     */
    void printFixSystemVPDOption(UserOption option);

  public:
    /**
     * @brief Dump the complete inventory in JSON format
     *
     * @param[in] jsObject - Inventory JSON specified in configure file.
     */
    void dumpInventory(const nlohmann::basic_json<>& jsObject);

    /**
     * @brief Dump the given inventory object in JSON format
     *
     * @param[in] jsObject - Inventory JSON specified in configure file.
     */
    void dumpObject(const nlohmann::basic_json<>& jsObject);

    /**
     * @brief Read keyword
     * Read the given object path, record name and keyword
     * from the inventory and display the value of the keyword
     * in JSON format.
     */
    void readKeyword();

    /**
     * @brief Update Keyword
     * Update the given keyword with the given value.
     *
     * @return return code (Success(0)/Failure(-1))
     */
    int updateKeyword();

    /**
     * @brief Force Reset
     * Clearing the inventory cache data and restarting the
     * phosphor inventory manager and also retriggering all the
     * udev events.
     *
     * @param[in] jsObject - Inventory JSON specified in configure file.
     */
    void forceReset(const nlohmann::basic_json<>& jsObject);

    /**
     * @brief Update Hardware
     * The given data is updated only on the given hardware path and not on dbus
     * for the given record-keyword pair. The user can now update record-keyword
     * value for any hardware path irrespective of whether its present or not in
     * VPD JSON, by providing a valid offset. By default offset takes 0.
     *
     * @param[in] offset - VPD offset.
     * @return returncode (success/failure).
     */
    int updateHardware(const uint32_t offset);

    /**
     * @brief Read Keyword from Hardware
     * This api is to read a keyword directly from the hardware. The hardware
     * path, record name and keyword name are received at the time of
     * initialising the constructor.
     * The user can now read keyword from any hardware path irrespective of
     * whether its present or not in VPD JSON, by providing a valid offset. By
     * default offset takes 0.
     *
     * @param[in] startOffset - VPD offset.
     */
    void readKwFromHw(const uint32_t& startOffset);

    /**
     * @brief Fix System VPD keyword.
     * This API provides an interactive way to fix system VPD keywords that are
     * part of restorable record-keyword pairs. The user can use this option to
     * restore the restorable keywords in cache or in hardware or in both cache
     * and hardware.
     * @return returncode (success/failure).
     */
    int fixSystemVPD();

    /**
     * @brief Constructor
     * Constructor is called during the
     * object instantiation for dumpInventory option and
     * forceReset option.
     */
    VpdTool()
    {
    }

    /**
     * @brief Constructor
     * Constructor is called during the
     * object instantiation for dumpObject option.
     */
    VpdTool(const std::string&& fru) : fruPath(std::move(fru))
    {
    }

    /**
     * @brief Constructor
     * Constructor is called during the
     * object instantiation for readKeyword option.
     */
    VpdTool(const std::string&& fru, const std::string&& recName,
            const std::string&& kw) :
        fruPath(std::move(fru)),
        recordName(std::move(recName)), keyword(std::move(kw))
    {
    }

    /**
     * @brief Constructor
     * Constructor is called during the
     * object instantiation for updateKeyword option.
     */

    VpdTool(const std::string&& fru, const std::string&& recName,
            const std::string&& kw, const std::string&& val) :
        fruPath(std::move(fru)),
        recordName(std::move(recName)), keyword(std::move(kw)),
        value(std::move(val))
    {
    }
};
