from __future__ import annotations

"""
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/>.
"""

"""Integration tests for vhost validation with topology operations (Story 3.11)."""

import pytest

from rabbitmq_mcp_connection.connection.exceptions import VHostNotFoundError
from rabbitmq_mcp_connection.http_client import HTTPClientManager
from rabbitmq_mcp_connection.operations.topology import (
    CreateQueueOperation,
    ListQueuesOperation,
)
from rabbitmq_mcp_connection.schemas.topology import CreateQueueRequest


@pytest.mark.integration
class TestVhostValidationIntegration:
    """Integration tests with real RabbitMQ to validate vhost checking."""

    @pytest.fixture
    def http_client(self, rabbitmq_config):
        """Create HTTP client for RabbitMQ."""
        return HTTPClientManager(
            host=rabbitmq_config["host"],
            port=rabbitmq_config["management_port"],
            username=rabbitmq_config["username"],
            password=rabbitmq_config["password"],
            use_tls=False,
            timeout=30,
        )

    @pytest.mark.asyncio
    async def test_list_queues_invalid_vhost(self, http_client):
        """Test ListQueuesOperation validates vhost before API call (AC #1)."""
        operation = ListQueuesOperation(http_client)

        with pytest.raises(VHostNotFoundError) as exc_info:
            await operation.execute(vhost="/invalid")

        # Should include available vhosts in error (AC #2)
        error_msg = str(exc_info.value)
        assert "/invalid" in error_msg
        assert "does not exist" in error_msg
        assert "/" in error_msg  # Default vhost should be available

    @pytest.mark.asyncio
    async def test_create_queue_invalid_vhost(self, http_client):
        """Test CreateQueueOperation validates vhost before API call (AC #1)."""
        operation = CreateQueueOperation(http_client)

        request = CreateQueueRequest(
            vhost="/invalid",
            name="test-queue",
            durable=True,
            auto_delete=False,
        )

        with pytest.raises(VHostNotFoundError) as exc_info:
            await operation.execute(request=request)

        # Should include available vhosts in error (AC #2)
        error_msg = str(exc_info.value)
        assert "/invalid" in error_msg

    @pytest.mark.asyncio
    async def test_validation_with_valid_vhost(self, http_client):
        """Test operations succeed with valid vhost."""
        operation = ListQueuesOperation(http_client)

        # Should not raise error for default vhost
        queues = await operation.execute(vhost="/")

        # Should return list (may be empty)
        assert isinstance(queues, list)

    @pytest.mark.asyncio
    async def test_validation_caching_performance(self, http_client):
        """Test multiple operations benefit from cache (AC #4)."""
        operation = ListQueuesOperation(http_client)

        # First call - populates cache
        await operation.execute(vhost="/")

        # Subsequent calls should use cache (no additional latency for validation)
        import time

        start = time.perf_counter()
        await operation.execute(vhost="/")
        duration = (time.perf_counter() - start) * 1000

        # Total operation including cache check should be reasonable
        # Even with API call, should be fast
        assert duration < 1000, f"Operation took {duration}ms"

    @pytest.mark.asyncio
    async def test_cache_invalidation_after_vhost_operations(self, http_client):
        """Test cache invalidation works correctly (AC #6)."""
        operation = ListQueuesOperation(http_client)

        # Validate with default vhost
        await operation.execute(vhost="/")

        # Get validator and invalidate cache
        validator = http_client._vhost_validator
        validator.invalidate_cache()

        # Should still work after cache invalidation
        await operation.execute(vhost="/")

    @pytest.mark.asyncio
    async def test_correlation_id_in_validation(self, http_client):
        """Test correlation_id is passed through validation."""
        operation = ListQueuesOperation(http_client)
        correlation_id = "test-correlation-123"

        # Should not raise error and should handle correlation_id
        queues = await operation.execute(vhost="/", correlation_id=correlation_id)
        assert isinstance(queues, list)
