"""
Unit tests for Django integration module.

This test module provides comprehensive coverage for storm_logger.integrations.django,
including DjangoStormLogger, configuration functions, and Django-specific features.
"""

import logging
import logging.config
from pathlib import Path
from typing import Any, Dict, List, Optional
from unittest.mock import MagicMock, Mock, patch, PropertyMock, call

import pytest

from storm_logger.config import Framework, LogLevel, StormLoggerConfig
from storm_logger.integrations.django import (
    DjangoStormLogger,
    DJANGO_CONTEXT_PATTERNS,
    create_django_logging_config,
    _add_django_filters,
    _add_django_handlers,
    _add_django_loggers,
    _configure_app_specific_loggers,
    _add_production_enhancements,
    configure_django_logging,
    get_django_logging_config,
    integrate_with_django_settings,
    detect_django_context,
)


class TestDjangoStormLogger:
    """Test DjangoStormLogger class."""
    
    @pytest.fixture
    def mock_config(self):
        """Create mock configuration."""
        config = Mock(spec=StormLoggerConfig)
        config.framework = Framework.DJANGO
        config.log_level = LogLevel.INFO
        config.log_directory = Path("/tmp/logs")
        config.debug_mode = False
        config.production_mode = True
        return config
    
    @pytest.fixture
    def logger(self, mock_config):
        """Create DjangoStormLogger instance."""
        with patch('storm_logger.integrations.django.create_django_logging_config'):
            return DjangoStormLogger("test", mock_config)
    
    def test_init_default_config(self):
        """Test initialization with default config."""
        with patch('storm_logger.integrations.django.create_django_logging_config'):
            logger = DjangoStormLogger("test")
            assert logger.name == "test"
            assert logger.config.framework == Framework.DJANGO
    
    def test_init_with_config(self, mock_config):
        """Test initialization with custom config."""
        with patch('storm_logger.integrations.django.create_django_logging_config'):
            logger = DjangoStormLogger("test", mock_config)
            assert logger.name == "test"
            assert logger.config == mock_config
            assert logger.config.framework == Framework.DJANGO
    
    def test_init_forces_django_framework(self, mock_config):
        """Test that init forces framework to Django."""
        mock_config.framework = Framework.STANDALONE
        with patch('storm_logger.integrations.django.create_django_logging_config'):
            logger = DjangoStormLogger("test", mock_config)
            assert logger.config.framework == Framework.DJANGO
    
    def test_auto_detect_context_param(self):
        """Test auto_detect_context parameter."""
        with patch('storm_logger.integrations.django.create_django_logging_config'):
            # Default is True
            logger1 = DjangoStormLogger("test1")
            assert hasattr(logger1, 'auto_detect_context')
            assert logger1.auto_detect_context is True
            
            # Explicit False
            logger2 = DjangoStormLogger("test2", auto_detect_context=False)
            assert hasattr(logger2, 'auto_detect_context')
            assert logger2.auto_detect_context is False
    
    @patch('logging.config.dictConfig')
    def test_configure_handlers(self, mock_dictconfig, logger, mock_config):
        """Test handler configuration."""
        mock_logging_config = {'version': 1, 'handlers': {}}
        with patch('storm_logger.integrations.django.create_django_logging_config', 
                   return_value=mock_logging_config):
            logger._configure_handlers()
            mock_dictconfig.assert_called_once_with(mock_logging_config)


