"""MCP router — selects which MCP servers to activate for a request.

Combines project context (stack, git remote) with task analysis (intent,
capabilities) to determine which MCP servers should handle tool calls.
"""

from __future__ import annotations

import structlog

from proxym.context._context import ProjectContext
from proxym.context.tool_selector import select_tools
from proxym.mcp.registry import MCPRegistry, MCPServerSpec
from proxym.router import AnalysisResult

logger = structlog.get_logger()


class MCPRouter:
    """Routes tool requests to appropriate MCP servers.

    Parameters
    ----------
    registry : MCPRegistry
        Registry of available MCP servers.
    """

    def __init__(self, registry: MCPRegistry) -> None:
        self.registry = registry

    def select_servers(
        self,
        context: ProjectContext,
        analysis: AnalysisResult | None = None,
    ) -> list[MCPServerSpec]:
        """Select MCP servers for a project + analysis combination.

        Returns servers sorted by priority (lower = higher priority).
        """
        available = self.registry.available_names()
        tool_names = select_tools(context, analysis, available_servers=available)

        servers: dict[str, MCPServerSpec] = {}
        for name in tool_names:
            spec = self.registry.get(name)
            if spec and spec.enabled:
                servers[name] = spec

        result = sorted(servers.values(), key=lambda s: s.priority)

        logger.info(
            "mcp_servers_selected",
            project=context.project_name,
            servers=[s.name for s in result],
            project_stack=context.stack,
        )

        return result

    def get_tools_for_servers(
        self, servers: list[MCPServerSpec],
    ) -> list[dict]:
        """Build OpenAI-compatible tool definitions from selected servers.

        Returns a list of tool dicts suitable for the ``tools`` parameter
        in a chat completion request.
        """
        tools = []
        for server in servers:
            for tool_name in server.tools:
                tools.append({
                    "type": "function",
                    "function": {
                        "name": f"{server.name}__{tool_name}",
                        "description": f"{tool_name} via {server.name} MCP server",
                        "parameters": {"type": "object", "properties": {}},
                    },
                })
        return tools

    def resolve_tool_call(
        self, tool_name: str,
    ) -> tuple[MCPServerSpec | None, str]:
        """Resolve a tool call name to (server, actual_tool_name).

        Tool names follow the convention: ``{server}__{tool}``
        """
        if "__" not in tool_name:
            # Try direct server name match
            spec = self.registry.get(tool_name)
            return (spec, tool_name) if spec else (None, tool_name)

        server_name, actual_tool = tool_name.split("__", 1)
        spec = self.registry.get(server_name)
        return (spec, actual_tool)
