# -*- coding: utf-8 -*-
"""
扩展上下文门面（ExtensionContext）

借鉴 Hermes Agent 的 PluginContext 模式：
- 给 SkillLoader / MCPClientManager / HookRunner 提供受限的注册接口
- 扩展不直接触碰 ToolRegistry，通过 context 注册/注销
- 追踪每个扩展所在 source，支持按源批量卸载

MCPToolProxy 从 runtime/host.py 迁移至此，与门面同层。
"""

from typing import Any, Dict, List, Optional

from .tools.base import Tool
from .tools.registry import ToolRegistry


class MCPToolProxy(Tool):
    """把单个 MCP 工具包装成内置 Tool 子类，注册到主 ToolRegistry。
    执行时委托 MCPClientManager.call_tool(server, tool, args)。
    """

    def __init__(self, full_name: str, description: str,
                 input_schema: Dict[str, Any], mcp):
        self._name = full_name
        self._description = description or ""
        self._parameters = input_schema or {"type": "object", "properties": {}}
        self._mcp = mcp

    @property
    def name(self) -> str:
        return self._name

    @property
    def description(self) -> str:
        return self._description

    @property
    def parameters(self) -> Dict[str, Any]:
        return self._parameters

    def execute(self, **kwargs) -> Dict[str, Any]:
        """委托 MCPClientManager 执行真实工具调用"""
        server_name, tool_name = self._mcp.get_server_for_tool(self._name)
        if server_name is None:
            return {"success": False, "error": f"MCP 工具未注册: {self._name}"}
        return self._mcp.call_tool(server_name, tool_name, kwargs)


class ExtensionContext:
    """扩展上下文门面。

    每个 ExtensionContext 绑定一个 registry 和一个 source 标识，
    负责追踪该 source 注册的所有工具，支持按源卸载。

    使用方式：
        ctx = ExtensionContext(registry, source="mcp__github")
        ctx.register_tool(proxy)
        ... 工具使用 ...
        ctx.unregister_all()  # 干净卸载
    """

    def __init__(self, registry: ToolRegistry, source: str):
        self._registry = registry
        self.source = source
        self._owned: List[str] = []

    def register_tool(self, tool: Tool) -> Optional[Tool]:
        """注册工具到 registry。同名工具已存在时取消注册返回 None。"""
        if tool.name in self._registry:
            return None
        self._registry.register(tool, source=self.source)
        self._owned.append(tool.name)
        return tool

    def list_owned_tools(self) -> List[str]:
        """返回该 context 注册的所有工具名。"""
        return list(self._owned)

    def unregister_all(self) -> int:
        """注销该 context 拥有的所有工具。返回注销数量。"""
        count = 0
        for name in self._owned:
            if name in self._registry:
                self._registry.unregister(name)
                count += 1
        self._owned.clear()
        return count