class TestDjangoLoggingConfig:
    """Test Django logging configuration functions."""
    
    @pytest.fixture
    def base_config(self):
        """Create base Storm Logger config."""
        config = StormLoggerConfig(
            log_level=LogLevel.INFO,
            log_directory=Path("/tmp/logs"),
            debug_mode=False,
            production_mode=True,
            max_file_size=10485760,
        )
        return config
    
    @pytest.fixture
    def django_config(self):
        """Create Django-specific config."""
        # Import here to avoid circular imports
        from storm_logger.integrations.django_config import DjangoStormLoggerConfig
        return DjangoStormLoggerConfig(
            log_level=LogLevel.INFO,
            log_directory=Path("/tmp/logs"),
            debug_mode=False,
            production_mode=True,
            app_log_levels={
                'myapp': LogLevel.DEBUG,
                'django.request': LogLevel.ERROR,
            },
            excluded_apps=['django.contrib.staticfiles'],
        )
    
    @patch('storm_logger.integrations.django.create_base_logging_config')
    def test_create_django_logging_config_basic(self, mock_base_config, base_config):
        """Test basic Django logging config creation."""
        mock_base_config.return_value = {
            'version': 1,
            'filters': {},
            'handlers': {},
            'loggers': {},
        }
        
        result = create_django_logging_config(base_config)
        
        assert isinstance(result, dict)
        assert 'version' in result
        assert 'filters' in result
        assert 'handlers' in result
        assert 'loggers' in result
        mock_base_config.assert_called_once_with(base_config)
    
    @patch('storm_logger.integrations.django.create_base_logging_config')
    @patch('storm_logger.integrations.django.check_optional_dependency')
    def test_create_django_logging_config_no_django(self, mock_check_dep, mock_base_config, base_config):
        """Test config creation when Django is not available."""
        mock_base_config.return_value = {'version': 1}
        mock_check_dep.return_value = False
        
        # Config without Django-specific attributes
        result = create_django_logging_config(base_config)
        
        assert result == {'version': 1}
        mock_check_dep.assert_called_once_with("django")
    
    @patch('storm_logger.integrations.django.create_base_logging_config')
    def test_create_django_logging_config_with_django_config(self, mock_base_config, django_config):
        """Test config creation with DjangoStormLoggerConfig."""
        mock_base_config.return_value = {
            'version': 1,
            'filters': {},
            'handlers': {},
            'loggers': {},
        }
        
        result = create_django_logging_config(django_config)
        
        # Should have Django-specific components
        assert 'require_debug_true' in result['filters']
        assert 'require_debug_false' in result['filters']
    
    def test_add_django_filters(self):
        """Test adding Django-specific filters."""
        config = {'filters': {}}
        _add_django_filters(config)
        
        assert 'require_debug_true' in config['filters']
        assert 'require_debug_false' in config['filters']
        assert config['filters']['require_debug_true']['()'] == 'django.utils.log.RequireDebugTrue'
        assert config['filters']['require_debug_false']['()'] == 'django.utils.log.RequireDebugFalse'
    
    def test_add_django_handlers_production(self, base_config):
        """Test adding handlers in production mode."""
        base_config.production_mode = True
        base_config.debug_mode = False
        logging_config = {'handlers': {}}
        
        _add_django_handlers(logging_config, base_config)
        
        assert 'mail_admins' in logging_config['handlers']
        assert 'syslog' in logging_config['handlers']
        assert 'django_file' in logging_config['handlers']
        assert 'debug_file' not in logging_config['handlers']
        
        # Check mail_admins configuration
        mail_handler = logging_config['handlers']['mail_admins']
        assert mail_handler['level'] == 'ERROR'
        assert mail_handler['class'] == 'django.utils.log.AdminEmailHandler'
        assert 'require_debug_false' in mail_handler['filters']
    
    def test_add_django_handlers_debug(self, base_config):
        """Test adding handlers in debug mode."""
        base_config.production_mode = False
        base_config.debug_mode = True
        logging_config = {'handlers': {}}
        
        _add_django_handlers(logging_config, base_config)
        
        assert 'debug_file' in logging_config['handlers']
        assert 'django_file' in logging_config['handlers']
        assert 'mail_admins' not in logging_config['handlers']
        assert 'syslog' not in logging_config['handlers']
        
        # Check debug_file configuration
        debug_handler = logging_config['handlers']['debug_file']
        assert debug_handler['level'] == 'DEBUG'
        assert debug_handler['class'] == 'logging.handlers.RotatingFileHandler'
        assert 'require_debug_true' in debug_handler['filters']
    
    def test_add_django_loggers_basic(self, base_config):
        """Test adding Django framework loggers."""
        base_config.production_mode = False
        logging_config = {'loggers': {}}
        
        _add_django_loggers(logging_config, base_config)
        
        assert 'django' in logging_config['loggers']
        assert 'django.request' in logging_config['loggers']
        assert 'django.security' in logging_config['loggers']
        assert 'django.db.backends' in logging_config['loggers']
        
        # Check django logger
        django_logger = logging_config['loggers']['django']
        assert django_logger['level'] == 'INFO'
        assert not django_logger['propagate']
        assert 'console' in django_logger['handlers']
    
    def test_add_django_loggers_production(self, base_config):
        """Test Django loggers in production mode."""
        base_config.production_mode = True
        base_config.debug_mode = False
        logging_config = {'loggers': {}}
        
        _add_django_loggers(logging_config, base_config)
        
        # Check request logger has mail_admins in production
        request_logger = logging_config['loggers']['django.request']
        assert 'mail_admins' in request_logger['handlers']
        
        # Check db logger has no debug handlers
        db_logger = logging_config['loggers']['django.db.backends']
        assert db_logger['handlers'] == []
        assert db_logger['level'] == 'INFO'
    
    def test_configure_app_specific_loggers_basic(self, base_config):
        """Test configuring app-specific loggers."""
        base_config.debug_mode = False
        logging_config = {'loggers': {}}
        
        _configure_app_specific_loggers(logging_config, base_config)
        
        # Check Storm app loggers
        storm_apps = [
            'storm.base', 'storm.billing', 'storm.auth',
            'storm.invoicing', 'storm.dashboard'
        ]
        for app in storm_apps:
            assert app in logging_config['loggers']
            logger = logging_config['loggers'][app]
            assert logger['level'] == base_config.log_level.value
            assert not logger['propagate']
            assert 'console' in logger['handlers']
    
    def test_configure_app_specific_loggers_with_django_config(self, django_config):
        """Test app-specific loggers with DjangoStormLoggerConfig."""
        logging_config = {'loggers': {}}
        
        _configure_app_specific_loggers(logging_config, django_config)
        
        # Check custom app log levels
        assert 'myapp' in logging_config['loggers']
        assert logging_config['loggers']['myapp']['level'] == LogLevel.DEBUG.value
        
        # Check excluded apps
        assert 'django.contrib.staticfiles' in logging_config['loggers']
        assert logging_config['loggers']['django.contrib.staticfiles']['level'] == 'ERROR'
    
    def test_add_production_enhancements(self, base_config):
        """Test adding production enhancements."""
        base_config.production_mode = True
        logging_config = {
            'loggers': {
                'myapp': {'handlers': ['console', 'file']},
                'django': {'handlers': ['console']},
            }
        }
        
        _add_production_enhancements(logging_config, base_config)
        
        # All loggers should have syslog handler added
        for logger_config in logging_config['loggers'].values():
            assert 'syslog' in logger_config['handlers']
    
    def test_add_production_enhancements_not_production(self, base_config):
        """Test production enhancements are not added in non-production."""
        base_config.production_mode = False
        original_config = {
            'loggers': {
                'myapp': {'handlers': ['console', 'file']},
            }
        }
        logging_config = original_config.copy()
        
        _add_production_enhancements(logging_config, base_config)
        
        # Should remain unchanged
        assert 'syslog' not in logging_config['loggers']['myapp']['handlers']


