#ifndef CONTROLLER_REGISTRY_HPP_
#define CONTROLLER_REGISTRY_HPP_

#include <functional>
#include <unordered_map>
#include <string>

#include <Controller/Controller.hpp>

/**
 * @brief Maps controller IDs to factories.
 */
class ControllerRegistry
{
private:
    typedef std::function<std::unique_ptr<Controller>(ControllerChannel &)> Factory;

    std::unordered_map<std::string, Factory> m_factories;

    template<typename TController, typename... TArgs>
    void registerController(std::string id, TArgs... args)
    {
        m_factories[id] = [args...](ControllerChannel &channel) -> std::unique_ptr<Controller>
        {
            return std::make_unique<TController>(channel, args...);
        };
    }

public:
    /**
     * @brief Register all controllers.
     */
    void registerAllControllers();

    /**
     * @brief Create a controller instance.
     * 
     * @param channel The channel we are creating on.
     * @param id The controller ID.
     * @return Pointer to the controller, or `nullptr` if the `id` is invalid.
     */
    std::unique_ptr<Controller> createController(ControllerChannel &channel, std::string id);
};

extern ControllerRegistry controllerRegistry;

#endif