"""
Integration tests for Logging module
Tests logger configuration, handlers, filters, and FastAPI middleware

Auto-generated by RapidKit - Logging Module
"""

import importlib
import importlib.util
import logging
from pathlib import Path

import pytest

from src.health.logging import register_logging_health  # type: ignore[import]


pytestmark = [pytest.mark.integration, pytest.mark.template_integration]


def test_imports():
    """Test that all essential exports are available"""
    logging_module = importlib.import_module("src.modules.free.essentials.logging.logging")
    expected_symbols = [
        "get_logger",
        "LoggingConfig",
        "JsonFormatter",
        "ColoredFormatter",
        "NoiseFilter",
        "RedactionFilter",
        "ContextEnricher",
        "create_stream_handler",
        "create_file_handler",
        "get_logging_metadata",
    ]

    for symbol in expected_symbols:
        assert hasattr(logging_module, symbol), f"Missing symbol: {symbol}"


def test_get_logger_basic():
    """Test basic logger creation"""
    from src.modules.free.essentials.logging.logging import get_logger

    logger = get_logger(__name__)

    assert logger is not None
    assert isinstance(logger, logging.Logger)
    assert logger.name == __name__


def test_get_logger_returns_same_instance():
    """Test that get_logger returns same logger for same name"""
    from src.modules.free.essentials.logging.logging import get_logger

    logger1 = get_logger("test_module")
    logger2 = get_logger("test_module")

    assert logger1 is logger2


def test_logger_has_methods():
    """Test logger has standard logging methods"""
    from src.modules.free.essentials.logging.logging import get_logger

    logger = get_logger(__name__)

    assert hasattr(logger, "debug")
    assert hasattr(logger, "info")
    assert hasattr(logger, "warning")
    assert hasattr(logger, "error")
    assert hasattr(logger, "critical")
    assert hasattr(logger, "exception")

    # All should be callable
    assert callable(logger.debug)
    assert callable(logger.info)
    assert callable(logger.warning)
    assert callable(logger.error)


def test_logging_config():
    """Test LoggingConfig dataclass"""
    from src.modules.free.essentials.logging.logging import LoggingConfig

    config = LoggingConfig(
        level="INFO",
        format="json",
        sinks=["stdout"],
        async_queue=False,
        file_path="logs/app.log",
        sampling_rate=1.0,
        otel_bridge_enabled=False,
        metrics_bridge_enabled=False,
    )

    assert hasattr(config, "level")
    assert hasattr(config, "format")

    # Should have sensible defaults
    assert config.level in ["DEBUG", "INFO", "WARNING", "ERROR", "CRITICAL"]


def test_json_formatter():
    """Test JsonFormatter creates valid JSON"""
    import json

    from src.modules.free.essentials.logging.logging import JsonFormatter

    formatter = JsonFormatter()

    # Create a log record
    logger = logging.getLogger("test")
    record = logger.makeRecord(
        "test", logging.INFO, __file__, 1, "Test message", (), None
    )

    # Format should produce valid JSON
    formatted = formatter.format(record)

    try:
        parsed = json.loads(formatted)
        assert isinstance(parsed, dict)
        assert "message" in parsed or "msg" in parsed
    except json.JSONDecodeError:
        pytest.fail("JsonFormatter did not produce valid JSON")


def test_colored_formatter():
    """Test ColoredFormatter formats records"""
    from src.modules.free.essentials.logging.logging import ColoredFormatter

    formatter = ColoredFormatter()

    # Create a log record
    logger = logging.getLogger("test")
    record = logger.makeRecord(
        "test", logging.INFO, __file__, 1, "Test message", (), None
    )

    # Should format without error
    formatted = formatter.format(record)
    assert isinstance(formatted, str)
    assert "Test message" in formatted


def test_noise_filter():
    """Test NoiseFilter filters log records"""
    from src.modules.free.essentials.logging.logging import NoiseFilter

    noise_filter = NoiseFilter()

    logger = logging.getLogger("test")
    record = logger.makeRecord(
        "test", logging.INFO, __file__, 1, "normal message", (), None
    )

    result = noise_filter.filter(record)

    assert isinstance(result, bool)


def test_redaction_filter():
    """Test RedactionFilter redacts sensitive data"""
    from src.modules.free.essentials.logging.logging import RedactionFilter

    redaction_filter = RedactionFilter()

    # Create a record with sensitive data
    logger = logging.getLogger("test")
    record = logger.makeRecord(
        "test",
        logging.INFO,
        __file__,
        1,
        "password=secret123 and token=abc123",
        (),
        None,
    )

    # Apply filter
    redaction_filter.filter(record)

    # Message should be redacted
    assert "secret123" not in record.getMessage()
    assert "abc123" not in record.getMessage()
    assert "***" in record.getMessage() or "[REDACTED]" in record.getMessage()