class TestDjangoIntegrationFunctions:
    """Test Django integration utility functions."""
    
    @pytest.fixture
    def mock_config(self):
        """Create mock configuration."""
        config = Mock(spec=StormLoggerConfig)
        config.framework = Framework.DJANGO
        config.create_log_directories = Mock()
        return config
    
    @patch('storm_logger.config.get_config')
    @patch('storm_logger.config.set_config')
    @patch('storm_logger.integrations.django.create_django_logging_config')
    @patch('logging.config.dictConfig')
    def test_configure_django_logging_no_config(self, mock_dictconfig, mock_create_config,
                                                mock_set_config, mock_get_config, mock_config):
        """Test configure_django_logging without config."""
        mock_get_config.return_value = mock_config
        mock_create_config.return_value = {'version': 1}
        
        configure_django_logging()
        
        mock_get_config.assert_called_once()
        mock_set_config.assert_called_once()
        mock_config.create_log_directories.assert_called_once()
        mock_dictconfig.assert_called_once_with({'version': 1})
    
    @patch('storm_logger.config.set_config')
    @patch('storm_logger.integrations.django.create_django_logging_config')
    @patch('logging.config.dictConfig')
    def test_configure_django_logging_with_config(self, mock_dictconfig, mock_create_config,
                                                  mock_set_config, mock_config):
        """Test configure_django_logging with custom config."""
        mock_create_config.return_value = {'version': 1}
        
        configure_django_logging(mock_config)
        
        assert mock_config.framework == Framework.DJANGO
        mock_set_config.assert_called_once_with(mock_config)
        mock_config.create_log_directories.assert_called_once()
        mock_dictconfig.assert_called_once_with({'version': 1})
    
    @patch('storm_logger.config.get_config')
    @patch('storm_logger.integrations.django.create_django_logging_config')
    def test_get_django_logging_config_no_config(self, mock_create_config, mock_get_config, mock_config):
        """Test get_django_logging_config without config."""
        mock_get_config.return_value = mock_config
        mock_create_config.return_value = {'version': 1}
        
        result = get_django_logging_config()
        
        assert result == {'version': 1}
        mock_get_config.assert_called_once()
        assert mock_config.framework == Framework.DJANGO
    
    @patch('storm_logger.integrations.django.create_django_logging_config')
    def test_get_django_logging_config_with_config(self, mock_create_config, mock_config):
        """Test get_django_logging_config with custom config."""
        mock_create_config.return_value = {'version': 1}
        
        result = get_django_logging_config(mock_config)
        
        assert result == {'version': 1}
        assert mock_config.framework == Framework.DJANGO
        mock_create_config.assert_called_once_with(mock_config)
    
    @patch('storm_logger.config.get_config')
    @patch('storm_logger.integrations.django.get_django_logging_config')
    def test_integrate_with_django_settings(self, mock_get_logging_config, mock_get_config, mock_config):
        """Test integrate_with_django_settings."""
        mock_get_config.return_value = mock_config
        mock_get_logging_config.return_value = {'version': 1}
        
        # Create mock settings module
        settings_module = Mock()
        settings_module.INSTALLED_APPS = ['django.contrib.admin']
        
        integrate_with_django_settings(settings_module)
        
        assert settings_module.LOGGING == {'version': 1}
        assert 'storm_logger' in settings_module.INSTALLED_APPS
        assert mock_config.framework == Framework.DJANGO
    
    @patch('storm_logger.config.get_config')
    @patch('storm_logger.integrations.django.get_django_logging_config')
    def test_integrate_with_django_settings_no_installed_apps(self, mock_get_logging_config, 
                                                              mock_get_config, mock_config):
        """Test integrate_with_django_settings without INSTALLED_APPS."""
        mock_get_config.return_value = mock_config
        mock_get_logging_config.return_value = {'version': 1}
        
        # Create mock settings module without INSTALLED_APPS
        settings_module = Mock(spec=[])
        
        integrate_with_django_settings(settings_module)
        
        assert hasattr(settings_module, 'INSTALLED_APPS')
        assert settings_module.INSTALLED_APPS == ['storm_logger']


