#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, ioc);
}

void NumericThreshold::sensorUpdated(interfaces::Sensor& sensor,
                                     Milliseconds timestamp, double value)
{
    auto& details = getDetails(sensor);
    auto& prevValue = details.prevValue;
    auto& prevDirection = details.prevDirection;
    auto& dwell = details.dwell;
    auto& timer = details.timer;

    if (!prevValue)
    {
        prevValue = value;
        return;
    }

    bool crossedDecreasing = thresholdValue < prevValue &&
                             thresholdValue > value;
    bool crossedIncreasing = thresholdValue > prevValue &&
                             thresholdValue < value;

    if (!crossedDecreasing && !crossedIncreasing && thresholdValue == prevValue)
    {
        crossedDecreasing = prevDirection == numeric::Direction::decreasing &&
                            thresholdValue > value;
        crossedIncreasing = prevDirection == numeric::Direction::increasing &&
                            thresholdValue < value;
    }

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

    prevDirection = value > prevValue   ? numeric::Direction::increasing
                    : value < prevValue ? numeric::Direction::decreasing
                                        : numeric::Direction::either;
    prevValue = value;
}

void NumericThreshold::startTimer(NumericThreshold::ThresholdDetail& details,
                                  double value)
{
    auto& sensorName = details.getSensorName();
    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);
}
