#include "discrete_threshold.hpp"

#include "utils/conversion_trigger.hpp"

#include <phosphor-logging/log.hpp>

DiscreteThreshold::DiscreteThreshold(
    boost::asio::io_context& ioc, const std::string& triggerIdIn,
    Sensors sensorsIn,
    std::vector<std::unique_ptr<interfaces::TriggerAction>> actionsIn,
    Milliseconds dwellTimeIn, const std::string& thresholdValueIn,
    const std::string& nameIn, const discrete::Severity severityIn,
    std::unique_ptr<interfaces::Clock> clockIn) :
    ioc(ioc),
    triggerId(triggerIdIn), actions(std::move(actionsIn)),
    dwellTime(dwellTimeIn), thresholdValue(thresholdValueIn),
    numericThresholdValue(utils::stodStrict(thresholdValue)),
    severity(severityIn), name(getNonEmptyName(nameIn)),
    clock(std::move(clockIn))
{
    for (const auto& sensor : sensorsIn)
    {
        sensorDetails.emplace(sensor, makeDetails(sensor->getName()));
    }
}

void DiscreteThreshold::initialize()
{
    ThresholdOperations::initialize(this);
}

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

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

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

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

    if (dwell && value != numericThresholdValue)
    {
        timer.cancel();
        dwell = false;
    }
    else if (value == numericThresholdValue)
    {
        startTimer(details, value);
    }
}

void DiscreteThreshold::startTimer(DiscreteThreshold::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 DiscreteThreshold::commit(const std::string& sensorName, double value)
{
    Milliseconds timestamp = clock->systemTimestamp();
    for (const auto& action : actions)
    {
        action->commit(triggerId, std::cref(name), sensorName, timestamp,
                       thresholdValue);
    }
}

LabeledThresholdParam DiscreteThreshold::getThresholdParam() const
{
    return discrete::LabeledThresholdParam(name, severity, dwellTime.count(),
                                           thresholdValue);
}

std::string DiscreteThreshold::getNonEmptyName(const std::string& nameIn) const
{
    if (nameIn.empty())
    {
        return discrete::severityToString(severity) + " condition";
    }
    return nameIn;
}