def test_context_enricher():
    """Test ContextEnricher adds context to records"""
    from src.modules.free.essentials.logging.logging import ContextEnricher

    enricher = ContextEnricher()

    # Create a log record
    logger = logging.getLogger("test")
    record = logger.makeRecord(
        "test", logging.INFO, __file__, 1, "Test message", (), None
    )

    # Apply enricher
    enricher.filter(record)

    # Should add context fields
    assert hasattr(record, "timestamp") or hasattr(record, "created")


def test_create_stream_handler():
    """Test stream handler creation"""
    from src.modules.free.essentials.logging.logging import create_stream_handler

    handler = create_stream_handler(style="plain")

    assert isinstance(handler, logging.Handler)
    assert handler.formatter is not None


def test_create_file_handler():
    """Test file handler creation"""
    import tempfile

    from src.modules.free.essentials.logging.logging import create_file_handler

    with tempfile.NamedTemporaryFile(suffix=".log", delete=False) as tmp:
        log_file = Path(tmp.name)

    try:
        handler = create_file_handler(style="plain", file_path=str(log_file))

        assert isinstance(handler, logging.Handler)
        assert handler.formatter is not None

        # Test logging
        logger = logging.getLogger("test_file")
        logger.addHandler(handler)
        logger.setLevel(logging.INFO)
        logger.info("Test message")

        handler.close()

        # Verify file was written
        assert log_file.exists()
        content = log_file.read_text(encoding="utf-8")
        assert "Test message" in content

    finally:
        if log_file.exists():
            log_file.unlink()


def test_module_exports():
    """Test that all expected symbols are exported"""
    from importlib import import_module

    logging_module = import_module("src.modules.free.essentials.logging.logging")

    expected_exports = [
        "get_logger",
        "LoggingConfig",
        "JsonFormatter",
        "ColoredFormatter",
        "NoiseFilter",
        "RedactionFilter",
        "ContextEnricher",
        "create_stream_handler",
        "create_file_handler",
        "get_logging_metadata",
    ]

    for export in expected_exports:
        assert hasattr(logging_module, export), f"Missing export: {export}"


def test_get_logging_metadata():
    """Ensure metadata helper exposes vendor details"""
    from src.modules.free.essentials.logging.logging import get_logging_metadata

    metadata = get_logging_metadata()

    assert metadata["module"] == "logging"
    assert metadata["version"]
    assert isinstance(metadata.get("available"), list)


@pytest.mark.skipif(
    importlib.util.find_spec("fastapi") is None,
    reason="FastAPI not installed",
)
def test_request_context_middleware():
    """Test RequestContextMiddleware if FastAPI is available"""
    try:
        from fastapi import FastAPI

        from src.modules.free.essentials.logging.logging import RequestContextMiddleware

        app = FastAPI()

        # Should be able to add middleware
        app.add_middleware(RequestContextMiddleware)

        assert RequestContextMiddleware is not None

    except (ImportError, RuntimeError):
        pytest.skip("RequestContextMiddleware not available or disabled")


def test_logger_levels():
    """Test that logger respects level settings"""
    from src.modules.free.essentials.logging.logging import get_logger

    logger = get_logger("test_levels")
    logger.setLevel(logging.WARNING)

    # Create a handler to capture logs
    from io import StringIO

    stream = StringIO()
    handler = logging.StreamHandler(stream)
    logger.addHandler(handler)

    # Debug should not be logged
    logger.debug("debug message")
    # Warning should be logged
    logger.warning("warning message")

    output = stream.getvalue()
    assert "debug message" not in output
    assert "warning message" in output

    logger.removeHandler(handler)


@pytest.mark.skipif(
    importlib.util.find_spec("fastapi") is None,
    reason="FastAPI not installed",
)
def test_logging_health_router_registration():
    """Register the logging health router and ensure the path is exposed"""
    from fastapi import FastAPI

    app = FastAPI()
    register_logging_health(app)

    paths = {route.path for route in app.routes}
    assert "/api/health/module/logging" in paths


@pytest.mark.skipif(
    importlib.util.find_spec("fastapi") is None,
    reason="FastAPI not installed",
)
def test_logging_health_endpoint_payload():
    """Invoke the logging health endpoint and validate its payload"""
    from fastapi import FastAPI, status
    from fastapi.testclient import TestClient

    app = FastAPI()
    register_logging_health(app)

    client = TestClient(app)
    response = client.get("/api/health/module/logging")

    assert response.status_code == status.HTTP_200_OK
    payload = response.json()
    assert payload["status"] == "ok"
    assert payload["module"] == "logging"
    assert payload["version"]
