# 中文注释：
# 文件：echobot/agent/tools/registry.py
# 说明：智能体工具层，实现文件、Shell、网络与消息等工具调用能力。

"""Tool Registry - 工具注册表
=================================================

此模块提供工具注册表，用于动态管理和执行工具。

功能特点：
1. 动态注册：运行时添加/移除工具
2. 名称查找：按名称获取工具实例
3. 批量获取：获取所有工具定义（供 LLM 使用）
4. 统一执行：通过名称调用工具并返回结果

使用示例：
    registry = ToolRegistry()
    registry.register(ReadFileTool())
    registry.register(WriteFileTool())
    
    # 检查工具是否存在
    if registry.has("read_file"):
        # 执行工具
        result = await registry.execute("read_file", {"path": "test.txt"})
    
    # 获取所有工具定义
    definitions = registry.get_definitions()
"""

from typing import Any

from echobot.agent.tools.base import Tool


class ToolRegistry:
    """
    工具注册表
    
    负责管理所有可用工具的注册、查找和执行。
    
    主要功能：
    - register(): 注册工具
    - unregister(): 移除工具
    - get(): 按名称获取工具
    - has(): 检查工具是否存在
    - get_definitions(): 获取所有工具定义
    - execute(): 执行工具
    
    使用示例：
        registry = ToolRegistry()
        registry.register(ReadFileTool())
        result = await registry.execute("read_file", {"path": "file.txt"})
    """
    
    def __init__(self):
        """初始化空注册表"""
        self._tools: dict[str, Tool] = {}
    
    def register(self, tool: Tool) -> None:
        """
        注册工具
        
        Args:
            tool: 工具实例
        """
        self._tools[tool.name] = tool
    
    def unregister(self, name: str) -> None:
        """
        移除工具
        
        Args:
            name: 工具名称
        """
        self._tools.pop(name, None)
    
    def get(self, name: str) -> Tool | None:
        """
        按名称获取工具
        
        Args:
            name: 工具名称
        
        Returns:
            Tool: 工具实例，如果不存在则返回 None
        """
        return self._tools.get(name)
    
    def has(self, name: str) -> bool:
        """
        检查工具是否已注册
        
        Args:
            name: 工具名称
        
        Returns:
            bool: 是否已注册
        """
        return name in self._tools
    
    def get_definitions(self) -> list[dict[str, Any]]:
        """
        获取所有工具定义（OpenAI 格式）
        
        Returns:
            list: 工具定义列表，可直接传递给 LLM API
        """
        return [tool.to_schema() for tool in self._tools.values()]
    
    async def execute(self, name: str, params: dict[str, Any]) -> str:
        """
        执行工具
        
        Args:
            name: 工具名称
            params: 工具参数
        
        Returns:
            str: 执行结果文本
        
        异常：
            KeyError: 工具未找到
        """
        tool = self._tools.get(name)
        if not tool:
            return f"Error: Tool '{name}' not found"
        
        try:
            return await tool.execute(**params)
        except Exception as e:
            return f"Error executing {name}: {str(e)}"
    
    @property
    def tool_names(self) -> list[str]:
        """
        获取所有已注册工具的名称列表
        
        Returns:
            list[str]: 工具名称列表
        """
        return list(self._tools.keys())
    
    def __len__(self) -> int:
        """
        获取已注册工具数量
        
        Returns:
            int: 工具数量
        """
        return len(self._tools)
    
    def __contains__(self, name: str) -> bool:
        """
        检查工具是否已注册（支持 in 操作符）
        
        Args:
            name: 工具名称
        
        Returns:
            bool: 是否已注册
        """
        return name in self._tools
