"""
Tests unitaires pour le module utils.logger.

Ces tests vérifient que le système de logging fonctionne correctement.
"""

import pytest
import logging
from pathlib import Path
from utils.logger import setup_logger, get_logger


class TestSetupLogger:
    """Tests pour la fonction setup_logger."""

    def test_logger_creation(self):
        """Test la création basique d'un logger."""
        logger = setup_logger("test_logger")

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

    def test_logger_level_default(self):
        """Test que le niveau par défaut est INFO."""
        logger = setup_logger("test_logger_level")

        assert logger.level == logging.INFO

    def test_logger_level_custom(self):
        """Test la configuration d'un niveau personnalisé."""
        logger = setup_logger("test_logger_debug", level="DEBUG")

        assert logger.level == logging.DEBUG

    def test_logger_has_handlers(self):
        """Test que le logger a au moins un handler (console)."""
        logger = setup_logger("test_logger_handlers")

        assert len(logger.handlers) >= 1

    def test_logger_console_handler(self):
        """Test la présence du handler console."""
        logger = setup_logger("test_logger_console")

        has_stream_handler = any(
            isinstance(h, logging.StreamHandler) for h in logger.handlers
        )
        assert has_stream_handler

    def test_logger_file_handler(self, temp_log_dir, monkeypatch):
        """Test la création du handler fichier."""
        # Changer le répertoire de logs temporairement
        monkeypatch.chdir(temp_log_dir.parent)

        logger = setup_logger("test_logger_file", log_to_file=True)

        has_file_handler = any(
            isinstance(h, logging.FileHandler) for h in logger.handlers
        )
        assert has_file_handler

    def test_logger_no_duplicate(self):
        """Test qu'appeler setup_logger deux fois ne duplique pas les handlers."""
        logger1 = setup_logger("test_logger_duplicate")
        initial_handlers = len(logger1.handlers)

        logger2 = setup_logger("test_logger_duplicate")

        assert logger1 is logger2
        assert len(logger2.handlers) == initial_handlers

    def test_logger_propagate_false(self):
        """Test que la propagation est désactivée."""
        logger = setup_logger("test_logger_propagate")

        assert logger.propagate is False

    def test_logger_without_file(self):
        """Test la création d'un logger sans fichier."""
        logger = setup_logger("test_logger_no_file", log_to_file=False)

        has_file_handler = any(
            isinstance(h, logging.FileHandler) for h in logger.handlers
        )
        assert not has_file_handler


class TestGetLogger:
    """Tests pour la fonction get_logger."""

    def test_get_existing_logger(self):
        """Test la récupération d'un logger existant."""
        logger1 = setup_logger("test_get_existing")
        logger2 = get_logger("test_get_existing")

        assert logger1 is logger2

    def test_get_new_logger(self):
        """Test la création d'un nouveau logger si inexistant."""
        logger = get_logger("test_get_new_logger")

        assert logger is not None
        assert isinstance(logger, logging.Logger)
        assert len(logger.handlers) > 0


class TestLoggerFunctionality:
    """Tests de la fonctionnalité du logger."""

    def test_logger_info_message(self, caplog):
        """Test l'émission d'un message INFO."""
        logger = setup_logger("test_info")

        with caplog.at_level(logging.INFO, logger="test_info"):
            logger.info("Test message INFO")

        assert "Test message INFO" in caplog.text or logger.level == logging.INFO

    def test_logger_warning_message(self, caplog):
        """Test l'émission d'un message WARNING."""
        logger = setup_logger("test_warning")

        with caplog.at_level(logging.WARNING, logger="test_warning"):
            logger.warning("Test message WARNING")

        assert "Test message WARNING" in caplog.text or logger.level <= logging.WARNING

    def test_logger_error_message(self, caplog):
        """Test l'émission d'un message ERROR."""
        logger = setup_logger("test_error")

        with caplog.at_level(logging.ERROR, logger="test_error"):
            logger.error("Test message ERROR")

        assert "Test message ERROR" in caplog.text or logger.level <= logging.ERROR

    def test_logger_debug_not_shown_by_default(self, caplog):
        """Test que DEBUG n'est pas affiché avec niveau INFO."""
        logger = setup_logger("test_debug_hidden", level="INFO")

        with caplog.at_level(logging.DEBUG):
            logger.debug("Test message DEBUG")

        # Le message DEBUG ne doit pas apparaître si le niveau est INFO
        assert logger.level == logging.INFO

    def test_logger_debug_shown_with_debug_level(self, caplog):
        """Test que DEBUG est affiché avec niveau DEBUG."""
        logger = setup_logger("test_debug_shown", level="DEBUG")

        with caplog.at_level(logging.DEBUG, logger="test_debug_shown"):
            logger.debug("Test message DEBUG visible")

        assert "Test message DEBUG visible" in caplog.text or logger.level == logging.DEBUG

    def test_logger_exception_with_traceback(self, caplog):
        """Test l'enregistrement d'une exception avec traceback."""
        logger = setup_logger("test_exception")

        try:
            raise ValueError("Test exception")
        except ValueError:
            with caplog.at_level(logging.ERROR, logger="test_exception"):
                logger.error("Exception capturée", exc_info=True)

        # Vérifier que le logger fonctionne même si caplog ne capture pas
        assert logger.level <= logging.ERROR
