#include "utils/conversion_trigger.hpp"

#include "utils/transform.hpp"
#include "utils/tstring.hpp"

#include <sdbusplus/exception.hpp>

namespace utils
{
namespace ts = utils::tstring;

LabeledTriggerThresholdParams ToLabeledThresholdParamConversion::operator()(
    const std::monostate& arg) const
{
    throw sdbusplus::exception::SdBusError(
        static_cast<int>(std::errc::invalid_argument),
        "Provided threshold parameter is invalid");
}

LabeledTriggerThresholdParams ToLabeledThresholdParamConversion::operator()(
    const std::vector<numeric::ThresholdParam>& arg) const
{
    return utils::transform(arg, [](const auto& thresholdParam) {
        const auto& [type, dwellTime, direction, thresholdValue] =
            thresholdParam;
        return numeric::LabeledThresholdParam(numeric::toType(type), dwellTime,
                                              numeric::toDirection(direction),
                                              thresholdValue);
    });
}

LabeledTriggerThresholdParams ToLabeledThresholdParamConversion::operator()(
    const std::vector<discrete::ThresholdParam>& arg) const
{
    return utils::transform(arg, [](const auto& thresholdParam) {
        const auto& [userId, severity, dwellTime, thresholdValue] =
            thresholdParam;
        return discrete::LabeledThresholdParam(
            userId, discrete::toSeverity(severity), dwellTime, thresholdValue);
    });
}

TriggerThresholdParams FromLabeledThresholdParamConversion::operator()(
    const std::vector<numeric::LabeledThresholdParam>& arg) const
{
    return utils::transform(
        arg, [](const numeric::LabeledThresholdParam& labeledThresholdParam) {
            return numeric::ThresholdParam(
                numeric::typeToString(
                    labeledThresholdParam.at_label<ts::Type>()),
                labeledThresholdParam.at_label<ts::DwellTime>(),
                numeric::directionToString(
                    labeledThresholdParam.at_label<ts::Direction>()),
                labeledThresholdParam.at_label<ts::ThresholdValue>());
        });
}

TriggerThresholdParams FromLabeledThresholdParamConversion::operator()(
    const std::vector<discrete::LabeledThresholdParam>& arg) const
{
    return utils::transform(
        arg, [](const discrete::LabeledThresholdParam& labeledThresholdParam) {
            return discrete::ThresholdParam(
                labeledThresholdParam.at_label<ts::UserId>(),
                discrete::severityToString(
                    labeledThresholdParam.at_label<ts::Severity>()),
                labeledThresholdParam.at_label<ts::DwellTime>(),
                labeledThresholdParam.at_label<ts::ThresholdValue>());
        });
}

SensorsInfo fromLabeledSensorsInfo(const std::vector<LabeledSensorInfo>& infos)
{
    return utils::transform(infos, [](const LabeledSensorInfo& val) {
        return SensorsInfo::value_type(
            sdbusplus::message::object_path(val.at_label<ts::Path>()),
            val.at_label<ts::Metadata>());
    });
}

TriggerThresholdParams
    fromLabeledThresholdParam(const std::vector<LabeledThresholdParam>& params)
{
    namespace ts = utils::tstring;
    if (isFirstElementOfType<std::monostate>(params))
    {
        return std::vector<discrete::ThresholdParam>();
    }

    if (isFirstElementOfType<discrete::LabeledThresholdParam>(params))
    {
        return utils::transform(params, [](const auto& param) {
            const discrete::LabeledThresholdParam* paramUnpacked =
                std::get_if<discrete::LabeledThresholdParam>(&param);
            if (!paramUnpacked)
            {
                throw std::runtime_error(
                    "Mixing threshold types is not allowed");
            }
            return discrete::ThresholdParam(
                paramUnpacked->at_label<ts::UserId>(),
                discrete::severityToString(
                    paramUnpacked->at_label<ts::Severity>()),
                paramUnpacked->at_label<ts::DwellTime>(),
                paramUnpacked->at_label<ts::ThresholdValue>());
        });
    }

    if (isFirstElementOfType<numeric::LabeledThresholdParam>(params))
    {
        return utils::transform(params, [](const auto& param) {
            const numeric::LabeledThresholdParam* paramUnpacked =
                std::get_if<numeric::LabeledThresholdParam>(&param);
            if (!paramUnpacked)
            {
                throw std::runtime_error(
                    "Mixing threshold types is not allowed");
            }
            return numeric::ThresholdParam(
                numeric::typeToString(paramUnpacked->at_label<ts::Type>()),
                paramUnpacked->at_label<ts::DwellTime>(),
                numeric::directionToString(
                    paramUnpacked->at_label<ts::Direction>()),
                paramUnpacked->at_label<ts::ThresholdValue>());
        });
    }

    throw std::runtime_error("Incorrect threshold params");
}

nlohmann::json labeledThresholdParamsToJson(
    const LabeledTriggerThresholdParams& labeledThresholdParams)
{
    return std::visit([](const auto& lt) { return nlohmann::json(lt); },
                      labeledThresholdParams);
}

} // namespace utils