class TestDjangoContextDetection:
    """Test Django context detection."""
    
    def test_detect_django_context_view(self):
        """Test detecting view context."""
        frame_info = Mock()
        frame_info.filename = '/app/myapp/views.py'
        frame_info.function = 'my_view'
        
        result = detect_django_context(frame_info)
        assert result == 'django.view'
    
    def test_detect_django_context_model(self):
        """Test detecting model context."""
        frame_info = Mock()
        frame_info.filename = '/app/myapp/models.py'
        frame_info.function = 'save'
        
        result = detect_django_context(frame_info)
        assert result == 'django.model'
    
    def test_detect_django_context_by_function(self):
        """Test detecting context by function name."""
        frame_info = Mock()
        frame_info.filename = '/app/myapp/utils.py'
        frame_info.function = 'MyForm'
        
        result = detect_django_context(frame_info)
        assert result == 'django.form'
    
    def test_detect_django_context_management_command(self):
        """Test detecting management command context."""
        frame_info = Mock()
        frame_info.filename = '/app/myapp/management/commands/mycommand.py'
        frame_info.function = 'handle'
        
        result = detect_django_context(frame_info)
        assert result == 'django.management'
    
    def test_detect_django_context_app_directory(self):
        """Test detecting app context from directory."""
        frame_info = Mock()
        frame_info.filename = '/app/myapp/apps/blog/utils.py'
        frame_info.function = 'process_data'
        
        result = detect_django_context(frame_info)
        assert result == 'django.app'
    
    def test_detect_django_context_django_directory(self):
        """Test detecting Django system context."""
        frame_info = Mock()
        frame_info.filename = '/site-packages/django/core/cache.py'
        frame_info.function = 'get_cache'
        
        result = detect_django_context(frame_info)
        assert result == 'django.app'
    
    def test_detect_django_context_default(self):
        """Test default Django context."""
        frame_info = Mock()
        frame_info.filename = '/app/some_random_file.py'
        frame_info.function = 'some_function'
        
        result = detect_django_context(frame_info)
        assert result == 'django.system'
    
    def test_django_context_patterns_completeness(self):
        """Test that all expected Django patterns are defined."""
        expected_contexts = [
            'view', 'model', 'form', 'admin', 'middleware',
            'management', 'template', 'static', 'test',
            'migration', 'signal', 'serializer', 'url',
            'settings', 'wsgi', 'asgi'
        ]
        
        for context in expected_contexts:
            assert context in DJANGO_CONTEXT_PATTERNS
            assert isinstance(DJANGO_CONTEXT_PATTERNS[context], list)
            assert len(DJANGO_CONTEXT_PATTERNS[context]) > 0


