#include "LeakGPIODetector.hpp"

#include "LeakEvents.hpp"
#include "SystemdInterface.hpp"

#include <sdbusplus/async.hpp>
#include <sdbusplus/message/native_types.hpp>
#include <xyz/openbmc_project/Association/Definitions/aserver.hpp>
#include <xyz/openbmc_project/State/Leak/Detector/aserver.hpp>

#include <array>
#include <functional>
#include <string>
#include <string_view>
#include <tuple>
#include <vector>

namespace leak
{

namespace config
{

/** @brief Leak level to systemd target service map */
static constexpr auto leakActionTargets = std::to_array<
    std::tuple<config::DetectorLevel, std::string_view, std::string_view>>(
    {{config::DetectorLevel::warning, "assert",
      "xyz.openbmc_project.leakdetector.warning.assert@"},
     {config::DetectorLevel::warning, "deassert",
      "xyz.openbmc_project.leakdetector.warning.deassert@"},
     {config::DetectorLevel::critical, "assert",
      "xyz.openbmc_project.leakdetector.critical.assert@"},
     {config::DetectorLevel::critical, "deassert",
      "xyz.openbmc_project.leakdetector.critical.deassert@"}});
} // namespace config

static auto getObjectPath(const std::string& detectorName)
    -> sdbusplus::object_path
{
    return (sdbusplus::object_path(DetectorIntf::namespace_path::value) /
            DetectorIntf::namespace_path::detector / detectorName);
}

GPIODetector::GPIODetector(sdbusplus::async::context& ctx, Events& leakEvents,
                           const config::DetectorConfig& config) :
    DetectorIntf(ctx, getObjectPath(config.name),
                 DetectorIntf::Definitions::properties_t{},
                 DetectorIntf::Detector::properties_t{
                     config.name, DetectorState::Normal, config.type},
                 DetectorIntf::signal_action::defer_emit),
    ctx(ctx), leakEvents(leakEvents), config(config),
    gpioInterface(ctx, config.name, config.pinName,
                  (config.polarity == config::PinPolarity::activeLow),
                  std::bind_front(&GPIODetector::updateGPIOStateAsync, this))
{
    createAssociations();
    DetectorIntf::emit_object_added();

    ctx.spawn(gpioInterface.start());

    debug("Created leak detector {NAME}", "NAME", config.name);
}

auto GPIODetector::createAssociations() -> void
{
    using association_t = std::tuple<std::string, std::string, std::string>;
    using association_list_t = std::vector<association_t>;
    association_list_t associationList;

    association_t association = {"monitoring", "monitored_by",
                                 config.parentInventoryPath};

    associationList.emplace_back(association);

    associations(associationList);
}

auto GPIODetector::updateGPIOStateAsync(bool gpioState)
    -> sdbusplus::async::task<>
{
    auto newState = gpioState ? DetectorIntf::DetectorState::Abnormal
                              : DetectorIntf::DetectorState::Normal;

    debug("Updating detector {DETECTOR} state to {STATE}", "DETECTOR",
          config.name, "STATE", newState);

    if (newState != state())
    {
        state(newState);

        co_await leakEvents.generateLeakEvent(getObjectPath(config.name),
                                              state(), config.level);
        std::string action = (state() == DetectorIntf::DetectorState::Normal)
                                 ? "deassert"
                                 : "assert";

        for (const auto& [level, action_str, serviceSuffix] :
             config::leakActionTargets)
        {
            if (config.level == level && action_str == action)
            {
                auto target = std::string(serviceSuffix) + config.name +
                              ".service";
                debug("Starting systemd target {TARGET}", "TARGET", target);
                co_await systemd::SystemdInterface::startUnit(ctx, target);
                break;
            }
        }
    }

    co_return;
}

} // namespace leak
