#pragma once
#include <string>
#include <spdlog/spdlog.h>
#include "../../scheduler/async_executor.hpp"
#include "../../service/base/registry.hpp"
#include "../../protocol/protocol.hpp"

namespace lsp::provider
{
    enum class ServerLifecycleEvent
    {
        kInitializing,
        kInitialized,
        kInitializeFailed,
        kShuttingDown,
        kShutdown
    };

    using LifecycleCallback = std::function<void(ServerLifecycleEvent)>;

    class ExecutionContext
    {
    public:
        ExecutionContext(LifecycleCallback lifecycle_callback, scheduler::AsyncExecutor& scheduler, service::Registry& registry) :
            lifecycle_callback_(lifecycle_callback), async_executor_(scheduler), service_registry_(registry) {}

        scheduler::AsyncExecutor& GetScheduler() const { return async_executor_; }

        template<typename T>
        std::shared_ptr<T> GetService() const
        {
            return service_registry_.GetService<T>();
        }

        void TriggerLifecycleEvent(ServerLifecycleEvent event) const
        {
            if (lifecycle_callback_)
                lifecycle_callback_(event);
        }

    private:
        LifecycleCallback lifecycle_callback_;
        scheduler::AsyncExecutor& async_executor_;
        service::Registry& service_registry_;
    };

    // LSP请求提供者接口基类
    class IProvider
    {
    public:
        virtual ~IProvider() = default;

        // 获取支持的LSP方法名
        virtual std::string GetMethod() const = 0;
        // 获取提供者名称（用于日志和调试）
        virtual std::string GetProviderName() const = 0;
    };

    // LSP 请求处理器接口
    class IRequestProvider : public IProvider
    {
    public:
        virtual ~IRequestProvider() = default;

        // 处理LSP请求
        virtual std::string ProvideResponse(const protocol::RequestMessage& request, ExecutionContext& execution_context) = 0;
    };

    // LSP 通知处理器接口
    class INotificationProvider : public IProvider
    {
    public:
        virtual ~INotificationProvider() = default;

        // 处理LSP通知
        virtual void HandleNotification(const protocol::NotificationMessage& notification, ExecutionContext& execution_context) = 0;
    };

    std::string BuildErrorResponseMessage(const protocol::RequestMessage& request, protocol::ErrorCodes code, const std::string& message);
}
