"""
Regression test: no MCP tool name is registered more than once across all
TypeScript tool files in src/tools/.

This caught a real bug where move_schematic_component was registered twice
(once in the original code and once in the PR adding wire-preservation),
causing the server to fail on startup with:
  Error: Tool move_schematic_component is already registered
"""

import re
from collections import Counter
from pathlib import Path

import pytest

SRC_TOOLS_DIR = Path(__file__).parent.parent / "src" / "tools"

# Pattern matches the tool-name argument to server.tool(
#   server.tool(
#     "some_tool_name",
_SERVER_TOOL_RE = re.compile(r'server\.tool\(\s*["\']([a-zA-Z0-9_]+)["\']')


@pytest.mark.unit
class TestTsToolRegistry:
    def _collect_registrations(self):
        """Return list of (tool_name, file, line_no) for every server.tool() call."""
        registrations = []
        for ts_file in sorted(SRC_TOOLS_DIR.glob("**/*.ts")):
            text = ts_file.read_text(encoding="utf-8")
            for m in _SERVER_TOOL_RE.finditer(text):
                line_no = text[: m.start()].count("\n") + 1
                registrations.append((m.group(1), ts_file.name, line_no))
        return registrations

    def test_no_duplicate_tool_names(self):
        """Every tool name must appear exactly once across all TS tool files."""
        registrations = self._collect_registrations()
        assert registrations, "No server.tool() calls found — check SRC_TOOLS_DIR path"

        counts = Counter(name for name, _, _ in registrations)
        duplicates = {name: count for name, count in counts.items() if count > 1}

        if duplicates:
            details = []
            for dup_name in sorted(duplicates):
                locations = [
                    f"  {fname}:{line}" for name, fname, line in registrations if name == dup_name
                ]
                details.append(f"{dup_name} ({duplicates[dup_name]}x):\n" + "\n".join(locations))
            pytest.fail(
                "Duplicate MCP tool registrations found — server will fail to start:\n\n"
                + "\n\n".join(details)
            )

    def test_tool_files_exist(self):
        """Sanity check: src/tools/ directory must be present and contain TS files."""
        assert SRC_TOOLS_DIR.is_dir(), f"src/tools/ not found at {SRC_TOOLS_DIR}"
        ts_files = list(SRC_TOOLS_DIR.glob("**/*.ts"))
        assert ts_files, "No .ts files found in src/tools/"

    def test_backend_state_tool_is_registered(self):
        """Backend observability must be exposed as a first-class MCP tool."""
        registrations = self._collect_registrations()
        tool_names = {name for name, _, _ in registrations}

        assert "get_backend_state" in tool_names