class TestDjangoIntegrationEdgeCases:
    """Test edge cases and error handling."""
    
    @patch('storm_logger.integrations.django.create_base_logging_config')
    def test_create_django_logging_config_with_exception(self, mock_base_config):
        """Test config creation handles exceptions gracefully."""
        mock_base_config.side_effect = Exception("Config error")
        
        with pytest.raises(Exception) as exc_info:
            create_django_logging_config(Mock())
        
        assert str(exc_info.value) == "Config error"
    
    def test_add_django_handlers_with_path_issues(self):
        """Test handler configuration with path issues."""
        config = Mock()
        config.production_mode = False
        config.debug_mode = True
        # Path that might cause issues
        config.log_directory = Path("/nonexistent/path")
        config.max_file_size = 10485760
        
        logging_config = {'handlers': {}}
        
        # Should not raise exception
        _add_django_handlers(logging_config, config)
        
        # Handlers should still be created with path
        assert 'debug_file' in logging_config['handlers']
        assert 'django_file' in logging_config['handlers']
    
    def test_detect_django_context_case_sensitivity(self):
        """Test context detection is case-insensitive."""
        frame_info = Mock()
        frame_info.filename = '/app/myapp/VIEWS.PY'
        frame_info.function = 'MY_VIEW'
        
        result = detect_django_context(frame_info)
        assert result == 'django.view'
    
    @patch('storm_logger.integrations.django.create_django_logging_config')
    @patch('logging.config.dictConfig')
    def test_configure_django_logging_dictconfig_error(self, mock_dictconfig, mock_create_config):
        """Test configure_django_logging handles dictConfig errors."""
        mock_create_config.return_value = {'version': 1}
        mock_dictconfig.side_effect = ValueError("Invalid config")
        
        config = Mock()
        config.framework = Framework.DJANGO
        config.create_log_directories = Mock()
        
        with pytest.raises(ValueError) as exc_info:
            configure_django_logging(config)
        
        assert str(exc_info.value) == "Invalid config"


