#pragma once

#include "bios_handler.hpp"
#include "editor_impl.hpp"
#include "gpioMonitor.hpp"

#include <sdbusplus/asio/object_server.hpp>

#include <map>

namespace openpower
{
namespace vpd
{
namespace manager
{

/** @class Manager
 *  @brief OpenBMC VPD Manager implementation.
 *
 *  Implements methods under interface com.ibm.vpd.Manager.
 */
class Manager
{
  public:
    /* Define all of the basic class operations:
     * Not allowed:
     * - Default constructor to avoid nullptrs.
     * - Copy operations due to internal unique_ptr.
     * - Move operations due to 'this' being registered as the
     *  'context' with sdbus.
     * Allowed:
     * - Destructor.
     */
    Manager() = delete;
    Manager(const Manager&) = delete;
    Manager& operator=(const Manager&) = delete;
    Manager(Manager&&) = delete;
    ~Manager()
    {
        sd_bus_unref(sdBus);
    }

    /** @brief Constructor.
     *  @param[in] ioCon - IO context.
     *  @param[in] iFace - interface to implement.
     *  @param[in] connection - Dbus Connection.
     */
    Manager(std::shared_ptr<boost::asio::io_context>& ioCon,
            std::shared_ptr<sdbusplus::asio::dbus_interface>& iFace,
            std::shared_ptr<sdbusplus::asio::connection>& conn);

    /** @brief Implementation for WriteKeyword
     *  Api to update the keyword value for a given inventory.
     *
     *  @param[in] path - Path to the D-Bus object that represents the FRU.
     *  @param[in] recordName - name of the record for which the keyword value
     *  has to be modified
     *  @param[in] keyword - keyword whose value needs to be updated
     *  @param[in] value - value that needs to be updated
     */
    void writeKeyword(const sdbusplus::message::object_path& path,
                      const std::string& recordName, const std::string& keyword,
                      const Binary& value);

    /** @brief Implementation for GetFRUsByUnexpandedLocationCode
     *  A method to get list of FRU D-BUS object paths for a given unexpanded
     *  location code. Returns empty vector if no FRU found for that location
     *  code.
     *
     *  @param[in] locationCode - An un-expanded Location code.
     *  @param[in] nodeNumber - Denotes the node in case of a multi-node
     *  configuration, ignored on a single node system.
     *
     *  @return inventoryList[std::vector<sdbusplus::message::object_path>] -
     *  List of all the FRUs D-Bus object paths for the given location code.
     */
    inventory::ListOfPaths
        getFRUsByUnexpandedLocationCode(const std::string& locationCode,
                                        const uint16_t nodeNumber);

    /** @brief Implementation for GetFRUsByExpandedLocationCode
     *  A method to get list of FRU D-BUS object paths for a given expanded
     *  location code. Returns empty vector if no FRU found for that location
     *  code.
     *
     *  @param[in] locationCode - Location code in expanded format.
     *
     *  @return inventoryList[std::vector<sdbusplus::message::object_path>] -
     *  List of all the FRUs D-Bus object path for the given location code.
     */
    inventory::ListOfPaths
        getFRUsByExpandedLocationCode(const std::string& locationCode);

    /** @brief Implementation for GetExpandedLocationCode
     *  An API to get expanded location code corresponding to a given
     *  un-expanded location code.
     *
     *  @param[in] locationCode - Location code in un-expaned format.
     *  @param[in] nodeNumber - Denotes the node in case of multi-node
     *  configuration. Ignored in case of single node configuration.
     *
     *  @return locationCode[std::string] - Location code in expanded format.
     */
    std::string getExpandedLocationCode(const std::string& locationCode,
                                        const uint16_t nodeNumber);

    /** @brief Api to perform VPD recollection.
     * This api will trigger parser to perform VPD recollection for FRUs that
     * can be replaced at standby.
     */
    void performVPDRecollection();

    /** @brief Api to delete FRU VPD.
     * This api will set the present property of given FRU to false. If already
     * set to false, It will log an error.
     * @param[in] path - Object path of FRU.
     */
    void deleteFRUVPD(const sdbusplus::message::object_path& path);

    /** @brief Api to perform VPD collection for a single fru.
     *  @param[in] path - Dbus object path of that fru.
     */
    void collectFRUVPD(const sdbusplus::message::object_path& path);

  private:
    /**
     * @brief An api to process some initial requirements.
     */
    void initManager();

    /** @brief process the given JSON file
     */
    void processJSON();

    /** @brief Api to register host state callback.
     * This api will register callback to listen for host state property change.
     */
    void listenHostState();

    /** @brief Callback to listen for Host state change
     *  @param[in] msg - callback message.
     */
    void hostStateCallBack(sdbusplus::message_t& msg);

    /** @brief Api to register AssetTag property change.
     * This api will register callback to listen for asset tag property change.
     */
    void listenAssetTag();

    /** @brief Callback to listen for Asset tag change
     *  @param[in] msg - callback message.
     */
    void assetTagCallback(sdbusplus::message_t& msg);

    /**
     * @brief Restores and defaulted VPD on the system VPD EEPROM.
     *
     * This function will read the system VPD EEPROM and check if any of the
     * keywords that need to be preserved across FRU replacements are defaulted
     * in the EEPROM. If they are, this function will restore them from the
     * value that is in the D-Bus cache.
     */
    void restoreSystemVpd();

    /**
     * @brief An api to trigger vpd collection for a fru by bind/unbind of
     * driver.
     * @param[in] singleFru - Json of a single fru inder a given EEPROM path.
     * @param[in] path - Inventory path.
     */
    void triggerVpdCollection(const nlohmann::json& singleFru,
                              const std::string& path);

    /**
     * @brief Check for essential fru in the system.
     * The api check for the presence of FRUs marked as essential and logs PEL
     * in case they are missing.
     */
    void checkEssentialFrus();

    // Shared pointer to asio context object.
    std::shared_ptr<boost::asio::io_context>& ioContext;

    // Shared pointer to Dbus interface class.
    std::shared_ptr<sdbusplus::asio::dbus_interface>& interface;

    // Shared pointer to bus connection.
    std::shared_ptr<sdbusplus::asio::connection>& conn;

    // file to store parsed json
    nlohmann::json jsonFile;

    // map to hold mapping to inventory path to vpd file path
    // we need as map here as it is in reverse order to that of json
    inventory::FrusMap frus;

    // map to hold the mapping of location code and inventory path
    inventory::LocationCodeMap fruLocationCode;

    // map to hold FRUs which can be replaced at standby
    inventory::ReplaceableFrus replaceableFrus;

    // Shared pointer to gpio monitor object.
    std::shared_ptr<GpioMonitor> gpioMon;

    // Shared pointer to instance of the BIOS handler.
    std::shared_ptr<BiosHandler> biosHandler;

    // List of FRUs marked as essential in the system.
    inventory::EssentialFrus essentialFrus;

    // sd-bus
    sd_bus* sdBus = nullptr;
};

} // namespace manager
} // namespace vpd
} // namespace openpower
