#pragma once

#include "types.hpp"
#include "utils.hpp"

#include <any>
#include <map>
#include <memory>
#include <string>
#include <type_traits>
#include <utility>

namespace sdbusplus
{
namespace bus
{
class bus;
}
} // namespace sdbusplus

namespace phosphor
{
namespace inventory
{
namespace manager
{

template <typename T>
struct HasProperties
{
  private:
    using yes = char;
    struct no
    {
        char array[2];
    };

    template <typename U>
    static constexpr yes test(typename U::PropertiesVariant*);
    template <typename U>
    static constexpr no test(...);

  public:
    static constexpr auto value = sizeof(test<T>(0)) == sizeof(yes);
};

template <typename T, typename Enable = void>
struct MakeInterface
{
    static std::any op(sdbusplus::bus_t& bus, const char* path,
                       const Interface&, bool)
    {
        return std::any(std::make_shared<T>(bus, path));
    }
};

template <typename T>
struct MakeInterface<T, std::enable_if_t<HasProperties<T>::value>>
{
    static std::any op(sdbusplus::bus_t& bus, const char* path,
                       const Interface& props, bool deferSignal)
    {
        using InterfaceVariant =
            std::map<std::string, typename T::PropertiesVariant>;

        InterfaceVariant v;
        for (const auto& p : props)
        {
            v.emplace(p.first,
                      convertVariant<typename T::PropertiesVariant>(p.second));
        }

        return std::any(std::make_shared<T>(bus, path, v, deferSignal));
    }
};

template <typename T, typename Enable = void>
struct GetPropertyValue
{
    static InterfaceVariantType op(const std::string /* propertyName */,
                                   std::any& /* holder */)
    {
        return InterfaceVariantType{};
    }
};

template <typename T>
struct GetPropertyValue<T, std::enable_if_t<HasProperties<T>::value>>
{
    static InterfaceVariantType op(const std::string propertyName,
                                   std::any& holder)
    {
        auto& iface = *std::any_cast<std::shared_ptr<T>&>(holder);
        auto property = iface.getPropertyByName(propertyName);
        return convertVariant<InterfaceVariantType>(property);
    }
};

template <typename T, typename Enable = void>
struct AssignInterface
{
    static void op(const Interface&, std::any&, bool) {}
};

template <typename T>
struct AssignInterface<T, std::enable_if_t<HasProperties<T>::value>>
{
    static void op(const Interface& props, std::any& holder, bool deferSignal)
    {
        auto& iface = *std::any_cast<std::shared_ptr<T>&>(holder);
        for (const auto& p : props)
        {
            iface.setPropertyByName(
                p.first,
                convertVariant<typename T::PropertiesVariant>(p.second),
                deferSignal);
        }
    }
};

template <typename T, typename Ops, typename Enable = void>
struct SerializeInterface
{
    static void op(const std::string& path, const std::string& iface,
                   const std::any&)
    {
        Ops::serialize(path, iface);
    }
};

template <typename T, typename Ops>
struct SerializeInterface<T, Ops, std::enable_if_t<HasProperties<T>::value>>
{
    static void op(const std::string& path, const std::string& iface,
                   const std::any& holder)
    {
        const auto& object = *std::any_cast<const std::shared_ptr<T>&>(holder);
        Ops::serialize(path, iface, object);
    }
};

template <typename T, typename Ops, typename Enable = void>
struct DeserializeInterface
{
    static void op(const std::string& path, const std::string& iface, std::any&)
    {
        Ops::deserialize(path, iface);
    }
};

template <typename T, typename Ops>
struct DeserializeInterface<T, Ops, std::enable_if_t<HasProperties<T>::value>>
{
    static void op(const std::string& path, const std::string& iface,
                   std::any& holder)
    {
        auto& object = *std::any_cast<std::shared_ptr<T>&>(holder);
        Ops::deserialize(path, iface, object);
    }
};

struct DummyInterface
{};
using MakeInterfaceType =
    std::add_pointer_t<decltype(MakeInterface<DummyInterface>::op)>;
using AssignInterfaceType =
    std::add_pointer_t<decltype(AssignInterface<DummyInterface>::op)>;
template <typename Ops>
using SerializeInterfaceType =
    std::add_pointer_t<decltype(SerializeInterface<DummyInterface, Ops>::op)>;
template <typename Ops>
using DeserializeInterfaceType =
    std::add_pointer_t<decltype(DeserializeInterface<DummyInterface, Ops>::op)>;
using GetPropertyValueType =
    std::add_pointer_t<decltype(GetPropertyValue<DummyInterface>::op)>;

} // namespace manager
} // namespace inventory
} // namespace phosphor
