#pragma once
#include "util_base.hpp"
#include "utility.hpp"
#include "xyz/openbmc_project/Common/error.hpp"

#include <fmt/format.h>

#include <gpiod.hpp>
#include <phosphor-logging/elog-errors.hpp>
#include <phosphor-logging/elog.hpp>
#include <phosphor-logging/log.hpp>

#include <bitset>
#include <chrono>

namespace phosphor::power::psu
{

using Property = std::string;
using Value = std::variant<bool, std::string>;
using PropertyMap = std::map<Property, Value>;
using Interface = std::string;
using InterfaceMap = std::map<Interface, PropertyMap>;
using Object = sdbusplus::message::object_path;
using ObjectMap = std::map<Object, InterfaceMap>;

class Util : public UtilBase
{
  public:
    bool getPresence(sdbusplus::bus::bus& bus,
                     const std::string& invpath) const override
    {
        bool present = false;

        // Use getProperty utility function to get presence status.
        util::getProperty(INVENTORY_IFACE, PRESENT_PROP, invpath,
                          INVENTORY_MGR_IFACE, bus, present);

        return present;
    }

    void setPresence(sdbusplus::bus::bus& bus, const std::string& invpath,
                     bool present, const std::string& name) const override
    {
        using InternalFailure =
            sdbusplus::xyz::openbmc_project::Common::Error::InternalFailure;
        PropertyMap invProp;

        invProp.emplace("Present", present);
        invProp.emplace("PrettyName", name);

        InterfaceMap invIntf;
        invIntf.emplace("xyz.openbmc_project.Inventory.Item",
                        std::move(invProp));

        Interface extraIface = "xyz.openbmc_project.Inventory.Item.PowerSupply";

        invIntf.emplace(extraIface, PropertyMap());

        ObjectMap invObj;
        invObj.emplace(std::move(invpath), std::move(invIntf));

        using namespace phosphor::logging;
        log<level::INFO>(fmt::format("Updating inventory present property. "
                                     "present:{} invpath:{} name:{}",
                                     present, invpath, name)
                             .c_str());

        try
        {
            auto invService = phosphor::power::util::getService(
                INVENTORY_OBJ_PATH, INVENTORY_MGR_IFACE, bus);

            // Update inventory
            auto invMsg =
                bus.new_method_call(invService.c_str(), INVENTORY_OBJ_PATH,
                                    INVENTORY_MGR_IFACE, "Notify");
            invMsg.append(std::move(invObj));
            auto invMgrResponseMsg = bus.call(invMsg);
        }
        catch (const std::exception& e)
        {
            log<level::ERR>(
                fmt::format(
                    "Error in inventory manager call to update inventory: {}",
                    e.what())
                    .c_str());
            elog<InternalFailure>();
        }
    }

    void setAvailable(sdbusplus::bus::bus& bus, const std::string& invpath,
                      bool available) const override
    {
        PropertyMap invProp;
        InterfaceMap invIntf;
        ObjectMap invObj;

        invProp.emplace(AVAILABLE_PROP, available);
        invIntf.emplace(AVAILABILITY_IFACE, std::move(invProp));

        invObj.emplace(std::move(invpath), std::move(invIntf));

        try
        {

            auto invService = phosphor::power::util::getService(
                INVENTORY_OBJ_PATH, INVENTORY_MGR_IFACE, bus);

            auto invMsg =
                bus.new_method_call(invService.c_str(), INVENTORY_OBJ_PATH,
                                    INVENTORY_MGR_IFACE, "Notify");
            invMsg.append(std::move(invObj));
            auto invMgrResponseMsg = bus.call(invMsg);
        }
        catch (const sdbusplus::exception::exception& e)
        {
            using namespace phosphor::logging;
            log<level::ERR>(
                fmt::format("Error in inventory manager call to update "
                            "availability interface: {}",
                            e.what())
                    .c_str());
            throw;
        }
    }

