"""
Comprehensive unit tests for StormLogger with 100% coverage
"""

import pytest
from unittest.mock import patch, MagicMock
import logging
from pathlib import Path

from storm_logger.core.logger import (
    StormLogger, 
    get_storm_logger, 
    setup_storm_logging,
    configure_storm_logging,
    get_logger,
    _logger_instances
)
from storm_logger.config import StormLoggerConfig

class TestStormLogger:
    """Test suite for StormLogger class"""

    @pytest.fixture
    def config(self):
        """Create a test configuration"""
        return StormLoggerConfig(
            log_level="DEBUG",
            enable_console=True,
            log_directory=Path("/tmp/test_logs"),
            enable_context_detection=True,
            enable_business_metrics=True,
            enable_professional_formatting=True
        )

    @pytest.fixture
    def logger(self, config):
        """Create a test logger instance"""
        return StormLogger("test_logger", config, auto_detect_context=True)

    @pytest.fixture
    def logger_no_context(self, config):
        """Create a test logger without context detection"""
        config.enable_context_detection = False
        return StormLogger("test_logger_no_ctx", config, auto_detect_context=False)

    @pytest.fixture(autouse=True)
    def clear_logger_cache(self):
        """Clear the logger instances cache before each test"""
        _logger_instances.clear()
        yield
        _logger_instances.clear()

    def test_init(self, logger, config):
        """Test logger initialization"""
        assert logger.name == "test_logger"
        assert logger.config == config
        assert logger.auto_detect_context is True
        assert logger._context_detector is not None
        assert logger._business_metrics == {}

    def test_init_without_context_detection(self, logger_no_context):
        """Test logger initialization without context detection"""
        assert logger_no_context._context_detector is None
        assert logger_no_context.auto_detect_context is False

    def test_init_with_context_disabled_in_config(self, config):
        """Test logger when context detection is disabled in config"""
        config.enable_context_detection = False
        logger = StormLogger("test", config, auto_detect_context=True)
        assert logger._context_detector is None

    @patch('storm_logger.core.logger.setup_logging_directories')
    @patch('storm_logger.core.logger.create_base_logging_config')
    @patch('logging.config.dictConfig')
    def test_configure_handlers(self, mock_dict_config, mock_create_config, 
                               mock_setup_dirs, logger):
        """Test handler configuration"""
        mock_create_config.return_value = {"version": 1}
        
        logger._configure_handlers()
        
        mock_setup_dirs.assert_called_once_with(logger.config)
        mock_create_config.assert_called_once_with(logger.config)
        mock_dict_config.assert_called_once_with({"version": 1})

    def test_configure_formatters(self, logger):
        """Test formatter configuration (no-op method)"""
        # This method does nothing, just ensure it doesn't raise
        logger._configure_formatters()

    def test_format_message_with_context(self, logger):
        """Test message formatting with context detection"""
        mock_context = {"framework": "django", "module": "views"}
        logger._context_detector.get_context = MagicMock(return_value=mock_context)
        
        result = logger._format_message("Test message", "INFO")
        
        assert result == "Test message"
        logger._context_detector.get_context.assert_called_once()

    def test_format_message_without_context(self, logger_no_context):
        """Test message formatting without context detection"""
        result = logger_no_context._format_message("Test message", "INFO")
        assert result == "Test message"

    def test_format_message_with_business_metrics(self, logger):
        """Test message formatting with business metrics"""
        logger._business_metrics = {"metric1": "value1"}
        result = logger._format_message("Test", "INFO")
        assert result == "Test"

    def test_format_message_without_business_metrics(self, config):
        """Test message formatting without business metrics"""
        config.enable_business_metrics = False
        logger = StormLogger("test", config)
        result = logger._format_message("Test", "INFO")
        assert result == "Test"

    @patch('storm_logger.core.base.BaseStormLogger.debug')
    def test_debug(self, mock_base_debug, logger):
        """Test debug logging"""
        logger.debug("Debug message", extra_param="value")
        
        mock_base_debug.assert_called_once_with("Debug message", extra_param="value")

    @patch('storm_logger.core.base.BaseStormLogger.info')
    def test_info(self, mock_base_info, logger):
        """Test info logging"""
        logger.info("Info message", extra_param="value")
        
        mock_base_info.assert_called_once_with("Info message", extra_param="value")

    @patch('storm_logger.core.base.BaseStormLogger.warning')
    def test_warning(self, mock_base_warning, logger):
        """Test warning logging"""
        logger.warning("Warning message", extra_param="value")
        
        mock_base_warning.assert_called_once_with("Warning message", extra_param="value")

    @patch('storm_logger.core.base.BaseStormLogger.error')
    def test_error(self, mock_base_error, logger):
        """Test error logging"""
        logger.error("Error message", exc_info=True, extra_param="value")
        
        mock_base_error.assert_called_once_with(
            "Error message", 
            exc_info=True, 
            extra_param="value"
        )

    @patch('storm_logger.core.base.BaseStormLogger.critical')
    def test_critical(self, mock_base_critical, logger):
        """Test critical logging"""
        logger.critical("Critical message", exc_info=True, extra_param="value")
        
        mock_base_critical.assert_called_once_with(
            "Critical message", 
            exc_info=True, 
            extra_param="value"
        )

    @patch('storm_logger.core.base.BaseStormLogger.info')
    def test_success(self, mock_base_info, logger):
        """Test success logging with metrics"""
        logger.success("Operation succeeded", timestamp="2024-01-01", context="test")
        
        # Check business metric was recorded
        assert len(logger._business_metrics) == 1
        metric_key = list(logger._business_metrics.keys())[0]
        assert logger._business_metrics[metric_key]['type'] == 'success'
        assert logger._business_metrics[metric_key]['message'] == 'Operation succeeded'
        
        # Check info was called
        mock_base_info.assert_called_once()
        args = mock_base_info.call_args[0]
        assert "✅ SUCCESS: Operation succeeded" in args[0]

    @patch('storm_logger.core.base.BaseStormLogger.info')
    def test_success_without_metrics(self, mock_base_info, config):
        """Test success logging without metrics"""
        config.enable_business_metrics = False
        logger = StormLogger("test", config)
        
        logger.success("Operation succeeded")
        
        assert len(logger._business_metrics) == 0
        mock_base_info.assert_called_once()

    @patch('storm_logger.core.base.BaseStormLogger.info')
    def test_test_pass(self, mock_base_info, logger):
        """Test passed test logging"""
        logger.test_pass("test_feature", timestamp="2024-01-01")
        
        # Check business metric
        assert "test_pass_test_feature" in logger._business_metrics
        assert logger._business_metrics["test_pass_test_feature"]['type'] == 'test_pass'
        
        # Check info was called
        mock_base_info.assert_called_once()
        call_kwargs = mock_base_info.call_args[1]
        assert call_kwargs['test_name'] == 'test_feature'
        assert call_kwargs['test_status'] == 'passed'

    @patch('storm_logger.core.base.BaseStormLogger.info')
    def test_test_pass_without_metrics(self, mock_base_info, config):
        """Test passed test logging without metrics"""
        config.enable_business_metrics = False
        logger = StormLogger("test", config)
        
        logger.test_pass("test_feature")
        
        assert len(logger._business_metrics) == 0
        mock_base_info.assert_called_once()

    @patch('storm_logger.core.base.BaseStormLogger.error')
    def test_test_fail(self, mock_base_error, logger):
        """Test failed test logging"""
        logger.test_fail("test_feature", "Assertion failed", timestamp="2024-01-01")
        
        # Check business metric
        assert "test_fail_test_feature" in logger._business_metrics
        assert logger._business_metrics["test_fail_test_feature"]['type'] == 'test_fail'
        assert logger._business_metrics["test_fail_test_feature"]['error_message'] == 'Assertion failed'
        
        # Check error was called
        mock_base_error.assert_called_once()
        call_kwargs = mock_base_error.call_args[1]
        assert call_kwargs['test_name'] == 'test_feature'
        assert call_kwargs['test_status'] == 'failed'
        assert call_kwargs['error_message'] == 'Assertion failed'

    @patch('storm_logger.core.base.BaseStormLogger.error')
    def test_test_fail_without_metrics(self, mock_base_error, config):
        """Test failed test logging without metrics"""
        config.enable_business_metrics = False
        logger = StormLogger("test", config)
        
        logger.test_fail("test_feature", "Error")
        
        assert len(logger._business_metrics) == 0
        mock_base_error.assert_called_once()

    @patch('storm_logger.core.base.BaseStormLogger.error')
    def test_test_fail_without_error_message(self, mock_base_error, logger):
        """Test failed test logging without error message"""
        logger.test_fail("test_feature")
        
        mock_base_error.assert_called_once()
        args = mock_base_error.call_args[0]
        assert "❌ FAIL: test_feature" in args[0]
        assert " - " not in args[0]

    @patch('storm_logger.core.base.BaseStormLogger.info')
    def test_helpful_tip(self, mock_base_info, logger):
        """Test helpful tip logging"""
        logger.helpful_tip("Use pytest for testing", timestamp="2024-01-01")
        
        # Check business metric
        assert len(logger._business_metrics) == 1
        metric = list(logger._business_metrics.values())[0]
        assert metric['type'] == 'helpful_tip'
        assert metric['message'] == 'Use pytest for testing'
        
        # Check info was called
        mock_base_info.assert_called_once()
        call_kwargs = mock_base_info.call_args[1]
        assert call_kwargs['tip_type'] == 'helpful'

    @patch('storm_logger.core.base.BaseStormLogger.info')
    def test_helpful_tip_without_metrics(self, mock_base_info, config):
        """Test helpful tip logging without metrics"""
        config.enable_business_metrics = False
        logger = StormLogger("test", config)
        
        logger.helpful_tip("Use pytest")
        
        assert len(logger._business_metrics) == 0
        mock_base_info.assert_called_once()

    @patch('storm_logger.core.base.BaseStormLogger.info')
    def test_teaching_moment(self, mock_base_info, logger):
        """Test teaching moment logging"""
        logger.teaching_moment("Python decorators explained", timestamp="2024-01-01")
        
        # Check business metric
        assert len(logger._business_metrics) == 1
        metric = list(logger._business_metrics.values())[0]
        assert metric['type'] == 'teaching_moment'
        assert metric['message'] == 'Python decorators explained'
        
        # Check info was called
        mock_base_info.assert_called_once()
        call_kwargs = mock_base_info.call_args[1]
        assert call_kwargs['teaching_content'] is True

    @patch('storm_logger.core.base.BaseStormLogger.info')
    def test_teaching_moment_without_metrics(self, mock_base_info, config):
        """Test teaching moment logging without metrics"""
        config.enable_business_metrics = False
        logger = StormLogger("test", config)
        
        logger.teaching_moment("Python is great")
        
        assert len(logger._business_metrics) == 0
        mock_base_info.assert_called_once()

    @patch('storm_logger.core.base.BaseStormLogger.info')
    def test_business_metric(self, mock_base_info, logger):
        """Test business metric logging"""
        logger.business_metric("response_time", 150, 200, timestamp="2024-01-01")
        
        # Check metric was stored
        assert "response_time" in logger._business_metrics
        assert logger._business_metrics["response_time"]['value'] == 150
        assert logger._business_metrics["response_time"]['threshold'] == 200
        
        # Check info was called
        mock_base_info.assert_called_once()
        call_kwargs = mock_base_info.call_args[1]
        assert call_kwargs['metric_name'] == 'response_time'
        assert call_kwargs['metric_value'] == 150
        assert call_kwargs['metric_threshold'] == 200

    @patch('storm_logger.core.base.BaseStormLogger.info')
    def test_business_metric_without_threshold(self, mock_base_info, logger):
        """Test business metric logging without threshold"""
        logger.business_metric("user_count", 1000)
        
        mock_base_info.assert_called_once()
        args = mock_base_info.call_args[0]
        assert "Business Metric: user_count = 1000" in args[0]
        assert "threshold" not in args[0]

    @patch('storm_logger.core.base.BaseStormLogger.info')
    @patch('storm_logger.core.base.BaseStormLogger.error')
    def test_test_result_passed(self, mock_error, mock_info, logger):
        """Test result logging for passed test"""
        logger.test_result("test_feature", "passed", 1.23)
        
        mock_info.assert_called_once()
        mock_error.assert_not_called()
        call_kwargs = mock_info.call_args[1]
        assert call_kwargs['test_name'] == 'test_feature'
        assert call_kwargs['test_status'] == 'passed'
        assert call_kwargs['test_duration'] == 1.23

    @patch('storm_logger.core.base.BaseStormLogger.info')
    @patch('storm_logger.core.base.BaseStormLogger.error')
    def test_test_result_failed(self, mock_error, mock_info, logger):
        """Test result logging for failed test"""
        logger.test_result("test_feature", "failed", 0.5)
        
        mock_error.assert_called_once()
        mock_info.assert_not_called()
        call_kwargs = mock_error.call_args[1]
        assert call_kwargs['test_name'] == 'test_feature'
        assert call_kwargs['test_status'] == 'failed'
        assert call_kwargs['test_duration'] == 0.5

    @patch('storm_logger.core.base.BaseStormLogger.info')
    def test_test_result_without_duration(self, mock_info, logger):
        """Test result logging without duration"""
        logger.test_result("test_feature", "passed")
        
        mock_info.assert_called_once()
        args = mock_info.call_args[0]
        assert "Test: test_feature - PASSED" in args[0]
        assert "s)" not in args[0]

    @patch('storm_logger.core.base.BaseStormLogger.warning')
    @patch('storm_logger.core.base.BaseStormLogger.info')
    def test_performance_metric_exceeded_threshold(self, mock_info, mock_warning, logger):
        """Test performance metric when threshold is exceeded"""
        logger.performance_metric("db_query", 5.5, 2.0)
        
        mock_warning.assert_called_once()
        mock_info.assert_not_called()
        call_kwargs = mock_warning.call_args[1]
        assert call_kwargs['operation'] == 'db_query'
        assert call_kwargs['duration'] == 5.5
        assert call_kwargs['threshold'] == 2.0
        assert call_kwargs['performance_issue'] is True

    @patch('storm_logger.core.base.BaseStormLogger.info')
    def test_performance_metric_within_threshold(self, mock_info, logger):
        """Test performance metric within threshold"""
        logger.performance_metric("api_call", 0.8, 2.0)
        
        mock_info.assert_called_once()
        args = mock_info.call_args[0]
        assert "(within threshold: 2.000s)" in args[0]

    @patch('storm_logger.core.base.BaseStormLogger.info')
    def test_performance_metric_no_threshold(self, mock_info, logger):
        """Test performance metric without threshold"""
        logger.performance_metric("calculation", 1.234)
        
        mock_info.assert_called_once()
        args = mock_info.call_args[0]
        assert "Performance: calculation took 1.234s" in args[0]
        assert "threshold" not in args[0]

    @patch('storm_logger.core.base.BaseStormLogger.critical')
    def test_security_event_critical(self, mock_critical, logger):
        """Test critical security event logging"""
        logger.security_event("breach_attempt", "Unauthorized access detected", "critical")
        
        mock_critical.assert_called_once()
        call_kwargs = mock_critical.call_args[1]
        assert call_kwargs['event_type'] == 'breach_attempt'
        assert call_kwargs['security_event'] is True

    @patch('storm_logger.core.base.BaseStormLogger.error')
    def test_security_event_error(self, mock_error, logger):
        """Test error security event logging"""
        logger.security_event("auth_failure", "Invalid credentials", "error")
        
        mock_error.assert_called_once()
        call_kwargs = mock_error.call_args[1]
        assert call_kwargs['event_type'] == 'auth_failure'
        assert call_kwargs['security_event'] is True

    @patch('storm_logger.core.base.BaseStormLogger.warning')
    def test_security_event_warning(self, mock_warning, logger):
        """Test warning security event logging"""
        logger.security_event("suspicious_activity", "Multiple login attempts", "warning")
        
        mock_warning.assert_called_once()
        call_kwargs = mock_warning.call_args[1]
        assert call_kwargs['event_type'] == 'suspicious_activity'
        assert call_kwargs['security_event'] is True

    @patch('storm_logger.core.base.BaseStormLogger.info')
    def test_user_action_with_details(self, mock_info, logger):
        """Test user action logging with details"""
        logger.user_action("user123", "login", "Successful login from IP 192.168.1.1")
        
        mock_info.assert_called_once()
        args = mock_info.call_args[0]
        assert "User Action: user123 performed login - Successful login from IP 192.168.1.1" in args[0]
        
        call_kwargs = mock_info.call_args[1]
        assert call_kwargs['user_id'] == 'user123'
        assert call_kwargs['user_action'] == 'login'
        assert call_kwargs['action_details'] == 'Successful login from IP 192.168.1.1'

    @patch('storm_logger.core.base.BaseStormLogger.info')
    def test_user_action_without_details(self, mock_info, logger):
        """Test user action logging without details"""
        logger.user_action("user456", "logout")
        
        mock_info.assert_called_once()
        args = mock_info.call_args[0]
        assert "User Action: user456 performed logout" in args[0]
        assert " - " not in args[0]

    def test_get_business_metrics(self, logger):
        """Test getting business metrics"""
        logger._business_metrics = {"metric1": "value1", "metric2": "value2"}
        
        metrics = logger.get_business_metrics()
        
        assert metrics == {"metric1": "value1", "metric2": "value2"}
        # Ensure it's a copy
        assert metrics is not logger._business_metrics

    def test_clear_business_metrics(self, logger):
        """Test clearing business metrics"""
        logger._business_metrics = {"metric1": "value1", "metric2": "value2"}
        
        logger.clear_business_metrics()
        
        assert logger._business_metrics == {}

    def test_set_context(self, logger):
        """Test setting context manually"""
        mock_context_detector = MagicMock()
        logger._context_detector = mock_context_detector
        
        context = {"user": "test_user", "session": "12345"}
        logger.set_context(context)
        
        mock_context_detector.set_manual_context.assert_called_once_with(context)

    def test_set_context_no_detector(self, logger_no_context):
        """Test setting context when detector is None"""
        # Should not raise an exception
        logger_no_context.set_context({"key": "value"})

    @patch('logging.getLogger')
    def test_get_level(self, mock_get_logger, logger):
        """Test getting logger level"""
        mock_logger = MagicMock()
        mock_logger.level = logging.DEBUG
        logger._logger = mock_logger
        
        assert logger.getLevel() == logging.DEBUG

    @patch('logging.getLogger')
    def test_set_level(self, mock_get_logger, logger):
        """Test setting logger level"""
        mock_logger = MagicMock()
        logger._logger = mock_logger
        
        logger.setLevel(logging.WARNING)
        
        mock_logger.setLevel.assert_called_once_with(logging.WARNING)


