from __future__ import annotations

"""Integration tests for call-id tool via MCP protocol."""

import json

import pytest
from testcontainers.rabbitmq import RabbitMqContainer

from config.settings import Settings
from mcp_server.server import MCPServer


@pytest.fixture(scope="module")
def rabbitmq_container():
    """Start RabbitMQ container with Management Plugin."""
    container = RabbitMqContainer("rabbitmq:3.13-management")
    container.start()

    yield container

    container.stop()


@pytest.fixture
async def mcp_server(rabbitmq_container):
    """Create MCP server with test settings."""
    # Get container connection details
    port = rabbitmq_container.get_exposed_port(15672)
    host = rabbitmq_container.get_container_host_ip()

    settings = Settings(
        host=host,
        port=int(port),
        user="guest",
        password="guest",
        rabbitmq_base_url=f"http://{host}:{port}",
        rabbitmq_username="guest",
        rabbitmq_password="guest",
    )

    server = MCPServer(settings)
    await server.startup()

    yield server

    await server.shutdown()


class TestCallIdToolIntegration:
    """Integration tests for call-id tool."""

    @pytest.mark.asyncio
    @pytest.mark.integration
    async def test_tool_registration(self, mcp_server):
        """Test call-id tool appears in tools/list (AC #1)."""
        tools = await mcp_server.server.list_tools()

        tool_names = [tool["name"] for tool in tools]
        assert "call-id" in tool_names, "call-id tool should be registered"

        # Find call-id tool definition
        call_id_tool = next(t for t in tools if t["name"] == "call-id")
        assert call_id_tool["description"], "Tool should have description"
        assert "inputSchema" in call_id_tool, "Tool should have input schema"
        assert call_id_tool["inputSchema"]["required"] == ["operation_id"]

    @pytest.mark.asyncio
    @pytest.mark.integration
    async def test_successful_get_operation(self, mcp_server):
        """Test successful GET operation (queues.list) (AC #3, #5)."""
        result = await mcp_server.operation_executor.execute(
            "queues.list", {"vhost": "/"}
        )

        assert result.status == "success", "Operation should succeed"
        assert result.correlation_id, "Should have correlation_id"
        assert "metadata" in result.model_dump(), "Should have metadata"
        assert result.metadata["operation_id"] == "queues.list"
        assert result.metadata["http_status_code"] == 200

    @pytest.mark.asyncio
    @pytest.mark.integration
    async def test_operation_not_found(self, mcp_server):
        """Test invalid operation_id returns error (AC #2)."""
        with pytest.raises(KeyError) as exc:
            await mcp_server.operation_executor.execute("invalid.operation", {})

        assert "not found" in str(exc.value).lower()

    @pytest.mark.asyncio
    @pytest.mark.integration
    async def test_missing_required_parameter(self, mcp_server):
        """Test missing required parameter returns validation error (AC #2)."""
        with pytest.raises(ValueError) as exc:
            await mcp_server.operation_executor.execute(
                "queues.list", {}  # Missing required 'vhost' parameter
            )

        assert "vhost" in str(exc.value).lower()

    @pytest.mark.asyncio
    @pytest.mark.integration
    async def test_correlation_id_in_response(self, mcp_server):
        """Test correlation_id present in response (AC #7)."""
        result = await mcp_server.operation_executor.execute("overview.list", {})

        assert result.correlation_id, "Should have correlation_id"
        # Verify it's a valid UUID format
        import uuid

        try:
            uuid.UUID(result.correlation_id)
        except ValueError:
            pytest.fail("correlation_id should be valid UUID")
