#pragma once

#include <sdbusplus/exception.hpp>

#include <algorithm>
#include <array>
#include <stdexcept>
#include <string>

namespace utils
{

template <class T>
struct EnumTraits
{
    [[noreturn]] static void throwConversionError()
    {
        throw sdbusplus::exception::SdBusError(
            static_cast<int>(std::errc::invalid_argument),
            "Invalid enum value");
    }
};

template <class T, T first, T last>
inline T toEnum(std::underlying_type_t<T> x)
{
    if (x < static_cast<std::underlying_type_t<T>>(first) ||
        x > static_cast<std::underlying_type_t<T>>(last))
    {
        EnumTraits<T>::throwConversionError();
    }
    return static_cast<T>(x);
}

template <class T>
constexpr inline std::underlying_type_t<T> toUnderlying(T value)
{
    return static_cast<std::underlying_type_t<T>>(value);
}

template <class T, size_t N>
constexpr inline T
    minEnumValue(std::array<std::pair<std::string_view, T>, N> data)
{
    auto min = data[0].second;
    for (auto [key, value] : data)
    {
        if (toUnderlying(min) > toUnderlying(value))
        {
            min = value;
        }
    }
    return min;
}

template <class T, size_t N>
constexpr inline T
    maxEnumValue(std::array<std::pair<std::string_view, T>, N> data)
{
    auto max = data[0].second;
    for (auto [key, value] : data)
    {
        if (toUnderlying(max) < toUnderlying(value))
        {
            max = value;
        }
    }
    return max;
}

template <class T, size_t N>
inline T toEnum(const std::array<std::pair<std::string_view, T>, N>& data,
                const std::string& value)
{
    auto it = std::find_if(
        std::begin(data), std::end(data),
        [&value](const auto& item) { return item.first == value; });
    if (it == std::end(data))
    {
        EnumTraits<T>::throwConversionError();
    }
    return it->second;
}

template <class T, size_t N>
inline std::string_view
    enumToString(const std::array<std::pair<std::string_view, T>, N>& data,
                 T value)
{
    auto it = std::find_if(
        std::begin(data), std::end(data),
        [value](const auto& item) { return item.second == value; });
    if (it == std::end(data))
    {
        EnumTraits<T>::throwConversionError();
    }
    return it->first;
}

} // namespace utils
