package com.easyagents.agent.runtime.mcp;

import com.easyagents.agent.runtime.AgentRuntimeException;
import com.easyagents.agent.runtime.tool.AgentToolSpec;
import com.easyagents.agent.runtime.tool.operate.AgentOperateToolAdapter;
import com.easyagents.agent.runtime.tool.operate.AgentOperateToolSpec;
import com.easyagents.agent.runtime.tool.operate.AgentOperateToolType;
import org.junit.Test;

import java.util.List;
import java.util.Map;

/**
 * 测试 MCP 声明校验器。
 */
public class McpSpecValidatorTest {

    @Test(expected = AgentRuntimeException.class)
    public void shouldRejectMissingStdioCommand() {
        McpSpec spec = spec(McpTransportType.STDIO);

        McpSpecValidator.validateConnection(spec);
    }

    @Test(expected = AgentRuntimeException.class)
    public void shouldRejectMissingSseUrl() {
        McpSpec spec = spec(McpTransportType.SSE);

        McpSpecValidator.validateConnection(spec);
    }

    @Test(expected = AgentRuntimeException.class)
    public void shouldRejectMissingHttpUrl() {
        McpSpec spec = spec(McpTransportType.HTTP);

        McpSpecValidator.validateConnection(spec);
    }

    @Test(expected = AgentRuntimeException.class)
    public void shouldRejectMcpToolNameConflictWithBusinessTool() {
        AgentToolSpec businessTool = toolSpec("search");
        AgentToolSpec mcpTool = toolSpec("search");

        McpSpecValidator.validateToolConflicts(List.of(businessTool), List.of(mcpTool), List.of());
    }

    @Test(expected = AgentRuntimeException.class)
    public void shouldRejectMcpToolNameConflictWithOperateTool() {
        AgentToolSpec mcpTool = toolSpec(AgentOperateToolAdapter.EXECUTE_SHELL_COMMAND_TOOL);
        AgentOperateToolSpec operateTool = new AgentOperateToolSpec();
        operateTool.setType(AgentOperateToolType.SHELL);

        McpSpecValidator.validateToolConflicts(List.of(), List.of(mcpTool), List.of(operateTool));
    }

    @Test(expected = AgentRuntimeException.class)
    public void shouldRejectDuplicatedRuntimeToolAliases() {
        McpSpec spec = spec(McpTransportType.STDIO);
        spec.setCommand("node");
        spec.setToolAliases(Map.of("search", "mcp_1_tool", "search.v2", "mcp_1_tool"));

        McpSpecValidator.validateConnection(spec);
    }

    private McpSpec spec(McpTransportType type) {
        McpSpec spec = new McpSpec();
        spec.setName("mcp");
        spec.setTransportType(type);
        return spec;
    }

    private AgentToolSpec toolSpec(String name) {
        AgentToolSpec spec = new AgentToolSpec();
        spec.setName(name);
        return spec;
    }
}
