#pragma once

#include "report.hpp"
#include "types/duration_types.hpp"
#include "types/trigger_types.hpp"
#include "utils/dbus_path_utils.hpp"
#include "utils/transform.hpp"

#include <sdbusplus/message.hpp>

#include <chrono>
#include <utility>

using sdbusplus::message::object_path;

class TriggerParams
{
  public:
    TriggerParams()
    {
        reportsProperty = utils::transform(reportIdsProperty,
                                           [](const auto& id) {
            return utils::pathAppend(utils::constants::reportDirPath, id);
        });
    }

    TriggerParams& id(std::string_view val)
    {
        idProperty = val;
        return *this;
    }

    const std::string& id() const
    {
        return idProperty;
    }

    TriggerParams& name(std::string_view val)
    {
        nameProperty = val;
        return *this;
    }

    const std::string& name() const
    {
        return nameProperty;
    }

    TriggerParams& triggerActions(const std::vector<TriggerAction>& val)
    {
        triggerActionsProperty = val;
        return *this;
    }

    const std::vector<TriggerAction>& triggerActions() const
    {
        return triggerActionsProperty;
    }

    const std::vector<LabeledSensorInfo>& sensors() const
    {
        return labeledSensorsProperty;
    }

    const std::vector<std::string>& reportIds() const
    {
        return reportIdsProperty;
    }

    TriggerParams& reportIds(std::vector<std::string> val)
    {
        reportIdsProperty = std::move(val);
        reportsProperty = utils::transform<std::vector>(reportIdsProperty,
                                                        [](const auto& id) {
            return utils::pathAppend(utils::constants::reportDirPath, id);
        });
        return *this;
    }

    const std::vector<object_path>& reports() const
    {
        return reportsProperty;
    }

    TriggerParams& reports(std::vector<object_path> val)
    {
        reportsProperty = std::move(val);
        return *this;
    }

    TriggerParams& thresholdParams(LabeledTriggerThresholdParams val)
    {
        labeledThresholdsProperty = std::move(val);
        return *this;
    }

    const LabeledTriggerThresholdParams& thresholdParams() const
    {
        return labeledThresholdsProperty;
    }

  private:
    std::string idProperty = "Trigger1";
    std::string nameProperty = "My Numeric Trigger";
    std::vector<TriggerAction> triggerActionsProperty = {
        TriggerAction::UpdateReport};
    std::vector<LabeledSensorInfo> labeledSensorsProperty = {
        {"service1", "/xyz/openbmc_project/sensors/temperature/BMC_Temp",
         "metadata1"}};
    std::vector<std::string> reportIdsProperty = {"Report1",
                                                  "Prefixed/Report2"};
    std::vector<object_path> reportsProperty;
    LabeledTriggerThresholdParams labeledThresholdsProperty =
        std::vector<numeric::LabeledThresholdParam>{
            numeric::LabeledThresholdParam{numeric::Type::lowerCritical,
                                           Milliseconds(10).count(),
                                           numeric::Direction::decreasing, 0.5},
            numeric::LabeledThresholdParam{
                numeric::Type::upperCritical, Milliseconds(10).count(),
                numeric::Direction::increasing, 90.2}};
};