class TestDjangoIntegrationBestPractices:
    """Test that Django integration follows best practices."""
    
    def test_no_hardcoded_paths(self):
        """Test that no hardcoded paths are used."""
        # This is more of a code review test
        # Check that paths use configuration
        config = Mock()
        config.log_directory = Path("/custom/logs")
        config.max_file_size = 1024
        
        logging_config = {'handlers': {}}
        _add_django_handlers(logging_config, config)
        
        # Check that custom path is used
        if 'django_file' in logging_config['handlers']:
            assert '/custom/logs' in logging_config['handlers']['django_file']['filename']
    
    def test_handler_configuration_completeness(self):
        """Test that handlers have all required configuration."""
        config = Mock()
        config.production_mode = True
        config.debug_mode = False
        config.log_directory = Path("/tmp/logs")
        config.max_file_size = 10485760
        
        logging_config = {'handlers': {}}
        _add_django_handlers(logging_config, config)
        
        # Check required fields for file handlers
        for handler_name, handler_config in logging_config['handlers'].items():
            if handler_config.get('class', '').endswith('FileHandler'):
                assert 'filename' in handler_config
                assert 'formatter' in handler_config
                assert 'encoding' in handler_config
    
    def test_logger_configuration_consistency(self):
        """Test that logger configurations are consistent."""
        config = Mock()
        config.production_mode = False
        config.debug_mode = True
        config.log_level = LogLevel.INFO
        
        logging_config = {'loggers': {}}
        _add_django_loggers(logging_config, config)
        
        # All loggers should have propagate=False
        for logger_config in logging_config['loggers'].values():
            assert logger_config['propagate'] is False
            assert 'handlers' in logger_config
            assert 'level' in logger_config


class TestDjangoIntegrationComplete:
    """Test complete Django integration scenarios."""
    
    @pytest.fixture
    def base_config(self):
        """Create base Storm Logger config."""
        config = StormLoggerConfig(
            log_level=LogLevel.INFO,
            log_directory=Path("/tmp/logs"),
            debug_mode=False,
            production_mode=True,
            max_file_size=10485760,
        )
        return config
    
    @pytest.fixture
    def django_config(self):
        """Create Django-specific config."""
        # Import here to avoid circular imports
        from storm_logger.integrations.django_config import DjangoStormLoggerConfig
        return DjangoStormLoggerConfig(
            log_level=LogLevel.INFO,
            log_directory=Path("/tmp/logs"),
            debug_mode=False,
            production_mode=True,
            app_log_levels={
                'myapp': LogLevel.DEBUG,
                'django.request': LogLevel.ERROR,
            },
            excluded_apps=['django.contrib.staticfiles'],
        )
    
    def test_celery_logger_configuration(self, django_config):
        """Test Celery logger is configured properly."""
        logging_config = {'loggers': {}}
        
        _configure_app_specific_loggers(logging_config, django_config)
        
        assert 'celery' in logging_config['loggers']
        celery_logger = logging_config['loggers']['celery']
        assert celery_logger['level'] == 'INFO'
        assert 'console' in celery_logger['handlers']
        assert 'app_file' in celery_logger['handlers']
        assert 'error_file' in celery_logger['handlers']
    
    def test_debug_mode_db_logger(self, django_config):
        """Test database logger configuration in debug mode."""
        django_config.debug_mode = True
        logging_config = {'loggers': {}}
        
        _add_django_loggers(logging_config, django_config)
        
        db_logger = logging_config['loggers']['django.db.backends']
        assert db_logger['level'] == 'DEBUG'
        assert 'debug_file' in db_logger['handlers']
    
    def test_debug_mode_app_loggers(self, base_config):
        """Test app-specific loggers get debug_file handler in debug mode."""
        base_config.debug_mode = True
        logging_config = {'loggers': {}}
        
        _configure_app_specific_loggers(logging_config, base_config)
        
        # Check that storm app loggers have debug_file handler
        for app in ['storm.base', 'storm.billing']:
            assert app in logging_config['loggers']
            assert 'debug_file' in logging_config['loggers'][app]['handlers']
    
    def test_empty_excluded_apps_handling(self):
        """Test handling when excluded_apps is None or empty."""
        # Import DjangoStormLoggerConfig
        from storm_logger.integrations.django_config import DjangoStormLoggerConfig
        
        config = DjangoStormLoggerConfig(excluded_apps=[])
        logging_config = {'loggers': {}}
        
        _configure_app_specific_loggers(logging_config, config)
        
        # Should not fail and should configure storm app loggers
        assert 'storm.base' in logging_config['loggers']
    
    def test_add_production_enhancements_edge_case(self, base_config):
        """Test production enhancements with loggers without handlers."""
        base_config.production_mode = True
        logging_config = {
            'loggers': {
                'app1': {},  # No handlers key
                'app2': {'handlers': []},  # Empty handlers
            }
        }
        
        # Should not fail
        _add_production_enhancements(logging_config, base_config)
        
        # Should add handlers key and syslog
        assert 'handlers' in logging_config['loggers']['app1']
        assert 'syslog' in logging_config['loggers']['app1']['handlers']
        assert 'syslog' in logging_config['loggers']['app2']['handlers']
    
    @patch('storm_logger.config.get_config')
    @patch('storm_logger.config.set_config')
    @patch('storm_logger.integrations.django.create_django_logging_config')
    @patch('logging.config.dictConfig')
    def test_configure_django_logging_full_flow(self, mock_dictconfig, mock_create_config,
                                                mock_set_config, mock_get_config):
        """Test complete flow of configure_django_logging."""
        # Create a proper mock config
        mock_config = Mock(spec=StormLoggerConfig)
        mock_config.framework = Framework.STANDALONE  # Will be changed to DJANGO
        mock_config.create_log_directories = Mock()
        
        mock_get_config.return_value = mock_config
        mock_create_config.return_value = {
            'version': 1,
            'handlers': {'console': {}},
            'loggers': {'django': {}}
        }
        
        # Call without config to test get_config path
        configure_django_logging()
        
        # Verify framework was set to Django
        assert mock_config.framework == Framework.DJANGO
        mock_get_config.assert_called_once()
        mock_set_config.assert_called_once_with(mock_config)
    
    def test_integrate_with_django_settings_existing_storm_logger(self):
        """Test integrate_with_django_settings when storm_logger already in INSTALLED_APPS."""
        settings_module = Mock()
        settings_module.INSTALLED_APPS = ['django.contrib.admin', 'storm_logger']
        
        with patch('storm_logger.config.get_config') as mock_get_config, \
             patch('storm_logger.integrations.django.get_django_logging_config') as mock_get_logging:
            
            mock_config = Mock()
            mock_config.framework = Framework.DJANGO
            mock_get_config.return_value = mock_config
            mock_get_logging.return_value = {'version': 1}
            
            integrate_with_django_settings(settings_module)
            
            # Should not add storm_logger again
            assert settings_module.INSTALLED_APPS.count('storm_logger') == 1


