"""ToolMiddleware 实现"""
from pydantic import ValidationError

from yier_agents.src.tool import Tool, ToolContext, ToolOutput
from yier_agents.src.message import ToolCall, ToolResult


class ToolMiddleware:
    """工具执行中间件"""

    def __init__(self, tools: list[Tool]):
        """初始化中间件

        Args:
            tools: 工具列表
        """
        self.tools = {tool.name: tool for tool in tools}

    async def execute_tool_call(
        self, tool_call: ToolCall, ctx: ToolContext
    ) -> ToolResult:
        """执行工具调用

        Args:
            tool_call: 工具调用信息
            ctx: 工具执行上下文

        Returns:
            工具执行结果
        """
        # 1. 查找工具
        tool = self.tools.get(tool_call.name)
        if tool is None:
            return ToolResult(
                call_id=tool_call.id,
                name=tool_call.name,
                content=f"Error: Tool '{tool_call.name}' not found",
                is_error=True,
            )

        # 2. 参数验证
        try:
            params = tool.parameters.model_validate(tool_call.arguments)
        except ValidationError as e:
            return ToolResult(
                call_id=tool_call.id,
                name=tool_call.name,
                content=f"Parameter validation error: {str(e)}",
                is_error=True,
            )

        # 3. 执行工具
        try:
            output = await tool.execute(params, ctx)
        except Exception as e:
            return ToolResult(
                call_id=tool_call.id,
                name=tool_call.name,
                content=f"Execution error: {str(e)}",
                is_error=True,
            )

        # 4. 后处理
        output = await self._post_process(output)

        # 5. 返回结果
        return ToolResult(
            call_id=tool_call.id,
            name=tool_call.name,
            content=output.content,
            is_error=False,
        )

    async def _post_process(self, output: ToolOutput) -> ToolOutput:
        """后处理输出 (扩展点)

        Args:
            output: 工具输出

        Returns:
            处理后的输出
        """
        return output
