#pragma once

#include "env.hpp"
#include "interface.hpp"

#include <cmath>

/** @class Thresholds
 *  @brief Threshold type traits.
 *
 *  @tparam T - The threshold type.
 */
template <typename T>
struct Thresholds
{
    static void fail()
    {
        static_assert(sizeof(Thresholds) == -1, "Unsupported Threshold type");
    }
};

/**@brief Thresholds specialization for warning thresholds. */
template <>
struct Thresholds<WarningObject>
{
    static constexpr InterfaceType type = InterfaceType::WARN;
    static constexpr const char* envLo = "WARNLO";
    static constexpr const char* envHi = "WARNHI";
    static SensorValueType (WarningObject::*const setLo)(SensorValueType);
    static SensorValueType (WarningObject::*const setHi)(SensorValueType);
    static SensorValueType (WarningObject::*const getLo)() const;
    static SensorValueType (WarningObject::*const getHi)() const;
    static bool (WarningObject::*const alarmLo)(bool);
    static bool (WarningObject::*const alarmHi)(bool);
    static bool (WarningObject::*const getAlarmLow)() const;
    static bool (WarningObject::*const getAlarmHigh)() const;
    static void (WarningObject::*const assertLowSignal)(SensorValueType);
    static void (WarningObject::*const assertHighSignal)(SensorValueType);
    static void (WarningObject::*const deassertLowSignal)(SensorValueType);
    static void (WarningObject::*const deassertHighSignal)(SensorValueType);
};

/**@brief Thresholds specialization for critical thresholds. */
template <>
struct Thresholds<CriticalObject>
{
    static constexpr InterfaceType type = InterfaceType::CRIT;
    static constexpr const char* envLo = "CRITLO";
    static constexpr const char* envHi = "CRITHI";
    static SensorValueType (CriticalObject::*const setLo)(SensorValueType);
    static SensorValueType (CriticalObject::*const setHi)(SensorValueType);
    static SensorValueType (CriticalObject::*const getLo)() const;
    static SensorValueType (CriticalObject::*const getHi)() const;
    static bool (CriticalObject::*const alarmLo)(bool);
    static bool (CriticalObject::*const alarmHi)(bool);
    static bool (CriticalObject::*const getAlarmLow)() const;
    static bool (CriticalObject::*const getAlarmHigh)() const;
    static void (CriticalObject::*const assertLowSignal)(SensorValueType);
    static void (CriticalObject::*const assertHighSignal)(SensorValueType);
    static void (CriticalObject::*const deassertLowSignal)(SensorValueType);
    static void (CriticalObject::*const deassertHighSignal)(SensorValueType);
};

/** @brief checkThresholds
 *
 *  Compare a sensor reading to threshold values and set the
 *  appropriate alarm property if bounds are exceeded.
 *
 *  @tparam T - The threshold type.
 *
 *  @param[in] iface - An sdbusplus server threshold instance.
 *  @param[in] value - The sensor reading to compare to thresholds.
 */
template <typename T>
void checkThresholds(std::any& iface, SensorValueType value)
{
    auto realIface = std::any_cast<std::shared_ptr<T>>(iface);
    auto lo = (*realIface.*Thresholds<T>::getLo)();
    auto hi = (*realIface.*Thresholds<T>::getHi)();
    auto alarmLowState = (*realIface.*Thresholds<T>::getAlarmLow)();
    auto alarmHighState = (*realIface.*Thresholds<T>::getAlarmHigh)();
    (*realIface.*Thresholds<T>::alarmLo)(value <= lo);
    (*realIface.*Thresholds<T>::alarmHi)(value >= hi);
    if (alarmLowState != (value <= lo))
    {
        if (value <= lo)
        {
            (*realIface.*Thresholds<T>::assertLowSignal)(value);
        }
        else
        {
            (*realIface.*Thresholds<T>::deassertLowSignal)(value);
        }
    }
    if (alarmHighState != (value >= hi))
    {
        if (value >= hi)
        {
            (*realIface.*Thresholds<T>::assertHighSignal)(value);
        }
        else
        {
            (*realIface.*Thresholds<T>::deassertHighSignal)(value);
        }
    }
}

/** @brief addThreshold
 *
 *  Look for a configured threshold value in the environment and
 *  create an sdbusplus server threshold if found.
 *
 *  @tparam T - The threshold type.
 *
 *  @param[in] sensorType - sensor type, like 'temp'
 *  @param[in] sensorID - sensor ID, like '5'
 *  @param[in] value - The sensor reading.
 *  @param[in] info - The sdbusplus server connection and interfaces.
 */
template <typename T>
auto addThreshold(const std::string& sensorType, const std::string& sensorID,
                  SensorValueType value, ObjectInfo& info, int64_t scale)
{
    auto& objPath = std::get<std::string>(info);
    auto& obj = std::get<InterfaceMap>(info);
    std::shared_ptr<T> iface;

    auto tLo = env::getEnv(Thresholds<T>::envLo, sensorType, sensorID);
    auto tHi = env::getEnv(Thresholds<T>::envHi, sensorType, sensorID);
    if (!tLo.empty() || !tHi.empty())
    {
        auto& bus = *std::get<sdbusplus::bus_t*>(info);

        iface = std::make_shared<T>(bus, objPath.c_str(),
                                    T::action::emit_no_signals);
        if (!tLo.empty())
        {
            auto lo = stod(tLo) * std::pow(10, scale);
            (*iface.*Thresholds<T>::setLo)(lo);
            auto alarmLowState = (*iface.*Thresholds<T>::getAlarmLow)();
            (*iface.*Thresholds<T>::alarmLo)(value <= lo);
            if (alarmLowState != (value <= lo))
            {
                if (value <= lo)
                {
                    (*iface.*Thresholds<T>::assertLowSignal)(value);
                }
                else
                {
                    (*iface.*Thresholds<T>::deassertLowSignal)(value);
                }
            }
        }
        if (!tHi.empty())
        {
            auto hi = stod(tHi) * std::pow(10, scale);
            (*iface.*Thresholds<T>::setHi)(hi);
            auto alarmHighState = (*iface.*Thresholds<T>::getAlarmHigh)();
            (*iface.*Thresholds<T>::alarmHi)(value >= hi);
            if (alarmHighState != (value >= hi))
            {
                if (value >= hi)
                {
                    (*iface.*Thresholds<T>::assertHighSignal)(value);
                }
                else
                {
                    (*iface.*Thresholds<T>::deassertHighSignal)(value);
                }
            }
        }
        auto type = Thresholds<T>::type;
        obj[type] = iface;
    }

    return iface;
}

// vim: tabstop=8 expandtab shiftwidth=4 softtabstop=4
