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

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

#include <bitset>
#include <chrono>
#include <format>

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_t& 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_t& bus, const std::string& invpath,
                     bool present, const std::string& name) const override
    {
        using namespace phosphor::logging;
        log<level::INFO>(std::format("Updating inventory present property. "
                                     "present:{} invpath:{} name:{}",
                                     present, invpath, name)
                             .c_str());

        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));

        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>(
                std::format(
                    "Error in inventory manager call to update inventory: {}",
                    e.what())
                    .c_str());
            elog<InternalFailure>();
        }
    }

    void setAvailable(sdbusplus::bus_t& 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_t& e)
        {
            using namespace phosphor::logging;
            log<level::ERR>(
                std::format("Error in inventory manager call to update "
                            "availability interface: {}",
                            e.what())
                    .c_str());
            throw;
        }
    }

    void handleChassisHealthRollup(sdbusplus::bus_t& 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_t& e)
        {
            using namespace phosphor::logging;
            log<level::INFO>(std::format("Error trying to handle health rollup "
                                         "associations for {}: {}",
                                         invpath, e.what())
                                 .c_str());
        }
    }

    std::string getChassis(sdbusplus::bus_t& bus,
                           const std::string& invpath) const override
    {
        sdbusplus::message::object_path assocPath = invpath + "/powering";
        sdbusplus::message::object_path basePath{"/"};
        std::vector<std::string> interfaces{CHASSIS_IFACE};

        // Find the object path that implements the chassis interface
        // and also shows up in the endpoints list of the powering assoc.
        auto chassisPaths = phosphor::power::util::getAssociatedSubTreePaths(
            bus, assocPath, basePath, interfaces, 0);

        if (chassisPaths.empty())
        {
            throw std::runtime_error(std::format(
                "No association to a chassis found for {}", invpath));
        }

        return chassisPaths[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
