/**
 * @file test_mcp_tool.cpp
 * @brief 测试MCP工具相关功能
 * 
 * 本文件包含对MCP工具模块的单元测试，基于规范2024-11-05。
 */

#include "mcp_tool.h"
#include <gtest/gtest.h>
#include <gmock/gmock.h>
#include <string>

// 测试工具结构体
TEST(McpToolTest, ToolStructTest) {
    // 创建一个工具
    mcp::tool tool;
    tool.name = "test_tool";
    tool.description = "测试工具";
    tool.parameters_schema = {
        {"type", "object"},
        {"properties", {
            {"param1", {
                {"type", "string"},
                {"description", "第一个参数"}
            }},
            {"param2", {
                {"type", "number"},
                {"description", "第二个参数"}
            }}
        }},
        {"required", {"param1"}}
    };
    
    // 验证工具属性
    EXPECT_EQ(tool.name, "test_tool");
    EXPECT_EQ(tool.description, "测试工具");
    
    // 验证转换为JSON
    mcp::json json_tool = tool.to_json();
    EXPECT_EQ(json_tool["name"], "test_tool");
    EXPECT_EQ(json_tool["description"], "测试工具");
    EXPECT_EQ(json_tool["parameters"]["type"], "object");
    EXPECT_EQ(json_tool["parameters"]["properties"]["param1"]["type"], "string");
    EXPECT_EQ(json_tool["parameters"]["properties"]["param1"]["description"], "第一个参数");
    EXPECT_EQ(json_tool["parameters"]["properties"]["param2"]["type"], "number");
    EXPECT_EQ(json_tool["parameters"]["required"][0], "param1");
}

// 测试工具构建器
TEST(McpToolTest, ToolBuilderTest) {
    // 使用构建器创建工具
    mcp::tool_builder builder("calculator");
    mcp::tool tool = builder
        .with_description("计算器工具")
        .with_string_param("operation", "操作类型 (add, subtract, multiply, divide)")
        .with_number_param("a", "第一个操作数")
        .with_number_param("b", "第二个操作数")
        .with_boolean_param("round_result", "是否四舍五入结果", false)
        .build();
    
    // 验证工具属性
    EXPECT_EQ(tool.name, "calculator");
    EXPECT_EQ(tool.description, "计算器工具");
    
    // 验证参数架构
    EXPECT_EQ(tool.parameters_schema["type"], "object");
    
    // 验证参数属性
    auto& properties = tool.parameters_schema["properties"];
    EXPECT_EQ(properties["operation"]["type"], "string");
    EXPECT_EQ(properties["operation"]["description"], "操作类型 (add, subtract, multiply, divide)");
    EXPECT_EQ(properties["a"]["type"], "number");
    EXPECT_EQ(properties["a"]["description"], "第一个操作数");
    EXPECT_EQ(properties["b"]["type"], "number");
    EXPECT_EQ(properties["b"]["description"], "第二个操作数");
    EXPECT_EQ(properties["round_result"]["type"], "boolean");
    EXPECT_EQ(properties["round_result"]["description"], "是否四舍五入结果");
    
    // 验证必需参数
    auto& required = tool.parameters_schema["required"];
    EXPECT_THAT(required, ::testing::UnorderedElementsAre("operation", "a", "b"));
    EXPECT_THAT(required, ::testing::Not(::testing::Contains("round_result")));
}

// 测试数组参数
TEST(McpToolTest, ArrayParamTest) {
    // 使用构建器创建带有数组参数的工具
    mcp::tool tool = mcp::tool_builder("list_processor")
        .with_description("处理列表")
        .with_array_param("items", "要处理的项目列表", "string")
        .build();
    
    // 验证数组参数
    auto& properties = tool.parameters_schema["properties"];
    EXPECT_EQ(properties["items"]["type"], "array");
    EXPECT_EQ(properties["items"]["description"], "要处理的项目列表");
    EXPECT_EQ(properties["items"]["items"]["type"], "string");
}

