#pragma once

#include <xyz/openbmc_project/Sensor/Threshold/Critical/server.hpp>
#include <xyz/openbmc_project/Sensor/Threshold/HardShutdown/server.hpp>
#include <xyz/openbmc_project/Sensor/Threshold/PerformanceLoss/server.hpp>
#include <xyz/openbmc_project/Sensor/Threshold/SoftShutdown/server.hpp>
#include <xyz/openbmc_project/Sensor/Threshold/Warning/server.hpp>

namespace phosphor::virtualSensor
{

template <typename... T>
using ServerObject = typename sdbusplus::server::object_t<T...>;

namespace threshold_ns =
    sdbusplus::xyz::openbmc_project::Sensor::Threshold::server;
using CriticalObject = ServerObject<threshold_ns::Critical>;
using WarningObject = ServerObject<threshold_ns::Warning>;
using SoftShutdownObject = ServerObject<threshold_ns::SoftShutdown>;
using HardShutdownObject = ServerObject<threshold_ns::HardShutdown>;
using PerformanceLossObject = ServerObject<threshold_ns::PerformanceLoss>;

template <typename T>
struct Threshold;

struct Hysteresis
{
    double highHysteresis;
    double lowHysteresis;
    auto getHighHysteresis()
    {
        return this->highHysteresis;
    }

    auto getLowHysteresis()
    {
        return this->lowHysteresis;
    }

    auto setHighHysteresis(double value)
    {
        this->highHysteresis = value;
    }

    auto setLowHysteresis(double value)
    {
        this->lowHysteresis = value;
    }
};

template <>
struct Threshold<WarningObject> : public WarningObject, public Hysteresis
{
    static constexpr auto name = "Warning";
    using WarningObject::WarningObject;
    /** @brief sdbusplus bus client connection. */
    sdbusplus::bus_t& bus;
    std::string objPath;

    /** @brief Virtual sensor path/interface in entityManagerDbus.
     * This 3 value is used to set thresholds
     */
    std::string entityPath;
    std::string entityInterfaceHigh;
    std::string entityInterfaceLow;

    /** @brief Constructor to put object onto bus at a dbus path.
     *  @param[in] bus - Bus to attach to.
     *  @param[in] path - Path to attach at.
     */
    Threshold(sdbusplus::bus_t& bus, const char* path) :
        WarningObject(bus, path), bus(bus), objPath(std::string(path))
    {}

    auto high()
    {
        return WarningObject::warningHigh();
    }
    auto low()
    {
        return WarningObject::warningLow();
    }

    template <typename... Args>
    auto alarmHigh(Args... args)
    {
        return warningAlarmHigh(std::forward<Args>(args)...);
    }

    template <typename... Args>
    auto alarmLow(Args... args)
    {
        return warningAlarmLow(std::forward<Args>(args)...);
    }

    template <typename... Args>
    auto alarmHighSignalAsserted(Args... args)
    {
        return warningHighAlarmAsserted(std::forward<Args>(args)...);
    }

    template <typename... Args>
    auto alarmHighSignalDeasserted(Args... args)
    {
        return warningHighAlarmDeasserted(std::forward<Args>(args)...);
    }

    template <typename... Args>
    auto alarmLowSignalAsserted(Args... args)
    {
        return warningLowAlarmAsserted(std::forward<Args>(args)...);
    }

    template <typename... Args>
    auto alarmLowSignalDeasserted(Args... args)
    {
        return warningLowAlarmDeasserted(std::forward<Args>(args)...);
    }

    /** @brief Set value of WarningHigh */
    virtual double warningHigh(double value)
    {
        if (!entityPath.empty() && !entityInterfaceHigh.empty())
        {
            // persistThreshold
            setDbusProperty(bus, entityManagerBusName, entityPath,
                            entityInterfaceHigh, "Value", value);
        }
        return WarningObject::warningHigh(value);
    }

    /** @brief Set value of WarningLow */
    virtual double warningLow(double value)
    {
        if (!entityPath.empty() && !entityInterfaceLow.empty())
        {
            // persistThreshold
            setDbusProperty(bus, entityManagerBusName, entityPath,
                            entityInterfaceLow, "Value", value);
        }
        return WarningObject::warningLow(value);
    }

