#pragma once

#include "Utils.hpp"

#include <boost/asio/io_context.hpp>
#include <boost/asio/steady_timer.hpp>
#include <nlohmann/json.hpp>

#include <list>
#include <memory>
#include <string>
#include <utility>
#include <vector>

struct Sensor;
namespace thresholds
{
enum class Level
{
    WARNING,
    CRITICAL,
    PERFORMANCELOSS,
    SOFTSHUTDOWN,
    HARDSHUTDOWN,
    ERROR
};
enum class Direction
{
    HIGH,
    LOW,
    ERROR
};
struct Threshold
{
    Threshold(
        const Level& lev, const Direction& dir, const double& val,
        const double hysteresis = std::numeric_limits<double>::quiet_NaN(),
        bool write = true) :
        level(lev),
        direction(dir), value(val), hysteresis(hysteresis), writeable(write)
    {}
    Level level;
    Direction direction;
    double value;
    double hysteresis;
    bool writeable;

    bool operator==(const Threshold& rhs) const
    {
        return (level == rhs.level && direction == rhs.direction &&
                value == rhs.value);
    }
};

void assertThresholds(Sensor* sensor, double assertValue,
                      thresholds::Level level, thresholds::Direction direction,
                      bool assert);

struct TimerUsed
{
    bool used;
    Level level;
    Direction direction;
    bool assert;
};

using TimerPair = std::pair<struct TimerUsed, boost::asio::steady_timer>;

struct ThresholdTimer
{
    explicit ThresholdTimer(boost::asio::io_context& ioService) : io(ioService)
    {}

    bool hasActiveTimer(const Threshold& threshold, bool assert)
    {
        for (TimerPair& timer : timers)
        {
            if (timer.first.used)
            {
                if ((timer.first.level == threshold.level) &&
                    (timer.first.direction == threshold.direction) &&
                    (timer.first.assert == assert))
                {
                    return true;
                }
            }
        }
        return false;
    }

    void stopTimer(const Threshold& threshold, bool assert)
    {
        struct TimerUsed timerUsed = {};
        for (TimerPair& timer : timers)
        {
            timerUsed = timer.first;
            if (timerUsed.used)
            {
                if ((timerUsed.level == threshold.level) &&
                    (timerUsed.direction == threshold.direction) &&
                    (timerUsed.assert == assert))
                {
                    timer.second.cancel();
                }
            }
        }
    }

    void startTimer(const std::weak_ptr<Sensor>& weakSensor,
                    const Threshold& threshold, bool assert,
                    double assertValue);

    boost::asio::io_context& io;
    std::list<TimerPair> timers;
};

bool parseThresholdsFromConfig(
    const SensorData& sensorData,
    std::vector<thresholds::Threshold>& thresholdVector,
    const std::string* matchLabel = nullptr, const int* sensorIndex = nullptr);

// Sensors touched by parseThresholdFromAttr() are forcibly updated with given
// parameters, so callers are encouraged to specify a sane hysteresis value for
// their HW. For reference, the hysteresis fomula used in Sensor.hpp is:
//  hysteresis.trigger = (max_val - min_val) * 0.01
bool parseThresholdsFromAttr(
    std::vector<thresholds::Threshold>& thresholdVector,
    const std::string& inputPath, const double& scaleFactor,
    const double& offset = 0,
    const double& hysteresis = std::numeric_limits<double>::quiet_NaN());

struct ThresholdDefinition
{
    Level level;
    uint8_t sevOrder;
    const char* levelName;
};

constexpr static std::array<thresholds::ThresholdDefinition, 5> thresProp = {
    {{Level::WARNING, 0, "Warning"},
     {Level::CRITICAL, 1, "Critical"},
     {Level::PERFORMANCELOSS, 2, "PerformanceLoss"},
     {Level::SOFTSHUTDOWN, 3, "SoftShutdown"},
     {Level::HARDSHUTDOWN, 4, "HardShutdown"}}};

std::string getInterface(Level level);

void persistThreshold(const std::string& path, const std::string& baseInterface,
                      const thresholds::Threshold& threshold,
                      std::shared_ptr<sdbusplus::asio::connection>& conn,
                      size_t thresholdCount, const std::string& label);

void updateThresholds(Sensor* sensor);
// returns false if a critical threshold has been crossed, true otherwise
bool checkThresholds(Sensor* sensor);
void checkThresholdsPowerDelay(const std::weak_ptr<Sensor>& weakSensor,
                               ThresholdTimer& thresholdTimer);

} // namespace thresholds