    void handleChassisHealthRollup(sdbusplus::bus::bus& bus,
                                   const std::string& invpath,
                                   bool addRollup) const override
    {
        using AssociationTuple =
            std::tuple<std::string, std::string, std::string>;
        using AssociationsProperty = std::vector<AssociationTuple>;
        try
        {
            auto chassisPath = getChassis(bus, invpath);

            auto service = phosphor::power::util::getService(
                invpath, ASSOC_DEF_IFACE, bus);

            AssociationsProperty associations;
            phosphor::power::util::getProperty<AssociationsProperty>(
                ASSOC_DEF_IFACE, ASSOC_PROP, invpath, service, bus,
                associations);

            AssociationTuple critAssociation{"health_rollup", "critical",
                                             chassisPath};

            auto assocIt = std::find(associations.begin(), associations.end(),
                                     critAssociation);
            if (addRollup)
            {
                if (assocIt != associations.end())
                {
                    // It's already there
                    return;
                }

                associations.push_back(critAssociation);
            }
            else
            {
                if (assocIt == associations.end())
                {
                    // It's already been removed.
                    return;
                }

                // If the object still isn't functional, then don't clear
                // the association.
                bool functional = false;
                phosphor::power::util::getProperty<bool>(
                    OPERATIONAL_STATE_IFACE, FUNCTIONAL_PROP, invpath, service,
                    bus, functional);

                if (!functional)
                {
                    return;
                }

                associations.erase(assocIt);
            }

            phosphor::power::util::setProperty(ASSOC_DEF_IFACE, ASSOC_PROP,
                                               invpath, service, bus,
                                               associations);
        }
        catch (const sdbusplus::exception::exception& e)
        {
            using namespace phosphor::logging;
            log<level::INFO>(fmt::format("Error trying to handle health rollup "
                                         "associations for {}: {}",
                                         invpath, e.what())
                                 .c_str());
        }
    }

    std::string getChassis(sdbusplus::bus::bus& bus,
                           const std::string& invpath) const
    {
        // Use the 'chassis' association to find the parent chassis.
        auto assocPath = invpath + "/chassis";
        std::vector<std::string> endpoints;

        phosphor::power::util::getProperty<decltype(endpoints)>(
            ASSOCIATION_IFACE, ENDPOINTS_PROP, assocPath,
            "xyz.openbmc_project.ObjectMapper", bus, endpoints);

        if (endpoints.empty())
        {
            throw std::runtime_error(
                fmt::format("Missing chassis association for {}", invpath));
        }

        return endpoints[0];
    }
};

std::unique_ptr<GPIOInterfaceBase> createGPIO(const std::string& namedGpio);

class GPIOInterface : public GPIOInterfaceBase
{
  public:
    GPIOInterface() = delete;
    virtual ~GPIOInterface() = default;
    GPIOInterface(const GPIOInterface&) = default;
    GPIOInterface& operator=(const GPIOInterface&) = default;
    GPIOInterface(GPIOInterface&&) = default;
    GPIOInterface& operator=(GPIOInterface&&) = default;

    /**
     * Constructor
     *
     * @param[in] namedGpio - The string for the gpio-line-name
     */
    GPIOInterface(const std::string& namedGpio);

    static std::unique_ptr<GPIOInterfaceBase>
        createGPIO(const std::string& namedGpio);

    /**
     * @brief Attempts to read the state of the GPIO line.
     *
     * Throws an exception if line not found, request line fails, or get_value
     * from line fails.
     *
     * @return 1 for active (low/present), 0 for not active (high/not present).
     */
    int read() override;

    /**
     * @brief Attempts to set the state of the GPIO line to the specified value.
     *
     * Throws an exception if line not found, request line fails, or set_value
     * to line fails.
     *
     * @param[in] value - The value to set the state of the GPIO line, 1 or 0.
     * @param[in] flags - Additional line request flags as defined in gpiod.hpp.
     */
    void write(int value, std::bitset<32> flags) override;

    /**
     * @brief Attempts to toggle (write) a GPIO low then high.
     *
     * Relies on write, so throws exception if line not found, etc.
     *
     * @param[in] delay - Milliseconds to delay betwen low/high toggle.
     */
    void toggleLowHigh(const std::chrono::milliseconds& delay) override;

    /**
     * @brief Returns the name of the GPIO, if not empty.
     */
    std::string getName() const override;

  private:
    gpiod::line line;
};

} // namespace phosphor::power::psu