class TestLoggerFactory:
    """Test suite for logger factory functions"""

    @pytest.fixture(autouse=True)
    def clear_cache(self):
        """Clear logger cache before each test"""
        _logger_instances.clear()
        yield
        _logger_instances.clear()

    @patch('storm_logger.core.logger.get_config')
    def test_get_storm_logger_with_default_config(self, mock_get_config):
        """Test getting logger with default config"""
        mock_config = MagicMock()
        mock_get_config.return_value = mock_config
        
        logger = get_storm_logger("test_logger")
        
        assert isinstance(logger, StormLogger)
        assert logger.name == "test_logger"
        mock_get_config.assert_called_once()

    def test_get_storm_logger_with_custom_config(self):
        """Test getting logger with custom config"""
        custom_config = StormLoggerConfig(log_level="WARNING")
        
        logger = get_storm_logger("test_logger", custom_config)
        
        assert isinstance(logger, StormLogger)
        assert logger.config == custom_config

    def test_get_storm_logger_caching(self):
        """Test logger instance caching"""
        config = StormLoggerConfig()
        
        logger1 = get_storm_logger("test_logger", config, True)
        logger2 = get_storm_logger("test_logger", config, True)
        
        assert logger1 is logger2
        assert len(_logger_instances) == 1

    def test_get_storm_logger_different_cache_keys(self):
        """Test different cache keys create different instances"""
        config1 = StormLoggerConfig(log_level="DEBUG")
        config2 = StormLoggerConfig(log_level="INFO")
        
        logger1 = get_storm_logger("test", config1)
        logger2 = get_storm_logger("test", config2)
        logger3 = get_storm_logger("test2", config1)
        logger4 = get_storm_logger("test", config1, False)
        
        assert logger1 is not logger2  # Different configs
        assert logger1 is not logger3  # Different names
        assert logger1 is not logger4  # Different auto_detect_context
        assert len(_logger_instances) == 4

    @patch('storm_logger.core.logger.get_config')
    @patch('storm_logger.core.logger.setup_logging_directories')
    def test_setup_storm_logging_default_config(self, mock_setup_dirs, mock_get_config):
        """Test setting up storm logging with default config"""
        mock_config = MagicMock()
        mock_get_config.return_value = mock_config
        
        with patch.object(StormLogger, '_configure_logger') as mock_configure:
            setup_storm_logging()
            
            mock_get_config.assert_called_once()
            mock_setup_dirs.assert_called_once_with(mock_config)
            mock_configure.assert_called_once()

    @patch('storm_logger.core.logger.setup_logging_directories')
    def test_setup_storm_logging_custom_config(self, mock_setup_dirs):
        """Test setting up storm logging with custom config"""
        custom_config = StormLoggerConfig(log_level="ERROR")
        
        with patch.object(StormLogger, '_configure_logger') as mock_configure:
            setup_storm_logging(custom_config)
            
            mock_setup_dirs.assert_called_once_with(custom_config)
            mock_configure.assert_called_once()

    @patch('storm_logger.core.logger.StormLoggerConfig.from_dict')
    @patch('storm_logger.core.logger.setup_storm_logging')
    def test_configure_storm_logging(self, mock_setup, mock_from_dict):
        """Test configuring storm logging from dict"""
        config_dict = {"log_level": "INFO", "enable_console": True}
        mock_config = MagicMock()
        mock_from_dict.return_value = mock_config
        
        configure_storm_logging(config_dict)
        
        mock_from_dict.assert_called_once_with(config_dict)
        mock_setup.assert_called_once_with(mock_config)

    @patch('storm_logger.core.logger.get_storm_logger')
    def test_get_logger(self, mock_get_storm_logger):
        """Test convenience get_logger function"""
        mock_logger = MagicMock()
        mock_get_storm_logger.return_value = mock_logger
        
        result = get_logger("test_module")
        
        assert result == mock_logger
        mock_get_storm_logger.assert_called_once_with("test_module")


