"""Counting MCP transport for race-condition testing.

This module provides :class:`CountingMCPTransport`, a test double that wraps a
``MockMCPTransport`` and records how many times ``connect()`` and
``discover_tools()`` (tools/list) are called.  It uses thread-safe counters so
that concurrent scenarios can assert the exact call counts expected when fixing
race conditions in ``McpClient.start()`` (issue #10438).

See: https://git.cleverthis.com/cleveragents/cleveragents-core/issues/10438
"""

from __future__ import annotations

import threading
from typing import Any

from cleveragents.mcp.adapter import MCPServerConfig, MCPTransport
from features.mocks.mock_mcp_transport import MockMCPTransport


class CountingMCPTransport(MCPTransport):
    """Transport that counts ``connect()`` and ``discover_tools()`` calls.

    Wraps an inner transport (typically :class:`MockMCPTransport`) and
    increments thread-safe counters for each ``connect()`` call and every
    ``tools/list`` method call on ``call()``.  Used to verify that concurrent
    :meth:`~McpClient.start` invocations produce exactly one initialisation
    sequence.
    """

    def __init__(self, tools: list[dict[str, Any]]) -> None:
        self._inner = MockMCPTransport(tools=tools)
        self._lock: threading.Lock = threading.Lock()
        self.connect_count: int = 0
        self.discover_count: int = 0

    def connect(self, config: MCPServerConfig) -> dict[str, Any]:
        with self._lock:
            self.connect_count += 1
        return self._inner.connect(config)

    def call(self, method: str, params: dict[str, Any]) -> dict[str, Any]:
        if method == "tools/list":
            with self._lock:
                self.discover_count += 1
        return self._inner.call(method, params)

    def close(self) -> None:
        self._inner.close()
