"""
工具注册框架
提供 ToolDef 基类和 @register_tool 装饰器，用于声明式定义 MCP 工具
"""

from abc import ABC, abstractmethod
from typing import Dict, Any, TYPE_CHECKING

if TYPE_CHECKING:
    from ..utils.api_client import AgileDBAPIClient


# 全局工具注册表
_registered_tools = []


def register_tool(name: str):
    """
    工具注册装饰器
    
    使用方式:
        @register_tool("list_datasources")
        class ListDatasourcesTool(ToolDef):
            name = "list_datasources"
            description = "获取数据源列表"
            input_schema = {...}
            
            async def execute(self, args):
                return await self.client.get("/datasource/...", params=args)
    
    Args:
        name: 工具名称（唯一标识）
    """
    def decorator(cls):
        # 确保类有正确的 name 属性
        if not hasattr(cls, 'name') or cls.name != name:
            cls.name = name
        
        # 注册到全局列表，避免重复注册
        if cls not in _registered_tools:
            _registered_tools.append(cls)
        return cls
    
    return decorator


class ToolDef(ABC):
    """
    工具定义基类
    
    所有工具都应继承此类并使用 @register_tool 装饰器注册
    
    类属性:
        name: 工具名称（唯一标识）
        description: 工具描述
        input_schema: JSON Schema 格式的工具输入参数定义
    
    实例属性:
        client: AgileDBAPIClient 实例（由 server 注入）
    """
    
    name: str = ""
    description: str = ""
    input_schema: Dict[str, Any] = {"type": "object", "properties": {}, "required": []}
    
    def __init__(self, client: "AgileDBAPIClient"):
        """
        初始化工具实例
        
        Args:
            client: API 客户端实例（由 server 注入）
        """
        self.client = client
    
    @abstractmethod
    async def execute(self, args: Dict[str, Any]) -> Dict[str, Any]:
        """
        执行工具逻辑
        
        Args:
            args: 工具输入参数（已校验）
            
        Returns:
            Dict[str, Any]: 执行结果，将作为 MCP 工具返回值
        """
        pass
    
    def to_tool_def(self) -> Dict[str, Any]:
        """
        转换为 MCP 工具定义格式
        
        Returns:
            dict: MCP types.Tool 所需的参数
        """
        return {
            "name": self.name,
            "description": self.description,
            "inputSchema": self.input_schema,
        }


def get_registered_tools() -> list:
    """
    获取所有已注册的工具类列表
    
    Returns:
        list: 所有被 @register_tool 装饰的类
    """
    return list(_registered_tools)


def clear_registered_tools():
    """
    清空所有已注册的工具（主要用于测试）
    """
    _registered_tools.clear()
