#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_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 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_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>(
                fmt::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>(fmt::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
    {
        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(fmt::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
