"""
本地工具注册测试。
"""

from __future__ import annotations

import time

import pytest

from cmdc.tools import LocalTool


class TestLocalTool:
    def test_basic_execute(self) -> None:
        tool = LocalTool(
            name="echo",
            description="回声工具",
            parameters={
                "type": "object",
                "properties": {"text": {"type": "string"}},
                "required": ["text"],
            },
            callback=lambda args: f"回声: {args['text']}",
        )

        result = tool.execute({"text": "你好"})
        assert result == "回声: 你好"

    def test_execute_exception_returns_error_string(self) -> None:
        def failing(args: dict) -> str:
            raise ValueError("工具执行失败")

        tool = LocalTool(
            name="fail",
            description="总是失败",
            parameters={},
            callback=failing,
        )

        result = tool.execute({})
        assert "[tool_error]" in result
        assert "工具执行失败" in result

    def test_execute_timeout(self) -> None:
        def slow(args: dict) -> str:
            time.sleep(10)
            return "never"

        tool = LocalTool(
            name="slow",
            description="超时工具",
            parameters={},
            callback=slow,
            timeout=0.1,
        )

        result = tool.execute({})
        assert "[tool_timeout]" in result

    def test_to_registration_payload(self) -> None:
        params = {
            "type": "object",
            "properties": {"query": {"type": "string"}},
            "required": ["query"],
        }
        tool = LocalTool(
            name="search",
            description="搜索工具",
            parameters=params,
            callback=lambda _: "ok",
        )

        payload = tool.to_registration_payload("http://localhost:8080/tools/search")

        assert payload["name"] == "search"
        assert payload["description"] == "搜索工具"
        assert payload["parameters"] == params
        assert payload["callbackUrl"] == "http://localhost:8080/tools/search"

    def test_complex_callback(self) -> None:
        def calculate(args: dict) -> str:
            a = int(args.get("a", 0))
            b = int(args.get("b", 0))
            return str(a + b)

        tool = LocalTool(
            name="add",
            description="加法工具",
            parameters={},
            callback=calculate,
        )

        assert tool.execute({"a": "3", "b": "4"}) == "7"
