#pragma once

#include "env.hpp"
#include "fan_pwm.hpp"
#include "fan_speed.hpp"
#include "hwmonio.hpp"

#include <phosphor-logging/elog-errors.hpp>
#include <phosphor-logging/log.hpp>
#include <xyz/openbmc_project/Sensor/Device/error.hpp>

#include <filesystem>
#include <format>
#include <memory>

enum class targetType
{
    DEFAULT,
    RPM,
    PWM
};

static constexpr auto RPM_TARGET = "RPM";
static constexpr auto PWM_TARGET = "PWM";

/** @class Targets
 *  @brief Target type traits.
 *
 *  @tparam T - The target type.
 */
template <typename T>
struct Targets
{
    static void fail()
    {
        static_assert(sizeof(Targets) == -1, "Unsupported Target type");
    }
};

/**@brief Targets specialization for fan speed. */
template <>
struct Targets<hwmon::FanSpeed>
{
    static constexpr InterfaceType type = InterfaceType::FAN_SPEED;
};

template <>
struct Targets<hwmon::FanPwm>
{
    static constexpr InterfaceType type = InterfaceType::FAN_PWM;
};

/** @brief addTarget
 *
 *  Creates the target type interface
 *
 *  @tparam T - The target type
 *
 *  @param[in] sensor - A sensor type and name
 *  @param[in] ioAccess - hwmon sysfs access object
 *  @param[in] devPath - The /sys/devices sysfs path
 *  @param[in] info - The sdbusplus server connection and interfaces
 *
 *  @return A shared pointer to the target interface object
 *          Will be empty if no interface was created
 */
template <typename T>
std::shared_ptr<T> addTarget(const SensorSet::key_type& sensor,
                             const hwmonio::HwmonIOInterface* ioAccess,
                             const std::string& devPath, ObjectInfo& info)
{
    std::shared_ptr<T> target;
    namespace fs = std::filesystem;

    auto& obj = std::get<InterfaceMap>(info);
    auto& objPath = std::get<std::string>(info);
    auto type = Targets<T>::type;

    // Check if target sysfs file exists
    std::string sysfsFullPath;
    std::string targetName = sensor.first;
    std::string targetId = sensor.second;
    std::string entry = hwmon::entry::target;

    using namespace std::literals;
    const std::string pwm = "pwm"s;
    const std::string empty = ""s;

    if (InterfaceType::FAN_PWM == type)
    {
        targetName = pwm;
        // If PWM_TARGET is set, use the specified pwm id
        auto id = env::getEnv("PWM_TARGET", sensor);
        if (!id.empty())
        {
            targetId = id;
        }
        entry = empty;
    }

    sysfsFullPath =
        sysfs::make_sysfs_path(ioAccess->path(), targetName, targetId, entry);
    if (fs::exists(sysfsFullPath))
    {
        auto useTarget = true;
        auto tmEnv = env::getEnv("TARGET_MODE");
        if (!tmEnv.empty())
        {
            std::string mode{tmEnv};
            std::transform(mode.begin(), mode.end(), mode.begin(), toupper);

            if (mode == RPM_TARGET)
            {
                if (type != InterfaceType::FAN_SPEED)
                {
                    useTarget = false;
                }
            }
            else if (mode == PWM_TARGET)
            {
                if (type != InterfaceType::FAN_PWM)
                {
                    useTarget = false;
                }
            }
            else
            {
                using namespace phosphor::logging;
                log<level::ERR>(
                    "Invalid TARGET_MODE env var found",
                    phosphor::logging::entry("TARGET_MODE=%s", tmEnv.c_str()),
                    phosphor::logging::entry("DEVPATH=%s", devPath.c_str()));
            }
        }

        if (useTarget)
        {
            uint32_t targetSpeed = 0;

            try
            {
                targetSpeed = ioAccess->read(targetName, targetId, entry,
                                             hwmonio::retries, hwmonio::delay);
            }
            catch (const std::system_error& e)
            {
                using namespace phosphor::logging;
                using namespace sdbusplus::xyz::openbmc_project::Sensor::
                    Device::Error;
                using metadata =
                    xyz::openbmc_project::Sensor::Device::ReadFailure;

                report<ReadFailure>(
                    metadata::CALLOUT_ERRNO(e.code().value()),
                    metadata::CALLOUT_DEVICE_PATH(devPath.c_str()));

                log<level::INFO>(std::format("Failing sysfs file: {} errno: {}",
                                             sysfsFullPath, e.code().value())
                                     .c_str());
            }

            static constexpr bool deferSignals = true;
            auto& bus = *std::get<sdbusplus::bus_t*>(info);

            // ioAccess->path() is a path like: /sys/class/hwmon/hwmon1
            // NOTE: When unit-testing, the target won't have an inject-ible
            // ioAccess: fan_pwm/fan_speed.
            target = std::make_shared<T>(
                std::move(std::make_unique<hwmonio::HwmonIO>(ioAccess->path())),
                devPath, targetId, bus, objPath.c_str(), deferSignals,
                targetSpeed);
            obj[type] = target;
        }
    }

    return target;
}