class TestIntegration:
    """Integration tests for StormLogger"""

    @pytest.fixture
    def temp_log_dir(self, tmp_path):
        """Create temporary log directory"""
        log_dir = tmp_path / "logs"
        log_dir.mkdir()
        return log_dir

    def test_full_logging_workflow(self, temp_log_dir):
        """Test complete logging workflow"""
        config = StormLoggerConfig(
            log_level="DEBUG",
            enable_console=False,  # Disable console to avoid output during tests
            log_directory=temp_log_dir,
            enable_context_detection=True,
            enable_business_metrics=True
        )
        
        logger = StormLogger("integration_test", config)
        
        # Test various logging methods
        logger.debug("Debug message")
        logger.info("Info message")
        logger.warning("Warning message")
        logger.error("Error message")
        logger.critical("Critical message")
        
        logger.success("Operation completed")
        logger.test_pass("test_integration")
        logger.test_fail("test_failure", "Expected failure")
        logger.helpful_tip("Use type hints")
        logger.teaching_moment("Python is awesome")
        
        logger.business_metric("conversion_rate", 0.85, 0.80)
        logger.test_result("test_example", "passed", 1.5)
        logger.performance_metric("api_response", 0.250, 0.500)
        logger.security_event("login_attempt", "User logged in", "info")
        logger.user_action("user123", "update_profile", "Changed email")
        
        # Verify business metrics were collected
        metrics = logger.get_business_metrics()
        assert len(metrics) > 0
        assert "success_0" in metrics
        assert "test_pass_test_integration" in metrics
        assert "conversion_rate" in metrics
        
        # Clear metrics and verify
        logger.clear_business_metrics()
        assert logger.get_business_metrics() == {}

    def test_context_detection_integration(self):
        """Test context detection integration"""
        config = StormLoggerConfig(
            enable_context_detection=True,
            enable_business_metrics=True
        )
        
        logger = StormLogger("context_test", config)
        
        # Set manual context
        test_context = {"environment": "testing", "user_id": "test123"}
        logger.set_context(test_context)
        
        # Verify context is used in formatting
        with patch.object(logger._context_detector, 'get_context', 
                         return_value=test_context) as mock_get_context:
            logger._format_message("Test", "INFO")
            mock_get_context.assert_called_once()

    def test_logger_compatibility_methods(self):
        """Test logger compatibility methods"""
        config = StormLoggerConfig(enable_console=False)
        logger = StormLogger("compat_test", config)
        
        # Initialize the logger by calling a logging method
        with patch('storm_logger.core.base.BaseStormLogger.info'):
            logger.info("Initialize logger")
        
        # Now test level methods with a mock logger
        mock_logger = MagicMock()
        mock_logger.level = logging.WARNING
        logger._logger = mock_logger
        
        logger.setLevel(logging.WARNING)
        mock_logger.setLevel.assert_called_once_with(logging.WARNING)
        
        # Test getLevel
        assert logger.getLevel() == logging.WARNING