"""
Copyright (C) 2025 Luciano Guerche

This file is part of rabbitmq-mcp-server.

rabbitmq-mcp-server is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

rabbitmq-mcp-server is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.

You should have received a copy of the GNU Lesser General Public License
along with rabbitmq-mcp-server. If not, see <https://www.gnu.org/licenses/>.
"""

"""
Example integration tests using centralized testcontainers fixtures.

This file demonstrates how to use the testcontainers fixtures from conftest.py
for integration testing with real RabbitMQ instances.

Epic: Epic 3 Action Item - "Setup testcontainers for integration tests"
Reference: docs-bmad/sprint-artifacts/epic-3-retro-2026-02-12.md
"""

import uuid

import pytest


@pytest.mark.integration
def test_basic_container_access(rabbitmq_container):
    """Demonstrate basic testcontainer access."""
    # Get connection details from container
    host = rabbitmq_container.get_container_host_ip()
    http_port = int(rabbitmq_container.get_exposed_port(15672))
    amqp_port = int(rabbitmq_container.get_exposed_port(5672))

    # Verify container is accessible
    assert host is not None
    assert http_port > 0
    assert amqp_port > 0
    assert http_port != amqp_port


@pytest.mark.integration
def test_using_settings_fixture(rabbitmq_settings):
    """Demonstrate using pre-configured Settings fixture."""
    # Settings object is pre-configured for testcontainer
    assert rabbitmq_settings.host is not None
    assert rabbitmq_settings.port > 0
    assert rabbitmq_settings.user == "guest"
    assert rabbitmq_settings.password == "guest"
    assert rabbitmq_settings.vhost == "/"
    assert rabbitmq_settings.use_tls is False


@pytest.mark.asyncio
@pytest.mark.integration
async def test_http_client_manager_fixture(http_client_manager):
    """Demonstrate using HTTP client manager fixture."""
    # HTTP client is already connected to testcontainer
    response = await http_client_manager.get("/api/overview")

    assert response.status_code == 200
    data = response.json()
    assert "rabbitmq_version" in data
    assert "cluster_name" in data


@pytest.mark.asyncio
@pytest.mark.integration
async def test_http_operations_with_client(http_client_manager):
    """Demonstrate HTTP operations for topology management."""
    # Create a test queue using HTTP API
    queue_name = f"test-queue-{uuid.uuid4().hex[:8]}"

    response = await http_client_manager.put(
        f"/api/queues/%2F/{queue_name}", json={"durable": True, "auto_delete": False}
    )
    assert response.status_code in (201, 204)

    # List queues and verify it exists
    response = await http_client_manager.get("/api/queues/%2F")
    assert response.status_code == 200

    queues = response.json()
    assert any(q["name"] == queue_name for q in queues)

    # Cleanup: delete the queue
    response = await http_client_manager.delete(f"/api/queues/%2F/{queue_name}")
    assert response.status_code == 204


@pytest.mark.asyncio
@pytest.mark.integration
async def test_amqp_connection_fixture(amqp_connection):
    """Demonstrate using AMQP connection fixture."""
    # Connection manager is already connected
    assert amqp_connection is not None

    # Get a channel for operations
    channel = await amqp_connection.get_channel()
    assert channel is not None

    # Channel is ready for messaging operations
    # (messaging tests would go here in Epic 4)


@pytest.mark.asyncio
@pytest.mark.integration
async def test_queue_operations_with_settings(rabbitmq_settings, http_client_manager):
    """Demonstrate topology operations using Settings object."""
    from rabbitmq_mcp_connection.operations.topology import (
        CreateQueueOperation,
        DeleteQueueOperation,
        ListQueuesOperation,
    )

    # Create operation instances
    list_op = ListQueuesOperation(http_client_manager, rabbitmq_settings)
    create_op = CreateQueueOperation(http_client_manager, rabbitmq_settings)
    delete_op = DeleteQueueOperation(http_client_manager, rabbitmq_settings)

    # Create a test queue
    queue_name = f"test-queue-{uuid.uuid4().hex[:8]}"
    create_result = await create_op.execute(
        vhost="/", name=queue_name, durable=True, auto_delete=False
    )
    assert create_result["name"] == queue_name

    # List queues and verify it exists
    list_result = await list_op.execute(vhost="/")
    queue_names = [q["name"] for q in list_result]
    assert queue_name in queue_names

    # Delete the queue
    delete_result = await delete_op.execute(vhost="/", name=queue_name, force=False)
    assert delete_result["status"] == "deleted"


@pytest.mark.asyncio
@pytest.mark.integration
async def test_idempotent_queue_creation(rabbitmq_settings, http_client_manager):
    """Demonstrate idempotent operation testing with testcontainers."""
    from rabbitmq_mcp_connection.operations.topology import CreateQueueOperation

    create_op = CreateQueueOperation(http_client_manager, rabbitmq_settings)
    queue_name = f"idempotent-queue-{uuid.uuid4().hex[:8]}"

    # Create queue first time
    result1 = await create_op.execute(
        vhost="/", name=queue_name, durable=True, auto_delete=False
    )
    assert result1["name"] == queue_name

    # Create queue second time with same properties (should succeed)
    result2 = await create_op.execute(
        vhost="/", name=queue_name, durable=True, auto_delete=False
    )
    assert result2["name"] == queue_name

    # Cleanup
    from rabbitmq_mcp_connection.operations.topology import DeleteQueueOperation

    delete_op = DeleteQueueOperation(http_client_manager, rabbitmq_settings)
    await delete_op.execute(vhost="/", name=queue_name, force=False)


@pytest.mark.asyncio
@pytest.mark.integration
async def test_safety_validation_with_testcontainer(
    rabbitmq_settings, http_client_manager
):
    """Demonstrate safety validation testing (Story 3.3 pattern)."""
    from rabbitmq_mcp_connection.operations.topology import (
        CreateQueueOperation,
        DeleteQueueOperation,
    )
    from utils.errors import ValidationError

    create_op = CreateQueueOperation(http_client_manager, rabbitmq_settings)
    delete_op = DeleteQueueOperation(http_client_manager, rabbitmq_settings)

    queue_name = f"safety-queue-{uuid.uuid4().hex[:8]}"

    # Create queue
    await create_op.execute(vhost="/", name=queue_name, durable=True, auto_delete=False)

    # Try to delete without force flag (should succeed if no messages)
    result = await delete_op.execute(vhost="/", name=queue_name, force=False)
    assert result["status"] == "deleted"


# Note: To run these tests:
# uv run pytest tests/integration/test_testcontainers_examples.py -m integration -v
#
# Prerequisites:
# - Docker Desktop running
# - testcontainers>=3.7 installed (included in dev dependencies)
#
# These tests demonstrate:
# 1. Using testcontainer fixtures from conftest.py
# 2. Testing topology operations with real RabbitMQ
# 3. Test isolation with unique resource names
# 4. Clean teardown (container stops automatically)