    /** @brief Set the entitymanager interface corresponding to virtualsensor
     * warningLow
     */
    void setEntityInterfaceLow(const std::string& interfaceLow)
    {
        entityInterfaceLow = interfaceLow;
    }

    /** @brief Set the entitymanager interface corresponding to virtualsensor
     * warningHigh
     */
    void setEntityInterfaceHigh(const std::string& interfaceHigh)
    {
        entityInterfaceHigh = interfaceHigh;
    }

    /** @brief Set the entitymanager path corresponding to virtualsensor warning
     */
    void setEntityPath(const std::string& path)
    {
        entityPath = path;
    }
};

template <>
struct Threshold<CriticalObject> : public CriticalObject, public Hysteresis
{
    static constexpr auto name = "Critical";

    /** @brief sdbusplus bus client connection. */
    sdbusplus::bus_t& bus;
    std::string objPath;

    /** @brief Virtual sensor path/interface in entityManagerDbus.
     * This 3 value is used to set thresholds
     */
    std::string entityPath;
    std::string entityInterfaceHigh;
    std::string entityInterfaceLow;

    using CriticalObject::CriticalObject;

    /** @brief Constructor to put object onto bus at a dbus path.
     *  @param[in] bus - Bus to attach to.
     *  @param[in] path - Path to attach at.
     */
    Threshold(sdbusplus::bus_t& bus, const char* path) :
        CriticalObject(bus, path), bus(bus), objPath(std::string(path))
    {}

    auto high()
    {
        return CriticalObject::criticalHigh();
    }
    auto low()
    {
        return CriticalObject::criticalLow();
    }

    template <typename... Args>
    auto alarmHigh(Args... args)
    {
        return criticalAlarmHigh(std::forward<Args>(args)...);
    }

    template <typename... Args>
    auto alarmLow(Args... args)
    {
        return criticalAlarmLow(std::forward<Args>(args)...);
    }

    template <typename... Args>
    auto alarmHighSignalAsserted(Args... args)
    {
        return criticalHighAlarmAsserted(std::forward<Args>(args)...);
    }

    template <typename... Args>
    auto alarmHighSignalDeasserted(Args... args)
    {
        return criticalHighAlarmDeasserted(std::forward<Args>(args)...);
    }

    template <typename... Args>
    auto alarmLowSignalAsserted(Args... args)
    {
        return criticalLowAlarmAsserted(std::forward<Args>(args)...);
    }

    template <typename... Args>
    auto alarmLowSignalDeasserted(Args... args)
    {
        return criticalLowAlarmDeasserted(std::forward<Args>(args)...);
    }

    /** @brief Set value of CriticalHigh */
    virtual double criticalHigh(double value)
    {
        // persistThreshold
        if (!entityPath.empty() && !entityInterfaceHigh.empty())
        {
            setDbusProperty(bus, entityManagerBusName, entityPath,
                            entityInterfaceHigh, "Value", value);
        }
        return CriticalObject::criticalHigh(value);
    }

    /** @brief Set value of CriticalLow */
    virtual double criticalLow(double value)
    {
        if (!entityPath.empty() && !entityInterfaceLow.empty())
        {
            setDbusProperty(bus, entityManagerBusName, entityPath,
                            entityInterfaceLow, "Value", value);
        }
        return CriticalObject::criticalLow(value);
    }

    /** @brief Set the entitymanager interface corresponding to virtualsensor
     * criticalLow
     */
    void setEntityInterfaceLow(const std::string& interfaceLow)
    {
        entityInterfaceLow = interfaceLow;
    }

    /** @brief Set the entitymanager interface corresponding to virtualsensor
     * criticalLow
     */
    void setEntityInterfaceHigh(const std::string& interfaceHigh)
    {
        entityInterfaceHigh = interfaceHigh;
    }