// 测试对象参数
TEST(McpToolTest, ObjectParamTest) {
    // 创建对象属性
    mcp::json user_properties = {
        {"name", {
            {"type", "string"},
            {"description", "用户名"}
        }},
        {"age", {
            {"type", "number"},
            {"description", "年龄"}
        }}
    };
    
    // 使用构建器创建带有对象参数的工具
    mcp::tool tool = mcp::tool_builder("user_processor")
        .with_description("处理用户信息")
        .with_object_param("user", "用户对象", user_properties)
        .build();
    
    // 验证对象参数
    auto& properties = tool.parameters_schema["properties"];
    EXPECT_EQ(properties["user"]["type"], "object");
    EXPECT_EQ(properties["user"]["description"], "用户对象");
    EXPECT_EQ(properties["user"]["properties"]["name"]["type"], "string");
    EXPECT_EQ(properties["user"]["properties"]["name"]["description"], "用户名");
    EXPECT_EQ(properties["user"]["properties"]["age"]["type"], "number");
    EXPECT_EQ(properties["user"]["properties"]["age"]["description"], "年龄");
}

// 测试工具注册表
TEST(McpToolTest, ToolRegistryTest) {
    // 获取工具注册表实例
    mcp::tool_registry& registry = mcp::tool_registry::instance();
    
    // 创建一个测试工具
    mcp::tool test_tool = mcp::tool_builder("test_registry_tool")
        .with_description("测试注册表工具")
        .with_string_param("input", "输入字符串")
        .build();
    
    // 创建一个处理函数
    mcp::tool_handler handler = [](const mcp::json& params) -> mcp::json {
        std::string input = params["input"];
        return {{"output", "处理结果: " + input}};
    };
    
    // 注册工具
    registry.register_tool(test_tool, handler);
    
    // 获取所有工具
    auto tools = registry.get_all_tools();
    
    // 验证工具是否已注册
    bool found = false;
    for (const auto& tool : tools) {
        if (tool.name == "test_registry_tool") {
            found = true;
            EXPECT_EQ(tool.description, "测试注册表工具");
            break;
        }
    }
    EXPECT_TRUE(found);
    
    // 获取特定工具
    auto tool_pair = registry.get_tool("test_registry_tool");
    ASSERT_NE(tool_pair, nullptr);
    EXPECT_EQ(tool_pair->first.name, "test_registry_tool");
    
    // 调用工具
    mcp::json call_params = {{"input", "测试输入"}};
    mcp::json result = registry.call_tool("test_registry_tool", call_params);
    EXPECT_EQ(result["output"], "处理结果: 测试输入");
    
    // 注销工具
    bool unregistered = registry.unregister_tool("test_registry_tool");
    EXPECT_TRUE(unregistered);
    
    // 验证工具已被注销
    tool_pair = registry.get_tool("test_registry_tool");
    EXPECT_EQ(tool_pair, nullptr);
}

// 测试create_tool辅助函数
TEST(McpToolTest, CreateToolHelperTest) {
    // 使用辅助函数创建工具
    std::vector<std::tuple<std::string, std::string, std::string, bool>> params = {
        {"name", "姓名", "string", true},
        {"age", "年龄", "number", true},
        {"is_active", "是否活跃", "boolean", false}
    };
    
    mcp::tool tool = mcp::create_tool("user_tool", "用户工具", params);
    
    // 验证工具属性
    EXPECT_EQ(tool.name, "user_tool");
    EXPECT_EQ(tool.description, "用户工具");
    
    // 验证参数
    auto& properties = tool.parameters_schema["properties"];
    EXPECT_EQ(properties["name"]["type"], "string");
    EXPECT_EQ(properties["name"]["description"], "姓名");
    EXPECT_EQ(properties["age"]["type"], "number");
    EXPECT_EQ(properties["age"]["description"], "年龄");
    EXPECT_EQ(properties["is_active"]["type"], "boolean");
    EXPECT_EQ(properties["is_active"]["description"], "是否活跃");
    
    // 验证必需参数
    auto& required = tool.parameters_schema["required"];
    EXPECT_THAT(required, ::testing::UnorderedElementsAre("name", "age"));
    EXPECT_THAT(required, ::testing::Not(::testing::Contains("is_active")));
} 