class TestDjangoStormLoggerAdvanced:
    """Advanced tests for DjangoStormLogger."""
    
    def test_django_storm_logger_inherits_correctly(self):
        """Test DjangoStormLogger inherits from StormLogger."""
        from storm_logger.core.logger import StormLogger
        assert issubclass(DjangoStormLogger, StormLogger)
    
    def test_super_init_called_correctly(self):
        """Test that DjangoStormLogger initialization works correctly."""
        with patch('storm_logger.integrations.django.create_django_logging_config'):
            config = Mock(spec=StormLoggerConfig)
            config.framework = Framework.STANDALONE  # Will be changed to DJANGO
            
            # Create logger with all parameters
            logger = DjangoStormLogger("test_logger", config, auto_detect_context=False)
            
            # Verify attributes are set correctly
            assert logger.name == "test_logger"
            assert logger.config == config
            assert logger.config.framework == Framework.DJANGO  # Should be forced to Django
            assert hasattr(logger, 'auto_detect_context')
            assert logger.auto_detect_context is False
    
    def test_configure_handlers_integration(self):
        """Test _configure_handlers method integration."""
        config = Mock(spec=StormLoggerConfig)
        config.framework = Framework.DJANGO
        
        with patch('storm_logger.integrations.django.create_django_logging_config') as mock_create, \
             patch('logging.config.dictConfig') as mock_dictconfig:
            
            mock_create.return_value = {
                'version': 1,
                'disable_existing_loggers': False,
                'handlers': {'django_handler': {}}
            }
            
            # Create logger which will call _configure_handlers
            logger = DjangoStormLogger("test", config)
            
            # Manually call _configure_handlers to test it
            logger._configure_handlers()
            
            # Should have been called once (manually)
            assert mock_dictconfig.call_count == 1
            call_args = mock_dictconfig.call_args[0][0]
            assert call_args['version'] == 1
            assert 'django_handler' in call_args['handlers']


# Performance and integration markers
pytestmark = [
    pytest.mark.unit,
    pytest.mark.django,
]