#pragma once

#include <any>
#include <memory>
#include <mutex>
#include <shared_mutex>
#include <stdexcept>
#include <unordered_map>
#include <typeindex>
#include <spdlog/spdlog.h>

namespace lsp::service
{
    class Registry
    {
    public:
        // 注册服务
        template<typename T>
        void RegisterService(std::shared_ptr<T> service)
        {
            std::unique_lock<std::shared_mutex> lock(mutex_);
            if (!service)
                throw std::invalid_argument("Cannot register null service");
            services_[std::type_index(typeid(T))] = service;

            spdlog::info("Registered service '{}' ", std::type_index(typeid(T)).name());
        }

        // 获取服务
        template<typename T>
        std::shared_ptr<T> GetService() const
        {
            std::shared_lock<std::shared_mutex> lock(mutex_);
            auto it = services_.find(std::type_index(typeid(T)));
            if (it != services_.end())
                return std::any_cast<std::shared_ptr<T>>(it->second);
            throw std::runtime_error(std::string("Service not found:") + typeid(T).name());
        }

        size_t ServiceCount()
        {
            return services_.size();
        }

    private:
        mutable std::shared_mutex mutex_;
        std::unordered_map<std::type_index, std::any> services_;
    };
}
