#include "numeric_threshold.hpp"

#include <phosphor-logging/log.hpp>

NumericThreshold::NumericThreshold(
    boost::asio::io_context& ioc, const std::string& triggerIdIn,
    Sensors sensorsIn,
    std::vector<std::unique_ptr<interfaces::TriggerAction>> actionsIn,
    Milliseconds dwellTimeIn, numeric::Direction directionIn,
    double thresholdValueIn, numeric::Type typeIn,
    std::unique_ptr<interfaces::Clock> clockIn) :
    ioc(ioc),
    triggerId(triggerIdIn), actions(std::move(actionsIn)),
    dwellTime(dwellTimeIn), direction(directionIn),
    thresholdValue(thresholdValueIn), type(typeIn), clock(std::move(clockIn))
{
    for (const auto& sensor : sensorsIn)
    {
        sensorDetails.emplace(sensor, makeDetails(sensor->getName()));
    }
}

void NumericThreshold::initialize()
{
    ThresholdOperations().initialize(this);
}

void NumericThreshold::updateSensors(Sensors newSensors)
{
    ThresholdOperations().updateSensors(this, std::move(newSensors));
}

NumericThreshold::ThresholdDetail&
    NumericThreshold::getDetails(const interfaces::Sensor& sensor)
{
    return ThresholdOperations().getDetails(this, sensor);
}

std::shared_ptr<NumericThreshold::ThresholdDetail>
    NumericThreshold::makeDetails(const std::string& sensorName)
{
    return std::make_shared<ThresholdDetail>(sensorName, thresholdValue, false,
                                             ioc);
}

void NumericThreshold::sensorUpdated(interfaces::Sensor& sensor,
                                     Milliseconds timestamp, double value)
{
    auto& details = getDetails(sensor);
    auto& [sensorName, prevValue, dwell, timer] = details;
    bool decreasing = thresholdValue < prevValue && thresholdValue > value;
    bool increasing = thresholdValue > prevValue && thresholdValue < value;

    if (dwell && (increasing || decreasing))
    {
        timer.cancel();
        dwell = false;
    }
    if ((direction == numeric::Direction::decreasing && decreasing) ||
        (direction == numeric::Direction::increasing && increasing) ||
        (direction == numeric::Direction::either && (increasing || decreasing)))
    {
        startTimer(details, value);
    }

    prevValue = value;
}

void NumericThreshold::startTimer(NumericThreshold::ThresholdDetail& details,
                                  double value)
{
    const auto& sensorName = details.sensorName;
    auto& dwell = details.dwell;
    auto& timer = details.timer;

    if (dwellTime == Milliseconds::zero())
    {
        commit(sensorName, value);
    }
    else
    {
        dwell = true;
        timer.expires_after(dwellTime);
        timer.async_wait([this, &sensorName, &dwell,
                          value](const boost::system::error_code ec) {
            if (ec)
            {
                phosphor::logging::log<phosphor::logging::level::DEBUG>(
                    "Timer has been canceled");
                return;
            }
            commit(sensorName, value);
            dwell = false;
        });
    }
}

void NumericThreshold::commit(const std::string& sensorName, double value)
{
    Milliseconds timestamp = clock->systemTimestamp();
    for (const auto& action : actions)
    {
        action->commit(triggerId, std::nullopt, sensorName, timestamp, value);
    }
}

LabeledThresholdParam NumericThreshold::getThresholdParam() const
{
    return numeric::LabeledThresholdParam(type, dwellTime.count(), direction,
                                          thresholdValue);
}