    /** @brief Set the entitymanager path corresponding to virtualsensor warning
     */
    void setEntityPath(const std::string& path)
    {
        entityPath = path;
    }
};

template <>
struct Threshold<SoftShutdownObject> :
    public SoftShutdownObject,
    public Hysteresis
{
    static constexpr auto name = "SoftShutdown";
    using SoftShutdownObject::SoftShutdownObject;

    auto high()
    {
        return softShutdownHigh();
    }
    auto low()
    {
        return softShutdownLow();
    }

    template <typename... Args>
    auto alarmHigh(Args... args)
    {
        return softShutdownAlarmHigh(std::forward<Args>(args)...);
    }

    template <typename... Args>
    auto alarmLow(Args... args)
    {
        return softShutdownAlarmLow(std::forward<Args>(args)...);
    }

    template <typename... Args>
    auto alarmHighSignalAsserted(Args... args)
    {
        return softShutdownHighAlarmAsserted(std::forward<Args>(args)...);
    }

    template <typename... Args>
    auto alarmHighSignalDeasserted(Args... args)
    {
        return softShutdownHighAlarmDeasserted(std::forward<Args>(args)...);
    }

    template <typename... Args>
    auto alarmLowSignalAsserted(Args... args)
    {
        return softShutdownLowAlarmAsserted(std::forward<Args>(args)...);
    }

    template <typename... Args>
    auto alarmLowSignalDeasserted(Args... args)
    {
        return softShutdownLowAlarmDeasserted(std::forward<Args>(args)...);
    }
};

template <>
struct Threshold<HardShutdownObject> :
    public HardShutdownObject,
    public Hysteresis
{
    static constexpr auto name = "HardShutdown";
    using HardShutdownObject::HardShutdownObject;

    auto high()
    {
        return hardShutdownHigh();
    }
    auto low()
    {
        return hardShutdownLow();
    }

    template <typename... Args>
    auto alarmHigh(Args... args)
    {
        return hardShutdownAlarmHigh(std::forward<Args>(args)...);
    }

    template <typename... Args>
    auto alarmLow(Args... args)
    {
        return hardShutdownAlarmLow(std::forward<Args>(args)...);
    }

    template <typename... Args>
    auto alarmHighSignalAsserted(Args... args)
    {
        return hardShutdownHighAlarmAsserted(std::forward<Args>(args)...);
    }

    template <typename... Args>
    auto alarmHighSignalDeasserted(Args... args)
    {
        return hardShutdownHighAlarmDeasserted(std::forward<Args>(args)...);
    }

    template <typename... Args>
    auto alarmLowSignalAsserted(Args... args)
    {
        return hardShutdownLowAlarmAsserted(std::forward<Args>(args)...);
    }

    template <typename... Args>
    auto alarmLowSignalDeasserted(Args... args)
    {
        return hardShutdownLowAlarmDeasserted(std::forward<Args>(args)...);
    }
};

template <>
struct Threshold<PerformanceLossObject> :
    public PerformanceLossObject,
    public Hysteresis
{
    static constexpr auto name = "PerformanceLoss";
    using PerformanceLossObject::PerformanceLossObject;
    double performanceLossHighHysteresis;
    double performanceLossLowHysteresis;

    auto high()
    {
        return performanceLossHigh();
    }
    auto low()
    {
        return performanceLossLow();
    }

    template <typename... Args>
    auto alarmHigh(Args... args)
    {
        return performanceLossAlarmHigh(std::forward<Args>(args)...);
    }

    template <typename... Args>
    auto alarmLow(Args... args)
    {
        return performanceLossAlarmLow(std::forward<Args>(args)...);
    }

    template <typename... Args>
    auto alarmHighSignalAsserted(Args... args)
    {
        return performanceLossHighAlarmAsserted(std::forward<Args>(args)...);
    }

    template <typename... Args>
    auto alarmHighSignalDeasserted(Args... args)
    {
        return performanceLossHighAlarmDeasserted(std::forward<Args>(args)...);
    }

    template <typename... Args>
    auto alarmLowSignalAsserted(Args... args)
    {
        return performanceLossLowAlarmAsserted(std::forward<Args>(args)...);
    }

    template <typename... Args>
    auto alarmLowSignalDeasserted(Args... args)
    {
        return performanceLossLowAlarmDeasserted(std::forward<Args>(args)...);
    }
};

} // namespace phosphor::virtualSensor
