"""测试工具定义"""
import pytest
from pydantic import BaseModel, Field
from yier_agents.src.tool import Tool, ToolContext, ToolOutput


class MockParams(BaseModel):
    """测试用参数"""
    value: int = Field(description="测试值")


async def mock_execute(params: MockParams, ctx: ToolContext) -> ToolOutput:
    """测试执行函数"""
    return ToolOutput(
        content=f"Executed with value={params.value}",
        metadata={"session": ctx.session_id}
    )


def test_tool_context_creation():
    """测试 ToolContext 创建"""
    ctx = ToolContext(
        session_id="sess_123",
        message_id="msg_456",
        call_id="call_789",
        metadata={"key": "value"}
    )
    assert ctx.session_id == "sess_123"
    assert ctx.message_id == "msg_456"
    assert ctx.call_id == "call_789"
    assert ctx.metadata["key"] == "value"


def test_tool_output_creation():
    """测试 ToolOutput 创建"""
    output = ToolOutput(
        content="result",
        metadata={"truncated": False}
    )
    assert output.content == "result"
    assert output.metadata["truncated"] is False


def test_tool_creation():
    """测试 Tool 创建"""
    tool = Tool(
        name="test_tool",
        description="A test tool",
        parameters=MockParams,
        execute=mock_execute
    )
    assert tool.name == "test_tool"
    assert tool.description == "A test tool"
    assert tool.parameters == MockParams


def test_tool_to_openai_schema():
    """测试转换为 OpenAI schema"""
    tool = Tool(
        name="calculator",
        description="Calculate something",
        parameters=MockParams,
        execute=mock_execute
    )
    schema = tool.to_openai_schema()

    assert schema["type"] == "function"
    assert schema["function"]["name"] == "calculator"
    assert schema["function"]["description"] == "Calculate something"
    assert "parameters" in schema["function"]
    assert schema["function"]["parameters"]["type"] == "object"


@pytest.mark.asyncio
async def test_tool_execute():
    """测试工具执行"""
    tool = Tool(
        name="test",
        description="Test",
        parameters=MockParams,
        execute=mock_execute
    )
    ctx = ToolContext(
        session_id="s1",
        message_id="m1",
        call_id="c1"
    )
    result = await tool.execute(MockParams(value=42), ctx)

    assert result.content == "Executed with value=42"
    assert result.metadata["session"] == "s1"
