#pragma once
#include "../protocol.hpp"
#include "./common.hpp"

namespace lsp::transform
{
    // LSPAny 序列化/反序列化工具类
    class LSPAnyConverter
    {
    public:
        // === 基本类型的转换 ===
        static protocol::LSPAny ToLSPAny(protocol::boolean value);
        static protocol::LSPAny ToLSPAny(int value);
        static protocol::LSPAny ToLSPAny(long value);
        static protocol::LSPAny ToLSPAny(long long value);
        static protocol::LSPAny ToLSPAny(unsigned int value);
        static protocol::LSPAny ToLSPAny(unsigned long value);
        static protocol::LSPAny ToLSPAny(unsigned long long value);
        static protocol::LSPAny ToLSPAny(float value);
        static protocol::LSPAny ToLSPAny(double value);
        static protocol::LSPAny ToLSPAny(long double value);
        static protocol::LSPAny ToLSPAny(const protocol::string& str);
        static protocol::LSPAny ToLSPAny(const char* str);
        static protocol::LSPAny ToLSPAny(std::nullptr_t);
        static protocol::LSPAny ToLSPAny(const protocol::LSPAny& any);

        // === LSPAny 到基本类型的转换 ===
        static protocol::boolean ToBool(const protocol::LSPAny& any);
        static protocol::string ToString(const protocol::LSPAny& any);

        // 其他转换
        static protocol::LSPObject ToLSPObject(const protocol::LSPAny& any);
        static protocol::LSPArray ToLSPArray(const protocol::LSPAny& any);

        // === 容器类型的转换 ===
        template<typename T>
        static protocol::LSPAny ToLSPAny(const std::vector<T>& vec);

        template<typename T>
        static protocol::LSPAny ToLSPAny(const std::map<protocol::string, T>& map);

        template<typename T>
        static protocol::LSPAny ToLSPAny(const std::optional<T>& opt);

        // === Struct 到 LSPAny 的转换 ===
        template<typename T>
        static typename std::enable_if<is_user_struct<T>::value, protocol::LSPAny>::type ToLSPAny(const T& obj);

        template<typename T>
        static typename std::enable_if<std::is_arithmetic<T>::value && !std::is_same<T, protocol::boolean>::value, T>::type ToNumber(const protocol::LSPAny& any);

        // === LSPAny 到容器类型的转换 ===
        template<typename T>
        static std::vector<T> ToVector(const protocol::LSPAny& any);

        template<typename T>
        static std::optional<T> ToOptional(const protocol::LSPAny& any);

        template<typename T>
        static typename std::enable_if<is_user_struct<T>::value, T>::type FromLSPAny(const protocol::LSPAny& any);

        // 处理 std::optional<T>
        template<typename T, typename From>
        static std::optional<T> As(const std::optional<From>& opt);

        // 处理 std::variant<Ts...>
        template<typename T, typename... Ts>
        static T As(const std::variant<Ts...>& var);

        // 处理 LSPObject 和 LSPArray
        template<typename T>
        static T As(const protocol::LSPObject& obj);

        template<typename T>
        static T As(const protocol::LSPArray& arr);


    private:
        template<typename T>
        static T FromLSPAnyImpl(const protocol::LSPAny& any);
    };

}

#include "./transformer.inl"
