#include "common_test.hpp"
#include <vector>
#include <map>
#include <optional>
#include <variant>
#include "../../src/protocol/transform/common.hpp"
#include "../../src/protocol/detail/basic_types.hpp"

namespace lsp::test
{
    // 用于测试的用户自定义结构体
    struct UserStruct
    {
        int value;
        std::string name;
    };

    void CommonTests::registerTests(TestRunner& runner)
    {
        // is_lsp_basic_type 测试
        runner.addTest("Common - is_lsp_basic_type (integer)", testIsLSPBasicInteger);
        runner.addTest("Common - is_lsp_basic_type (uinteger)", testIsLSPBasicUInteger);
        runner.addTest("Common - is_lsp_basic_type (boolean)", testIsLSPBasicBoolean);
        runner.addTest("Common - is_lsp_basic_type (string)", testIsLSPBasicString);
        runner.addTest("Common - is_lsp_basic_type (decimal)", testIsLSPBasicDecimal);
        runner.addTest("Common - is_lsp_basic_type (nullptr_t)", testIsLSPBasicNullptr);
        runner.addTest("Common - is_lsp_basic_type (负面案例)", testIsLSPBasicNegativeCases);

        // is_lsp_container_type 测试
        runner.addTest("Common - is_lsp_container_type (LSPObject)", testIsLSPContainerObject);
        runner.addTest("Common - is_lsp_container_type (LSPArray)", testIsLSPContainerArray);
        runner.addTest("Common - is_lsp_container_type (LSPAny)", testIsLSPContainerAny);
        runner.addTest("Common - is_lsp_container_type (负面案例)", testIsLSPContainerNegativeCases);

        // is_user_struct 测试
        runner.addTest("Common - is_user_struct (用户结构体)", testIsUserStructPositive);
        runner.addTest("Common - is_user_struct (排除算术类型)", testIsUserStructExcludeArithmetic);
        runner.addTest("Common - is_user_struct (排除字符串)", testIsUserStructExcludeString);
        runner.addTest("Common - is_user_struct (排除LSP类型)", testIsUserStructExcludeLSPTypes);
        runner.addTest("Common - is_user_struct (排除vector)", testIsUserStructExcludeVector);
        runner.addTest("Common - is_user_struct (排除map)", testIsUserStructExcludeMap);
        runner.addTest("Common - is_user_struct (排除optional)", testIsUserStructExcludeOptional);
        runner.addTest("Common - is_user_struct (排除variant)", testIsUserStructExcludeVariant);
        runner.addTest("Common - is_user_struct (排除指针)", testIsUserStructExcludePointers);
    }

    // ==================== is_lsp_basic_type 测试 ====================

    TestResult CommonTests::testIsLSPBasicInteger()
    {
        TestResult result;
        result.passed = true;

        bool is_basic = transform::is_lsp_basic_type_v<protocol::integer>;
        assertTrue(is_basic, "integer应该是LSP基本类型");

        result.message = "成功";
        return result;
    }

    TestResult CommonTests::testIsLSPBasicUInteger()
    {
        TestResult result;
        result.passed = true;

        bool is_basic = transform::is_lsp_basic_type_v<protocol::uinteger>;
        assertTrue(is_basic, "uinteger应该是LSP基本类型");

        result.message = "成功";
        return result;
    }

    TestResult CommonTests::testIsLSPBasicBoolean()
    {
        TestResult result;
        result.passed = true;

        bool is_basic = transform::is_lsp_basic_type_v<protocol::boolean>;
        assertTrue(is_basic, "boolean应该是LSP基本类型");

        result.message = "成功";
        return result;
    }

    TestResult CommonTests::testIsLSPBasicString()
    {
        TestResult result;
        result.passed = true;

        bool is_basic = transform::is_lsp_basic_type_v<protocol::string>;
        assertTrue(is_basic, "string应该是LSP基本类型");

        result.message = "成功";
        return result;
    }

    TestResult CommonTests::testIsLSPBasicDecimal()
    {
        TestResult result;
        result.passed = true;

        bool is_basic = transform::is_lsp_basic_type_v<protocol::decimal>;
        assertTrue(is_basic, "decimal应该是LSP基本类型");

        result.message = "成功";
        return result;
    }

    TestResult CommonTests::testIsLSPBasicNullptr()
    {
        TestResult result;
        result.passed = true;

        bool is_basic = transform::is_lsp_basic_type_v<std::nullptr_t>;
        assertTrue(is_basic, "nullptr_t应该是LSP基本类型");

        result.message = "成功";
        return result;
    }

    TestResult CommonTests::testIsLSPBasicNegativeCases()
    {
        TestResult result;
        result.passed = true;

        // 测试明确不是 LSP 基本类型的类型
        // 注意：避免测试 int/int32_t，因为它们可能等于 protocol::integer
        assertFalse(transform::is_lsp_basic_type_v<int64_t>,
                    "int64_t不应该是LSP基本类型");
        assertFalse(transform::is_lsp_basic_type_v<long long>,
                    "long long不应该是LSP基本类型");
        assertFalse(transform::is_lsp_basic_type_v<float>,
                    "float不应该是LSP基本类型");
        assertFalse(transform::is_lsp_basic_type_v<std::vector<int>>,
                    "vector不应该是LSP基本类型");
        assertFalse(transform::is_lsp_basic_type_v<UserStruct>,
                    "UserStruct不应该是LSP基本类型");

        result.message = "成功";
        return result;
    }

