"""Convert MCP tool definitions to OpenAI function-calling format.

MCP tools use JSON Schema ``inputSchema``; OpenAI expects ``parameters``
inside a ``function`` wrapper. We prefix every tool name with ``mcp_``
so the agent brain can distinguish local tools from MCP tools.
"""

from __future__ import annotations

import json
import logging
from typing import TYPE_CHECKING

if TYPE_CHECKING:
    from .client import MCPClient

logger = logging.getLogger(__name__)

MCP_TOOL_PREFIX = "mcp_"


class MCPToolRegistry:
    """Loads MCP tools and provides OpenAI-compatible definitions."""

    def __init__(self, client: MCPClient) -> None:
        self.client = client
        self._mcp_tools: dict[str, dict] = {}  # prefixed_name → original def
        self._openai_defs: list[dict] = []

    def load(self) -> list[dict]:
        """Fetch tools from MCP server and return OpenAI-format defs.

        Call once after MCPClient.connect(). The returned list is
        suitable for appending to AgentBrain.mcp_tools.
        """
        raw_tools = self.client.list_tools()
        self._mcp_tools.clear()
        self._openai_defs.clear()

        for tool in raw_tools:
            name = tool.get("name", "")
            prefixed = f"{MCP_TOOL_PREFIX}{name}"

            self._mcp_tools[prefixed] = tool

            # Map MCP inputSchema → OpenAI parameters
            input_schema = tool.get("inputSchema", {
                "type": "object",
                "properties": {},
            })

            self._openai_defs.append({
                "type": "function",
                "function": {
                    "name": prefixed,
                    "description": tool.get("description", ""),
                    "parameters": input_schema,
                },
            })

        logger.info("MCP: loaded %d tools", len(self._openai_defs))
        return list(self._openai_defs)

    def is_mcp_tool(self, name: str) -> bool:
        """Check if a tool name belongs to MCP."""
        return name in self._mcp_tools

    def call(self, prefixed_name: str, arguments: dict) -> str:
        """Execute an MCP tool call, returning a JSON result string.

        Called synchronously from the agent's background thread.
        """
        if prefixed_name not in self._mcp_tools:
            return json.dumps({"error": f"Unknown MCP tool: {prefixed_name}"})

        # Strip prefix to get the original MCP tool name
        original_name = prefixed_name[len(MCP_TOOL_PREFIX):]

        try:
            result = self.client.call_tool(original_name, arguments)
            return json.dumps({"result": result})
        except Exception as exc:
            logger.exception("MCP tool error: %s", prefixed_name)
            return json.dumps({"error": str(exc)})

    def tool_names(self) -> list[str]:
        """Return list of prefixed MCP tool names."""
        return list(self._mcp_tools.keys())
