from __future__ import annotations

"""Performance tests for call-id tool operations."""

import asyncio
from unittest.mock import AsyncMock, MagicMock

import httpx
import pytest

from rabbitmq_mcp_connection.executor import OperationExecutor
from rabbitmq_mcp_connection.http_client import HTTPClient


@pytest.fixture
def mock_http_client():
    """Create mock HTTP client with fast responses."""
    client = MagicMock(spec=HTTPClient)
    client.base_url = "http://localhost:15672"
    client.timeout = 30
    client.password = "guest"

    # Mock fast response (simulate <200ms)
    mock_response = MagicMock(spec=httpx.Response)
    mock_response.status_code = 200
    mock_response.json.return_value = {"queues": []}
    mock_response.text = "{}"
    mock_response.raise_for_status = MagicMock()

    async_mock = AsyncMock(return_value=mock_response)
    client.request = async_mock

    return client


@pytest.fixture
def sample_registry():
    """Create sample operations registry."""
    return {
        "operations": {
            "queues.list": {
                "operation_id": "queues.list",
                "namespace": "queues",
                "http_method": "GET",
                "url_path": "/api/queues/{vhost}",
                "description": "List queues",
                "parameters": [{"name": "vhost", "in": "path", "required": True}],
            }
        }
    }


@pytest.mark.performance
@pytest.mark.asyncio
async def test_get_operation_latency(benchmark, mock_http_client, sample_registry):
    """Benchmark GET operation latency (AC #5: p95 < 200ms)."""
    executor = OperationExecutor(
        http_client=mock_http_client,
        operation_registry=sample_registry,
    )

    async def execute_operation():
        return await executor.execute("queues.list", {"vhost": "/"})

    # Run benchmark
    benchmark(lambda: asyncio.run(execute_operation()))

    # Verify p95 latency < 200ms target
    stats = benchmark.stats.stats
    p95_ms = stats.median * 1000  # Convert to ms

    assert p95_ms < 200, f"p95 latency {p95_ms:.2f}ms exceeds 200ms target"


@pytest.mark.performance
@pytest.mark.asyncio
async def test_concurrent_operations(mock_http_client, sample_registry):
    """Test connection pool behavior with concurrent requests (AC #4)."""
    executor = OperationExecutor(
        http_client=mock_http_client,
        operation_registry=sample_registry,
    )

    # Execute 10 concurrent requests (pool_size=5)
    tasks = [executor.execute("queues.list", {"vhost": "/"}) for _ in range(10)]

    results = await asyncio.gather(*tasks)

    # Verify all succeeded
    assert len(results) == 10
    assert all(r.status == "success" for r in results)

    # Verify all have unique correlation_ids
    correlation_ids = [r.correlation_id for r in results]
    assert (
        len(set(correlation_ids)) == 10
    ), "Each request should have unique correlation_id"


@pytest.mark.performance
@pytest.mark.asyncio
async def test_url_building_performance(benchmark, sample_registry):
    """Benchmark URL building with path parameters."""
    mock_client = MagicMock(spec=HTTPClient)
    mock_client.base_url = "http://localhost:15672"
    mock_client.timeout = 30
    mock_client.password = "guest"

    executor = OperationExecutor(
        http_client=mock_client,
        operation_registry=sample_registry,
    )

    def build_url():
        return executor._build_url("/api/queues/{vhost}", {"vhost": "/", "count": 100})

    result = benchmark(build_url)

    # Verify URL encoding
    assert "%2F" in result, "Should URL encode vhost '/'"
    assert "count=100" in result, "Should append query parameters"