    // ==================== is_lsp_container_type 测试 ====================

    TestResult CommonTests::testIsLSPContainerObject()
    {
        TestResult result;
        result.passed = true;

        bool is_container = transform::is_lsp_container_type_v<protocol::LSPObject>;
        assertTrue(is_container, "LSPObject应该是LSP容器类型");

        result.message = "成功";
        return result;
    }

    TestResult CommonTests::testIsLSPContainerArray()
    {
        TestResult result;
        result.passed = true;

        bool is_container = transform::is_lsp_container_type_v<protocol::LSPArray>;
        assertTrue(is_container, "LSPArray应该是LSP容器类型");

        result.message = "成功";
        return result;
    }

    TestResult CommonTests::testIsLSPContainerAny()
    {
        TestResult result;
        result.passed = true;

        bool is_container = transform::is_lsp_container_type_v<protocol::LSPAny>;
        assertTrue(is_container, "LSPAny应该是LSP容器类型");

        result.message = "成功";
        return result;
    }

    TestResult CommonTests::testIsLSPContainerNegativeCases()
    {
        TestResult result;
        result.passed = true;

        assertFalse(transform::is_lsp_container_type_v<int>,
                    "int不应该是LSP容器");
        assertFalse(transform::is_lsp_container_type_v<std::string>,
                    "string不应该是LSP容器");
        assertFalse(transform::is_lsp_container_type_v<std::vector<int>>,
                    "std::vector不应该是LSP容器");

        result.message = "成功";
        return result;
    }

    // ==================== is_user_struct 测试 ====================

    TestResult CommonTests::testIsUserStructPositive()
    {
        TestResult result;
        result.passed = true;

        bool is_user = transform::is_user_struct_v<UserStruct>;
        assertTrue(is_user, "UserStruct应该被识别为用户结构体");

        result.message = "成功";
        return result;
    }

    TestResult CommonTests::testIsUserStructExcludeArithmetic()
    {
        TestResult result;
        result.passed = true;

        assertFalse(transform::is_user_struct_v<int>,
                    "int不应该是用户结构体");
        assertFalse(transform::is_user_struct_v<double>,
                    "double不应该是用户结构体");
        assertFalse(transform::is_user_struct_v<bool>,
                    "bool不应该是用户结构体");
        assertFalse(transform::is_user_struct_v<char>,
                    "char不应该是用户结构体");

        result.message = "成功";
        return result;
    }

    TestResult CommonTests::testIsUserStructExcludeString()
    {
        TestResult result;
        result.passed = true;

        assertFalse(transform::is_user_struct_v<std::string>,
                    "std::string不应该是用户结构体");
        assertFalse(transform::is_user_struct_v<protocol::string>,
                    "protocol::string不应该是用户结构体");

        result.message = "成功";
        return result;
    }

    TestResult CommonTests::testIsUserStructExcludeLSPTypes()
    {
        TestResult result;
        result.passed = true;

        assertFalse(transform::is_user_struct_v<protocol::LSPObject>,
                    "LSPObject不应该是用户结构体");
        assertFalse(transform::is_user_struct_v<protocol::LSPArray>,
                    "LSPArray不应该是用户结构体");
        assertFalse(transform::is_user_struct_v<protocol::LSPAny>,
                    "LSPAny不应该是用户结构体");
        assertFalse(transform::is_user_struct_v<protocol::integer>,
                    "protocol::integer不应该是用户结构体");

        result.message = "成功";
        return result;
    }

    TestResult CommonTests::testIsUserStructExcludeVector()
    {
        TestResult result;
        result.passed = true;

        bool is_user = transform::is_user_struct_v<std::vector<int>>;
        assertFalse(is_user, "std::vector不应该是用户结构体");

        result.message = "成功";
        return result;
    }

    TestResult CommonTests::testIsUserStructExcludeMap()
    {
        TestResult result;
        result.passed = true;

        bool is_user = transform::is_user_struct_v<std::map<std::string, int>>;
        assertFalse(is_user, "std::map不应该是用户结构体");

        result.message = "成功";
        return result;
    }

    TestResult CommonTests::testIsUserStructExcludeOptional()
    {
        TestResult result;
        result.passed = true;

        bool is_user = transform::is_user_struct_v<std::optional<int>>;
        assertFalse(is_user, "std::optional不应该是用户结构体");

        result.message = "成功";
        return result;
    }

    TestResult CommonTests::testIsUserStructExcludeVariant()
    {
        TestResult result;
        result.passed = true;

        bool is_user = transform::is_user_struct_v<std::variant<int, std::string>>;
        assertFalse(is_user, "std::variant不应该是用户结构体");

        result.message = "成功";
        return result;
    }

    TestResult CommonTests::testIsUserStructExcludePointers()
    {
        TestResult result;
        result.passed = true;

        assertFalse(transform::is_user_struct_v<int*>,
                    "int*不应该是用户结构体");
        assertFalse(transform::is_user_struct_v<const char*>,
                    "const char*不应该是用户结构体");
        assertFalse(transform::is_user_struct_v<UserStruct*>,
                    "UserStruct*不应该是用户结构体");

        result.message = "成功";
        return result;
    }

} // namespace lsp::test
