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