# Copyright (C) 2026 GoodData Corporation

"""Explicit MCP tool registration (Option A).

We keep tool registration explicit to avoid "import for side effects" surprises
that can lead to a running server with 0 tools registered.
"""

from __future__ import annotations

from typing import TYPE_CHECKING

import aida_mcp.server.tools_commit as tools_commit
import aida_mcp.server.tools_github as tools_github
import aida_mcp.server.tools_pr as tools_pr
import aida_mcp.server.tools_pr_review as tools_pr_review
import aida_mcp.server.tools_rules as tools_rules
import aida_mcp.server.tools_validation as tools_validation

if TYPE_CHECKING:
    from mcp.server.fastmcp import FastMCP


_REGISTERED_SENTINEL = "_aida_tools_registered"


def register_all(mcp: FastMCP) -> None:
    """Register all MCP tools on the given FastMCP instance."""
    if getattr(mcp, _REGISTERED_SENTINEL, False):
        return
    tools_commit.register(mcp)
    tools_github.register(mcp)
    tools_pr.register(mcp)
    tools_pr_review.register(mcp)
    tools_rules.register(mcp)
    tools_validation.register(mcp)
    _forbid_extra_tool_args(mcp)
    setattr(mcp, _REGISTERED_SENTINEL, True)


def _forbid_extra_tool_args(mcp: FastMCP) -> None:
    """Patch all registered tool argument models to reject unknown parameters.

    The MCP SDK defaults to ``extra="ignore"`` which silently drops unknown
    arguments.  For AIDA tools we want a hard error so that callers discover
    typos/hallucinated parameters immediately.
    """
    tool_manager = getattr(mcp, "_tool_manager", None)
    if tool_manager is None:
        return
    for tool in tool_manager._tools.values():
        model = tool.fn_metadata.arg_model
        model.model_config["extra"] = "forbid"
        model.model_rebuild(force=True)
