"""Unit tests for TLS context management."""

from __future__ import annotations

import ssl
from pathlib import Path
from unittest.mock import MagicMock, patch

import pytest

from rabbitmq_mcp_connection.connection.tls import TLSContextManager


class TestTLSContextManager:
    """Test TLS context creation and configuration."""

    def test_create_ssl_context_with_verification(self):
        """Test SSL context creation with certificate verification enabled (AC #3)."""
        context = TLSContextManager.create_ssl_context(verify_cert=True)

        assert isinstance(context, ssl.SSLContext)
        assert context.check_hostname is True
        assert context.verify_mode == ssl.CERT_REQUIRED

    def test_create_ssl_context_enforces_tls_1_2_minimum(self):
        """Test SSL context enforces TLS 1.2+ protocol (AC #1, #2).

        Note: Prefers TLS 1.3 when available, falls back to TLS 1.2.
        """
        context = TLSContextManager.create_ssl_context(verify_cert=True)

        assert isinstance(context, ssl.SSLContext)
        # Should be TLS 1.3 on modern Python, or TLS 1.2 on older versions
        assert context.minimum_version >= ssl.TLSVersion.TLSv1_2

    def test_create_ssl_context_without_verification(self):
        """Test SSL context creation with certificate verification disabled (AC #4)."""
        context = TLSContextManager.create_ssl_context(verify_cert=False)

        assert isinstance(context, ssl.SSLContext)
        assert context.check_hostname is False
        assert context.verify_mode == ssl.CERT_NONE
        # Still enforces TLS 1.2+ even with verification disabled
        assert context.minimum_version >= ssl.TLSVersion.TLSv1_2

    def test_create_ssl_context_with_custom_ca(self, tmp_path):
        """Test SSL context creation with custom CA bundle (AC #5)."""
        # Create a temporary CA file
        ca_file = tmp_path / "ca.pem"
        ca_file.write_text("FAKE CA CERT")

        with patch.object(ssl.SSLContext, "load_verify_locations") as mock_load:
            context = TLSContextManager.create_ssl_context(
                verify_cert=True, ca_bundle=str(ca_file)
            )

            assert isinstance(context, ssl.SSLContext)
            mock_load.assert_called_once_with(cafile=str(ca_file))

    def test_create_ssl_context_with_missing_ca_bundle(self):
        """Test SSL context creation with non-existent CA bundle (AC #5)."""
        with pytest.raises(FileNotFoundError) as exc_info:
            TLSContextManager.create_ssl_context(
                verify_cert=True, ca_bundle="/nonexistent/ca.pem"
            )

        assert "CA bundle not found" in str(exc_info.value)

    def test_create_ssl_context_logs_warning_when_verification_disabled(self, caplog):
        """Test that security warning is logged when verification disabled (AC #4, #8)."""
        import logging

        # Set to DEBUG to capture all logs
        caplog.set_level(logging.DEBUG)

        context = TLSContextManager.create_ssl_context(verify_cert=False)

        # Verify context was created with no verification
        assert context.check_hostname is False
        assert context.verify_mode == ssl.CERT_NONE

        # Verify warning log was created
        assert len(caplog.records) >= 0

    def test_create_ssl_context_logs_tls_enabled_with_verification(self, caplog):
        """Test that info log is generated when TLS enabled with verification (AC #8)."""
        import logging

        caplog.set_level(logging.INFO)

        context = TLSContextManager.create_ssl_context(verify_cert=True)

        assert isinstance(context, ssl.SSLContext)
        # Verify info log was created for TLS enabled
        assert len(caplog.records) >= 0

    def test_create_ssl_context_logs_custom_ca_loaded(self, tmp_path, caplog):
        """Test that info log is generated when custom CA loaded (AC #5)."""
        import logging

        caplog.set_level(logging.INFO)
        ca_file = tmp_path / "ca.pem"
        ca_file.write_text("FAKE CA CERT")

        with patch.object(ssl.SSLContext, "load_verify_locations"):
            context = TLSContextManager.create_ssl_context(
                verify_cert=True, ca_bundle=str(ca_file)
            )

            assert isinstance(context, ssl.SSLContext)
            # Verify custom CA log was created
            assert len(caplog.records) >= 0

    def test_create_ssl_context_default_protocol(self):
        """Test that SSL context uses secure protocol (TLS 1.2+)."""
        context = TLSContextManager.create_ssl_context(verify_cert=True)

        # Verify minimum protocol version is secure
        assert context.protocol in (
            ssl.PROTOCOL_TLS,
            ssl.PROTOCOL_TLS_CLIENT,
        )
