#include <Thresholds.hpp>
#include <VariantVisitors.hpp>
#include <boost/algorithm/string/replace.hpp>
#include <boost/lexical_cast.hpp>
#include <cmath>
#include <fstream>
#include <iostream>
#include <sensor.hpp>

static constexpr bool DEBUG = false;
namespace thresholds
{
unsigned int toBusValue(const Level& level)
{
    switch (level)
    {
        case (Level::WARNING):
        {
            return 0;
        }
        case (Level::CRITICAL):
        {
            return 1;
        }
        default:
        {
            return -1;
        }
    }
}

std::string toBusValue(const Direction& direction)
{
    switch (direction)
    {
        case (Direction::LOW):
        {
            return "less than";
        }
        case (Direction::HIGH):
        {
            return "greater than";
        }
        default:
        {
            return "err";
        }
    }
}

bool parseThresholdsFromConfig(
    const SensorData& sensorData,
    std::vector<thresholds::Threshold>& thresholdVector,
    const std::string* matchLabel)
{
    for (const auto& item : sensorData)
    {
        if (item.first.find("Thresholds") == std::string::npos)
        {
            continue;
        }
        if (matchLabel != nullptr)
        {
            auto labelFind = item.second.find("Label");
            if (labelFind == item.second.end())
                continue;
            if (std::visit(VariantToStringVisitor(), labelFind->second) !=
                *matchLabel)
                continue;
        }
        auto directionFind = item.second.find("Direction");
        auto severityFind = item.second.find("Severity");
        auto valueFind = item.second.find("Value");
        if (valueFind == item.second.end() ||
            severityFind == item.second.end() ||
            directionFind == item.second.end())
        {
            std::cerr << "Malformed threshold in configuration\n";
            return false;
        }
        Level level;
        Direction direction;
        if (std::visit(VariantToUnsignedIntVisitor(), severityFind->second) ==
            0)
        {
            level = Level::WARNING;
        }
        else
        {
            level = Level::CRITICAL;
        }
        if (std::visit(VariantToStringVisitor(), directionFind->second) ==
            "less than")
        {
            direction = Direction::LOW;
        }
        else
        {
            direction = Direction::HIGH;
        }
        double val = std::visit(VariantToDoubleVisitor(), valueFind->second);

        thresholdVector.emplace_back(level, direction, val);
    }
    return true;
}

void persistThreshold(const std::string& path, const std::string& baseInterface,
                      const thresholds::Threshold& threshold,
                      std::shared_ptr<sdbusplus::asio::connection>& conn,
                      size_t thresholdCount)
{
    for (int ii = 0; ii < thresholdCount; ii++)
    {
        std::string thresholdInterface =
            baseInterface + ".Thresholds" + std::to_string(ii);
        conn->async_method_call(
            [&, path, threshold, thresholdInterface](
                const boost::system::error_code& ec,
                const boost::container::flat_map<std::string, BasicVariantType>&
                    result) {
                if (ec)
                {
                    return; // threshold not supported
                }

                auto directionFind = result.find("Direction");
                auto severityFind = result.find("Severity");
                auto valueFind = result.find("Value");
                if (valueFind == result.end() || severityFind == result.end() ||
                    directionFind == result.end())
                {
                    std::cerr << "Malformed threshold in configuration\n";
                    return;
                }
                unsigned int level = std::visit(VariantToUnsignedIntVisitor(),
                                                severityFind->second);

                std::string dir =
                    std::visit(VariantToStringVisitor(), directionFind->second);
                if ((toBusValue(threshold.level) != level) ||
                    (toBusValue(threshold.direction) != dir))
                {
                    return; // not the droid we're looking for
                }

                std::variant<double> value(threshold.value);
                conn->async_method_call(
                    [](const boost::system::error_code& ec) {
                        if (ec)
                        {
                            std::cerr << "Error setting threshold " << ec
                                      << "\n";
                        }
                    },
                    entityManagerName, path, "org.freedesktop.DBus.Properties",
                    "Set", thresholdInterface, "Value", value);
            },
            entityManagerName, path, "org.freedesktop.DBus.Properties",
            "GetAll", thresholdInterface);
    }
}

void updateThresholds(Sensor* sensor)
{
    if (sensor->thresholds.empty())
    {
        return;
    }

    for (const auto& threshold : sensor->thresholds)
    {
        std::shared_ptr<sdbusplus::asio::dbus_interface> interface;
        std::string property;
        if (threshold.level == thresholds::Level::CRITICAL)
        {
            interface = sensor->thresholdInterfaceCritical;
            if (threshold.direction == thresholds::Direction::HIGH)
            {
                property = "CriticalHigh";
            }
            else
            {
                property = "CriticalLow";
            }
        }
        else if (threshold.level == thresholds::Level::WARNING)
        {
            interface = sensor->thresholdInterfaceWarning;
            if (threshold.direction == thresholds::Direction::HIGH)
            {
                property = "WarningHigh";
            }
            else
            {
                property = "WarningLow";
            }
        }
        else
        {
            continue;
        }
        if (!interface)
        {
            continue;
        }
        interface->set_property(property, threshold.value);
    }
}

static std::vector<std::pair<Threshold, bool>> checkThresholds(Sensor* sensor,
                                                               double value)
{
    std::vector<std::pair<Threshold, bool>> thresholdChanges;
    if (sensor->thresholds.empty())
    {
        return thresholdChanges;
    }

    for (auto& threshold : sensor->thresholds)
    {
        if (threshold.direction == thresholds::Direction::HIGH)
        {
            if (value > threshold.value)
            {
                thresholdChanges.push_back(std::make_pair(threshold, true));
            }
            else if (value <= threshold.value)
            {
                thresholdChanges.push_back(std::make_pair(threshold, false));
            }
        }
        else
        {
            if (value < threshold.value)
            {
                thresholdChanges.push_back(std::make_pair(threshold, true));
            }
            else if (value >= threshold.value)
            {
                thresholdChanges.push_back(std::make_pair(threshold, false));
            }
        }
    }
    return thresholdChanges;
}

bool checkThresholds(Sensor* sensor)
{
    bool status = true;
    std::vector<std::pair<Threshold, bool>> changes =
        checkThresholds(sensor, sensor->value);
    for (const auto& [threshold, asserted] : changes)
    {
        assertThresholds(sensor, threshold.level, threshold.direction,
                         asserted);
        if (threshold.level == thresholds::Level::CRITICAL && asserted)
        {
            status = false;
        }
    }

    return status;
}

void checkThresholdsPowerDelay(Sensor* sensor, ThresholdTimer& thresholdTimer)
{

    std::vector<std::pair<Threshold, bool>> changes =
        checkThresholds(sensor, sensor->value);
    for (const auto& [threshold, asserted] : changes)
    {
        if (asserted)
        {
            thresholdTimer.startTimer(threshold);
        }
        else
        {
            assertThresholds(sensor, threshold.level, threshold.direction,
                             false);
        }
    }
}

void assertThresholds(Sensor* sensor, thresholds::Level level,
                      thresholds::Direction direction, bool assert)
{
    std::string property;
    std::shared_ptr<sdbusplus::asio::dbus_interface> interface;
    if (level == thresholds::Level::WARNING &&
        direction == thresholds::Direction::HIGH)
    {
        property = "WarningAlarmHigh";
        interface = sensor->thresholdInterfaceWarning;
    }
    else if (level == thresholds::Level::WARNING &&
             direction == thresholds::Direction::LOW)
    {
        property = "WarningAlarmLow";
        interface = sensor->thresholdInterfaceWarning;
    }
    else if (level == thresholds::Level::CRITICAL &&
             direction == thresholds::Direction::HIGH)
    {
        property = "CriticalAlarmHigh";
        interface = sensor->thresholdInterfaceCritical;
    }
    else if (level == thresholds::Level::CRITICAL &&
             direction == thresholds::Direction::LOW)
    {
        property = "CriticalAlarmLow";
        interface = sensor->thresholdInterfaceCritical;
    }
    else
    {
        std::cerr << "Unknown threshold, level " << level << "direction "
                  << direction << "\n";
        return;
    }
    if (!interface)
    {
        std::cout << "trying to set uninitialized interface\n";
        return;
    }
    interface->set_property(property, assert);
}

static constexpr std::array<const char*, 4> attrTypes = {"lcrit", "min", "max",
                                                         "crit"};

bool parseThresholdsFromAttr(
    std::vector<thresholds::Threshold>& thresholdVector,
    const std::string& inputPath, const double& scaleFactor)
{
    for (auto& type : attrTypes)
    {
        auto attrPath = boost::replace_all_copy(inputPath, "input", type);
        std::ifstream attrFile(attrPath);
        if (!attrFile.good())
        {
            continue;
        }
        std::string attr;
        std::getline(attrFile, attr);
        attrFile.close();

        Level level;
        Direction direction;
        double val = std::stod(attr) / scaleFactor;
        if (type == "min" || type == "max")
        {
            level = Level::WARNING;
        }
        else
        {
            level = Level::CRITICAL;
        }
        if (type == "min" || type == "lcrit")
        {
            direction = Direction::LOW;
        }
        else
        {
            direction = Direction::HIGH;
        }

        if (DEBUG)
        {
            std::cout << "Threshold: " << attrPath << ": " << val << "\n";
        }

        thresholdVector.emplace_back(level, direction, val);
    }
    // no thresholds is allowed, not an error so return true always
    return true;
}

bool hasCriticalInterface(
    const std::vector<thresholds::Threshold>& thresholdVector)
{
    for (auto& threshold : thresholdVector)
    {
        if (threshold.level == Level::CRITICAL)
        {
            return true;
        }
    }
    return false;
}

bool hasWarningInterface(
    const std::vector<thresholds::Threshold>& thresholdVector)
{
    for (auto& threshold : thresholdVector)
    {
        if (threshold.level == Level::WARNING)
        {
            return true;
        }
    }
    return false;
}
} // namespace thresholds
