# -*- coding: utf-8 -*-
"""
CraftPilot MCP 装饰器
Author: CraftPilot

本模块提供 MCP 相关的装饰器，供外部开发者使用。

主要装饰器：
- expose_as_mcp: 将函数标记为 MCP 工具

注意：@craftmethod 装饰器定义在 pypapi.dson 模块中，
这里提供别名以便导入。
"""

import functools
from typing import Callable, Any, Optional


def expose_as_mcp(
    func: Callable = None,
    *,
    timeout: int = 30,
    category: str = "general",
    description: str = None
) -> Callable:
    """
    将函数标记为 MCP 工具的装饰器
    
    这是一个独立的装饰器，用于在不使用 @craftmethod 的情况下
    将函数标记为 MCP 工具。
    
    示例用法::
    
        from craftpilot.pypapi.mcp import expose_as_mcp
        
        @expose_as_mcp(timeout=60, category="custom")
        def my_tool(param: str) -> dict:
            '''我的自定义工具'''
            return {"result": param}
    
    Args:
        func: 被装饰的函数
        timeout: 工具执行超时时间（秒），默认 30
        category: 工具分类，默认 "general"
        description: 工具描述，默认使用函数 docstring
        
    Returns:
        装饰后的函数
    """
    def decorator(f: Callable) -> Callable:
        # 标记为 MCP 工具
        f._is_mcp_tool = True
        f._mcp_timeout = timeout
        f._mcp_category = category
        f._mcp_description = description or f.__doc__ or f"MCP tool: {f.__name__}"
        
        @functools.wraps(f)
        def wrapper(*args, **kwargs):
            return f(*args, **kwargs)
        
        # 复制 MCP 属性到 wrapper
        wrapper._is_mcp_tool = f._is_mcp_tool
        wrapper._mcp_timeout = f._mcp_timeout
        wrapper._mcp_category = f._mcp_category
        wrapper._mcp_description = f._mcp_description
        
        return wrapper
    
    if func is not None:
        # 无参数调用方式：@expose_as_mcp
        return decorator(func)
    else:
        # 有参数调用方式：@expose_as_mcp(...)
        return decorator


def mcp_param(
    name: str,
    type_hint: str,
    description: str = "",
    required: bool = True,
    default: Any = None
) -> dict:
    """
    创建 MCP 工具参数定义
    
    用于手动定义工具参数，供不使用类型注解的情况。
    
    示例用法::
    
        from craftpilot.pypapi.mcp import mcp_param
        
        MY_TOOL_PARAMS = [
            mcp_param("name", "string", "名称", required=True),
            mcp_param("count", "integer", "数量", required=False, default=1),
        ]
    
    Args:
        name: 参数名称
        type_hint: 参数类型（string, integer, number, boolean, array, object）
        description: 参数描述
        required: 是否必需
        default: 默认值
        
    Returns:
        dict: 参数定义字典
    """
    param_def = {
        'name': name,
        'type': type_hint,
        'description': description,
        'required': required
    }
    if default is not None:
        param_def['default'] = default
    return param_def


class MCPToolConfig:
    """
    MCP 工具配置类
    
    用于配置 MCP 工具的行为。
    
    示例用法::
    
        from craftpilot.pypapi.mcp import MCPToolConfig
        
        config = MCPToolConfig(
            timeout=60,
            category="custom",
            retry_on_failure=True,
            max_retries=3
        )
    """
    
    def __init__(
        self,
        timeout: int = 30,
        category: str = "general",
        retry_on_failure: bool = False,
        max_retries: int = 3,
        execute_on_server: bool = True
    ):
        """
        初始化配置
        
        Args:
            timeout: 超时时间（秒）
            category: 工具分类
            retry_on_failure: 失败时是否重试
            max_retries: 最大重试次数
            execute_on_server: 是否在服务器端执行
        """
        self.timeout = timeout
        self.category = category
        self.retry_on_failure = retry_on_failure
        self.max_retries = max_retries
        self.execute_on_server = execute_on_server
    
    def to_dict(self) -> dict:
        """转换为字典"""
        return {
            'timeout': self.timeout,
            'category': self.category,
            'retry_on_failure': self.retry_on_failure,
            'max_retries': self.max_retries,
            'execute_on_server': self.execute_on_server
        }
