"""Tests for logging configuration behaviour."""

import logging
from pathlib import Path

from dotpromptz.logging import _StructuredFormatter, configure_logging, get_logger


def _cleanup_dotpromptz_handlers() -> None:
    """Remove handlers created by configure_logging during tests."""
    root = logging.getLogger()
    for handler in list(root.handlers):
        if isinstance(handler.formatter, _StructuredFormatter):
            root.removeHandler(handler)
            handler.close()


def test_configure_logging_closes_previous_file_handler(tmp_path: Path) -> None:
    """Old file handlers are detached and their streams are closed."""
    _cleanup_dotpromptz_handlers()
    root = logging.getLogger()
    stale_handler = logging.FileHandler(tmp_path / 'stale.log', encoding='utf-8')
    root.addHandler(stale_handler)
    stale_stream = stale_handler.stream
    assert stale_stream is not None
    assert not stale_stream.closed

    configure_logging(level='INFO', log_dir=tmp_path)

    assert stale_handler not in root.handlers
    assert stale_stream.closed


def test_configure_logging_reconfigure_does_not_accumulate_handlers(tmp_path: Path) -> None:
    """Reconfiguring logging keeps a stable handler count."""
    _cleanup_dotpromptz_handlers()
    root = logging.getLogger()

    configure_logging(level='INFO', log_dir=tmp_path)
    first_handlers = [handler for handler in root.handlers if isinstance(handler.formatter, _StructuredFormatter)]
    assert len(first_handlers) == 2

    configure_logging(level='DEBUG', log_dir=tmp_path)
    second_handlers = [handler for handler in root.handlers if isinstance(handler.formatter, _StructuredFormatter)]
    assert len(second_handlers) == 2
    assert all(handler not in second_handlers for handler in first_handlers)


def test_structured_fields_are_rendered_to_file(tmp_path: Path) -> None:
    """Structured key/value fields should appear in file logs."""
    _cleanup_dotpromptz_handlers()
    configure_logging(level='INFO', log_dir=tmp_path)
    logger = get_logger('dotpromptz.test')

    logger.info('hello world', user='alice', attempts=2)
    for handler in logging.getLogger().handlers:
        if hasattr(handler, 'flush'):
            handler.flush()

    log_files = sorted(tmp_path.glob('dotpromptz_*.log'))
    assert log_files
    content = log_files[-1].read_text(encoding='utf-8')
    assert 'hello world' in content
    assert "user='alice'" in content
    assert 'attempts=2' in content


def test_configure_logging_suppresses_third_party_info_logs(tmp_path: Path) -> None:
    """Noisy third-party INFO logs stay hidden outside DEBUG mode."""
    _cleanup_dotpromptz_handlers()
    configure_logging(level='INFO', log_dir=tmp_path)
    google_logger = logging.getLogger('google_genai.models')
    httpx_logger = logging.getLogger('httpx')

    assert google_logger.level == logging.WARNING
    assert not google_logger.isEnabledFor(logging.INFO)
    assert google_logger.isEnabledFor(logging.WARNING)
    assert httpx_logger.level == logging.WARNING
    assert not httpx_logger.isEnabledFor(logging.INFO)
    assert httpx_logger.isEnabledFor(logging.WARNING)


def test_configure_logging_allows_third_party_info_logs_in_debug(tmp_path: Path) -> None:
    """Noisy third-party INFO logs remain available in DEBUG mode."""
    _cleanup_dotpromptz_handlers()
    configure_logging(level='DEBUG', log_dir=tmp_path)
    google_logger = logging.getLogger('google_genai.models')
    httpx_logger = logging.getLogger('httpx')

    assert google_logger.level == logging.INFO
    assert google_logger.isEnabledFor(logging.INFO)
    assert httpx_logger.level == logging.INFO
    assert httpx_logger.isEnabledFor(logging.INFO)
