"""
Unit tests for Standalone integration module.

This test module provides comprehensive coverage for storm_logger.integrations.standalone,
including StandaloneStormLogger, configuration functions, and standalone-specific features.
"""

import logging
import logging.config
import os
import time
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.standalone import (
    StandaloneStormLogger,
    STANDALONE_CONTEXT_PATTERNS,
    create_standalone_logging_config,
    _add_production_handlers,
    _add_syslog_handler,
    _add_syslog_to_loggers,
    _add_app_loggers,
    _get_app_logger_names,
    _configure_handler_list,
    configure_standalone_logging,
    get_standalone_logger,
    detect_standalone_context,
    setup_script_logging,
    setup_cli_logging,
    ScriptProgressLogger,
)


class TestStandaloneStormLogger:
    """Test StandaloneStormLogger class."""
    
    @pytest.fixture
    def mock_config(self):
        """Create mock configuration."""
        config = Mock(spec=StormLoggerConfig)
        config.framework = Framework.STANDALONE
        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 StandaloneStormLogger instance."""
        with patch('storm_logger.integrations.standalone.create_standalone_logging_config'):
            return StandaloneStormLogger("test", mock_config)
    
    def test_init_default_config(self):
        """Test initialization with default config."""
        with patch('storm_logger.integrations.standalone.create_standalone_logging_config'):
            logger = StandaloneStormLogger("test")
            assert logger.name == "test"
            assert logger.config.framework == Framework.STANDALONE
    
    def test_init_with_config(self, mock_config):
        """Test initialization with custom config."""
        with patch('storm_logger.integrations.standalone.create_standalone_logging_config'):
            logger = StandaloneStormLogger("test", mock_config)
            assert logger.name == "test"
            assert logger.config == mock_config
            assert logger.config.framework == Framework.STANDALONE
    
    def test_init_forces_standalone_framework(self, mock_config):
        """Test that init forces framework to Standalone."""
        mock_config.framework = Framework.DJANGO
        with patch('storm_logger.integrations.standalone.create_standalone_logging_config'):
            logger = StandaloneStormLogger("test", mock_config)
            assert logger.config.framework == Framework.STANDALONE
    
    def test_auto_detect_context_param(self):
        """Test auto_detect_context parameter."""
        with patch('storm_logger.integrations.standalone.create_standalone_logging_config'):
            # Default is True
            logger1 = StandaloneStormLogger("test1")
            assert hasattr(logger1, 'auto_detect_context')
            assert logger1.auto_detect_context is True
            
            # Explicit False
            logger2 = StandaloneStormLogger("test2", auto_detect_context=False)
            assert hasattr(logger2, 'auto_detect_context')
            assert logger2.auto_detect_context is False
    
    def test_configure_handlers(self):
        """Test _configure_handlers method."""
        config = Mock(spec=StormLoggerConfig)
        config.framework = Framework.STANDALONE
        
        with patch('storm_logger.integrations.standalone.create_standalone_logging_config') as mock_create, \
             patch('logging.config.dictConfig') as mock_dictconfig:
            
            mock_create.return_value = {
                'version': 1,
                'handlers': {'console': {}}
            }
            
            logger = StandaloneStormLogger("test", config)
            logger._configure_handlers()
            
            mock_dictconfig.assert_called()
            call_args = mock_dictconfig.call_args[0][0]
            assert call_args['version'] == 1


class TestStandaloneLoggingConfig:
    """Test Standalone 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
    
    @patch('storm_logger.integrations.standalone.create_base_logging_config')
    def test_create_standalone_logging_config_basic(self, mock_base_config, base_config):
        """Test basic standalone logging config creation."""
        mock_base_config.return_value = {
            'version': 1,
            'filters': {},
            'handlers': {},
            'loggers': {},
        }
        
        result = create_standalone_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.standalone.create_base_logging_config')
    def test_create_standalone_logging_config_production(self, mock_base_config, base_config):
        """Test production mode configuration."""
        base_config.production_mode = True
        mock_base_config.return_value = {
            'version': 1,
            'handlers': {},
            'loggers': {},
        }
        
        with patch('os.name', 'posix'):
            result = create_standalone_logging_config(base_config)
            
            # Should have syslog handler on POSIX
            assert 'syslog' in result['handlers']
            assert result['handlers']['syslog']['class'] == 'logging.handlers.SysLogHandler'
    
    @patch('storm_logger.integrations.standalone.create_base_logging_config')
    def test_create_standalone_logging_config_non_posix(self, mock_base_config, base_config):
        """Test production mode on non-POSIX systems."""
        base_config.production_mode = True
        mock_base_config.return_value = {
            'version': 1,
            'handlers': {},
            'loggers': {},
        }
        
        with patch('os.name', 'nt'):  # Windows
            result = create_standalone_logging_config(base_config)
            
            # Should not have syslog handler on Windows
            assert 'syslog' not in result['handlers']
    
    def test_add_production_handlers_not_production(self, base_config):
        """Test production handlers when not in production mode."""
        base_config.production_mode = False
        logging_config = {'handlers': {}, 'loggers': {}}
        
        _add_production_handlers(logging_config, base_config)
        
        # Should not add any handlers
        assert 'syslog' not in logging_config['handlers']
    
    def test_add_syslog_handler(self):
        """Test adding syslog handler."""
        logging_config = {'handlers': {}}
        
        _add_syslog_handler(logging_config)
        
        assert 'syslog' in logging_config['handlers']
        syslog = logging_config['handlers']['syslog']
        assert syslog['level'] == 'INFO'
        assert syslog['class'] == 'logging.handlers.SysLogHandler'
        assert syslog['formatter'] == 'standard'
        assert syslog['address'] == '/dev/log'
    
    def test_add_syslog_to_loggers(self):
        """Test adding syslog to all loggers."""
        logging_config = {
            'loggers': {
                'app': {'handlers': ['console']},
                'service': {'handlers': ['file']},
                'worker': {},  # No handlers key
            }
        }
        
        _add_syslog_to_loggers(logging_config)
        
        # All loggers should have syslog
        assert 'syslog' in logging_config['loggers']['app']['handlers']
        assert 'syslog' in logging_config['loggers']['service']['handlers']
        assert 'syslog' in logging_config['loggers']['worker']['handlers']
    
    def test_add_app_loggers(self, base_config):
        """Test adding application-specific loggers."""
        logging_config = {'loggers': {}}
        
        _add_app_loggers(logging_config, base_config)
        
        # Check standard app loggers
        for logger_name in ['app', 'main', 'service', 'worker']:
            assert logger_name in logging_config['loggers']
            logger = logging_config['loggers'][logger_name]
            assert logger['level'] == base_config.log_level.value
            assert not logger['propagate']
            assert 'console' in logger['handlers']
            assert 'app_file' in logger['handlers']
    
    def test_add_app_loggers_debug_mode(self, base_config):
        """Test app loggers in debug mode."""
        base_config.debug_mode = True
        logging_config = {'loggers': {}}
        
        _add_app_loggers(logging_config, base_config)
        
        # Should have debug_file handler
        for logger_name in ['app', 'main']:
            assert 'debug_file' in logging_config['loggers'][logger_name]['handlers']
    
    def test_get_app_logger_names(self):
        """Test getting app logger names."""
        names = _get_app_logger_names()
        
        assert isinstance(names, list)
        assert 'app' in names
        assert 'service' in names
        assert 'worker' in names
        assert 'cli' in names
        assert 'script' in names
        assert len(names) > 10  # Should have many logger names
    
    def test_configure_handler_list_basic(self, base_config):
        """Test handler list configuration."""
        base_config.debug_mode = False
        
        handlers = _configure_handler_list(base_config)
        
        assert handlers == ['console', 'app_file', 'error_file']
    
    def test_configure_handler_list_debug(self, base_config):
        """Test handler list in debug mode."""
        base_config.debug_mode = True
        
        handlers = _configure_handler_list(base_config)
        
        assert handlers == ['console', 'app_file', 'error_file', 'debug_file']


class TestStandaloneIntegrationFunctions:
    """Test Standalone integration utility functions."""
    
    @pytest.fixture
    def mock_config(self):
        """Create mock configuration."""
        config = Mock(spec=StormLoggerConfig)
        config.framework = Framework.STANDALONE
        config.create_log_directories = Mock()
        return config
    
    @patch('storm_logger.config.get_config')
    @patch('storm_logger.config.set_config')
    @patch('storm_logger.integrations.standalone.create_standalone_logging_config')
    @patch('logging.config.dictConfig')
    def test_configure_standalone_logging_no_config(self, mock_dictconfig, mock_create_config,
                                                    mock_set_config, mock_get_config, mock_config):
        """Test configure_standalone_logging without config."""
        mock_get_config.return_value = mock_config
        mock_create_config.return_value = {'version': 1}
        
        configure_standalone_logging()
        
        mock_get_config.assert_called_once()
        assert mock_config.framework == Framework.STANDALONE
        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.set_config')
    @patch('storm_logger.integrations.standalone.create_standalone_logging_config')
    @patch('logging.config.dictConfig')
    def test_configure_standalone_logging_with_config(self, mock_dictconfig, mock_create_config,
                                                      mock_set_config, mock_config):
        """Test configure_standalone_logging with custom config."""
        mock_create_config.return_value = {'version': 1}
        
        configure_standalone_logging(mock_config)
        
        assert mock_config.framework == Framework.STANDALONE
        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})
    
    def test_get_standalone_logger(self):
        """Test get_standalone_logger function."""
        with patch('storm_logger.integrations.standalone.create_standalone_logging_config'):
            logger = get_standalone_logger("test_logger")
            
            assert isinstance(logger, StandaloneStormLogger)
            assert logger.name == "test_logger"
    
    def test_get_standalone_logger_with_config(self, mock_config):
        """Test get_standalone_logger with custom config."""
        with patch('storm_logger.integrations.standalone.create_standalone_logging_config'):
            logger = get_standalone_logger("test_logger", mock_config)
            
            assert isinstance(logger, StandaloneStormLogger)
            assert logger.name == "test_logger"
            assert logger.config == mock_config


class TestStandaloneContextDetection:
    """Test standalone context detection."""
    
    def test_detect_standalone_context_main(self):
        """Test detecting main context."""
        frame_info = Mock()
        frame_info.filename = '/app/main.py'
        frame_info.function = 'main'
        
        result = detect_standalone_context(frame_info)
        assert result == 'app.main'
    
    def test_detect_standalone_context_service(self):
        """Test detecting service context."""
        frame_info = Mock()
        frame_info.filename = '/app/myservice.py'
        frame_info.function = 'ServiceHandler'
        
        result = detect_standalone_context(frame_info)
        assert result == 'app.service'
    
    def test_detect_standalone_context_cli(self):
        """Test detecting CLI context."""
        frame_info = Mock()
        frame_info.filename = '/app/cli.py'
        frame_info.function = 'handle_command'
        
        result = detect_standalone_context(frame_info)
        assert result == 'app.cli'
    
    def test_detect_standalone_context_by_function(self):
        """Test detecting context by function name."""
        frame_info = Mock()
        frame_info.filename = '/app/utils.py'
        frame_info.function = 'WorkerProcess'
        
        result = detect_standalone_context(frame_info)
        assert result == 'app.worker'
    
    def test_detect_standalone_context_initialization(self):
        """Test detecting initialization context."""
        frame_info = Mock()
        frame_info.filename = '/app/app.py'
        frame_info.function = '__init__'
        
        result = detect_standalone_context(frame_info)
        assert result == 'app.initialization'
    
    def test_detect_standalone_context_setup(self):
        """Test detecting setup context."""
        frame_info = Mock()
        frame_info.filename = '/app/app.py'
        frame_info.function = 'setup_database'
        
        result = detect_standalone_context(frame_info)
        assert result == 'app.setup'
    
    def test_detect_standalone_context_cleanup(self):
        """Test detecting cleanup context."""
        frame_info = Mock()
        frame_info.filename = '/app/app.py'
        frame_info.function = 'cleanup_resources'
        
        result = detect_standalone_context(frame_info)
        assert result == 'app.cleanup'
    
    def test_detect_standalone_context_default(self):
        """Test default standalone context."""
        frame_info = Mock()
        frame_info.filename = '/app/some_random_file.py'
        frame_info.function = 'some_function'
        
        result = detect_standalone_context(frame_info)
        assert result == 'app.general'
    
    def test_standalone_context_patterns_completeness(self):
        """Test that all expected standalone patterns are defined."""
        expected_contexts = [
            'main', 'service', 'worker', 'scheduler', 'api', 'cli',
            'config', 'database', 'cache', 'queue', 'test', 'util',
            'exception', 'validation', 'security', 'monitoring',
            'script', 'batch', 'etl', 'pipeline'
        ]
        
        for context in expected_contexts:
            assert context in STANDALONE_CONTEXT_PATTERNS
            assert isinstance(STANDALONE_CONTEXT_PATTERNS[context], list)
            assert len(STANDALONE_CONTEXT_PATTERNS[context]) > 0


class TestStandaloneUtilityFunctions:
    """Test standalone utility functions."""
    
    @patch('storm_logger.integrations.standalone.configure_standalone_logging')
    @patch('storm_logger.integrations.standalone.get_standalone_logger')
    def test_setup_script_logging_default(self, mock_get_logger, mock_configure):
        """Test setup_script_logging with defaults."""
        mock_logger = Mock()
        mock_get_logger.return_value = mock_logger
        
        result = setup_script_logging("test_script.py")
        
        assert result == mock_logger
        mock_configure.assert_called_once()
        mock_get_logger.assert_called_once_with("test_script.py")
        
        # Check config passed to configure
        config_arg = mock_configure.call_args[0][0]
        assert config_arg.log_level == LogLevel.INFO
        assert config_arg.enable_file_logging is True
        assert config_arg.enable_console is True
    
    @patch('storm_logger.integrations.standalone.configure_standalone_logging')
    @patch('storm_logger.integrations.standalone.get_standalone_logger')
    def test_setup_script_logging_custom(self, mock_get_logger, mock_configure):
        """Test setup_script_logging with custom settings."""
        mock_logger = Mock()
        mock_get_logger.return_value = mock_logger
        
        result = setup_script_logging(
            "test_script.py",
            log_level="DEBUG",
            log_to_file=False
        )
        
        config_arg = mock_configure.call_args[0][0]
        assert config_arg.log_level == LogLevel.DEBUG
        assert config_arg.enable_file_logging is False
    
    @patch('storm_logger.integrations.standalone.configure_standalone_logging')
    @patch('storm_logger.integrations.standalone.get_standalone_logger')
    def test_setup_cli_logging_quiet(self, mock_get_logger, mock_configure):
        """Test setup_cli_logging in quiet mode."""
        mock_logger = Mock()
        mock_get_logger.return_value = mock_logger
        
        result = setup_cli_logging("myapp", quiet=True)
        
        config_arg = mock_configure.call_args[0][0]
        assert config_arg.log_level == LogLevel.ERROR
        assert config_arg.console_colors is False
    
    @patch('storm_logger.integrations.standalone.configure_standalone_logging')
    @patch('storm_logger.integrations.standalone.get_standalone_logger')
    def test_setup_cli_logging_verbose(self, mock_get_logger, mock_configure):
        """Test setup_cli_logging with verbosity."""
        mock_logger = Mock()
        mock_get_logger.return_value = mock_logger
        
        # Test verbosity level 1
        result = setup_cli_logging("myapp", verbosity=1)
        config_arg = mock_configure.call_args[0][0]
        assert config_arg.log_level == LogLevel.INFO
        assert config_arg.enable_file_logging is True
        
        # Test verbosity level 2+
        result = setup_cli_logging("myapp", verbosity=2)
        config_arg = mock_configure.call_args[0][0]
        assert config_arg.log_level == LogLevel.DEBUG
    
    @patch('storm_logger.integrations.standalone.configure_standalone_logging')
    @patch('storm_logger.integrations.standalone.get_standalone_logger')
    def test_setup_cli_logging_normal(self, mock_get_logger, mock_configure):
        """Test setup_cli_logging with normal verbosity."""
        mock_logger = Mock()
        mock_get_logger.return_value = mock_logger
        
        result = setup_cli_logging("myapp", verbosity=0)
        
        config_arg = mock_configure.call_args[0][0]
        assert config_arg.log_level == LogLevel.WARNING
        assert config_arg.enable_file_logging is False


class TestScriptProgressLogger:
    """Test ScriptProgressLogger class."""
    
    @patch('storm_logger.integrations.standalone.get_standalone_logger')
    def test_init(self, mock_get_logger):
        """Test ScriptProgressLogger initialization."""
        mock_logger = Mock()
        mock_get_logger.return_value = mock_logger
        
        progress = ScriptProgressLogger("test_logger")
        
        assert progress.logger == mock_logger
        assert progress.start_time is None
        assert progress.operation is None
        mock_get_logger.assert_called_once_with("test_logger")
    
    @patch('storm_logger.integrations.standalone.get_standalone_logger')
    @patch('time.time')
    def test_start(self, mock_time, mock_get_logger):
        """Test starting an operation."""
        mock_logger = Mock()
        mock_get_logger.return_value = mock_logger
        mock_time.return_value = 1234567890
        
        progress = ScriptProgressLogger("test")
        progress.start("Data import")
        
        assert progress.start_time == 1234567890
        assert progress.operation == "Data import"
        mock_logger.info.assert_called_once_with("Started: Data import")
    
    @patch('storm_logger.integrations.standalone.get_standalone_logger')
    def test_update(self, mock_get_logger):
        """Test progress update."""
        mock_logger = Mock()
        mock_get_logger.return_value = mock_logger
        
        progress = ScriptProgressLogger("test")
        progress.update(50, 100, "Processing batch 2")
        
        mock_logger.info.assert_called_once_with(
            "Progress: 50.0% (50/100) - Processing batch 2"
        )
    
    @patch('storm_logger.integrations.standalone.get_standalone_logger')
    def test_update_zero_total(self, mock_get_logger):
        """Test progress update with zero total."""
        mock_logger = Mock()
        mock_get_logger.return_value = mock_logger
        
        progress = ScriptProgressLogger("test")
        progress.update(0, 0, "No items")
        
        # Should not log when total is 0
        mock_logger.info.assert_not_called()
    
    @patch('storm_logger.integrations.standalone.get_standalone_logger')
    @patch('time.time')
    def test_complete_with_timing(self, mock_time, mock_get_logger):
        """Test completing an operation with timing."""
        mock_logger = Mock()
        mock_get_logger.return_value = mock_logger
        mock_time.side_effect = [1234567890, 1234567900]  # 10 second duration
        
        progress = ScriptProgressLogger("test")
        progress.start("Import")
        progress.complete("Imported 1000 records")
        
        # Check complete message includes duration
        complete_call = mock_logger.info.call_args_list[-1]
        assert "Completed: Import - Imported 1000 records (Duration: 10.00s)" in str(complete_call)
    
    @patch('storm_logger.integrations.standalone.get_standalone_logger')
    def test_complete_without_start(self, mock_get_logger):
        """Test completing without starting."""
        mock_logger = Mock()
        mock_get_logger.return_value = mock_logger
        
        progress = ScriptProgressLogger("test")
        progress.complete("Done")
        
        mock_logger.info.assert_called_once_with("Done")


class TestStandaloneIntegrationEdgeCases:
    """Test edge cases and error handling."""
    
    @patch('storm_logger.integrations.standalone.create_base_logging_config')
    def test_create_standalone_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_standalone_logging_config(Mock())
        
        assert str(exc_info.value) == "Config error"
    
    def test_add_syslog_to_loggers_empty_handlers(self):
        """Test adding syslog to logger with no handlers."""
        logging_config = {
            'loggers': {
                'app': {},  # No handlers key
            }
        }
        
        _add_syslog_to_loggers(logging_config)
        
        assert 'handlers' in logging_config['loggers']['app']
        assert 'syslog' in logging_config['loggers']['app']['handlers']
    
    def test_detect_standalone_context_case_sensitivity(self):
        """Test context detection is case-insensitive."""
        frame_info = Mock()
        frame_info.filename = '/app/MAIN.PY'
        frame_info.function = 'MAIN'
        
        result = detect_standalone_context(frame_info)
        assert result == 'app.main'
    
    @patch('storm_logger.integrations.standalone.create_standalone_logging_config')
    @patch('logging.config.dictConfig')
    def test_configure_standalone_logging_dictconfig_error(self, mock_dictconfig, mock_create_config):
        """Test configure_standalone_logging handles dictConfig errors."""
        mock_create_config.return_value = {'version': 1}
        mock_dictconfig.side_effect = ValueError("Invalid config")
        
        config = Mock()
        config.framework = Framework.STANDALONE
        config.create_log_directories = Mock()
        
        with pytest.raises(ValueError) as exc_info:
            configure_standalone_logging(config)
        
        assert str(exc_info.value) == "Invalid config"


class TestStandaloneBestPractices:
    """Test that standalone integration follows best practices."""
    
    def test_no_hardcoded_paths(self):
        """Test that no hardcoded paths are used."""
        config = Mock()
        config.log_directory = Path("/custom/logs")
        config.production_mode = False
        config.debug_mode = False
        config.log_level = LogLevel.INFO
        
        with patch('storm_logger.integrations.standalone.create_base_logging_config') as mock_base:
            mock_base.return_value = {'loggers': {}}
            
            create_standalone_logging_config(config)
            
            # Should use config's log directory, not hardcoded
            mock_base.assert_called_once_with(config)
    
    def test_handler_configuration_completeness(self):
        """Test that handlers have all required configuration."""
        logging_config = {'handlers': {}}
        
        _add_syslog_handler(logging_config)
        
        syslog = logging_config['handlers']['syslog']
        assert 'level' in syslog
        assert 'class' in syslog
        assert 'formatter' in syslog
        assert 'address' in syslog
    
    def test_logger_configuration_consistency(self):
        """Test that logger configurations are consistent."""
        config = Mock()
        config.debug_mode = False
        config.log_level = LogLevel.INFO
        
        logging_config = {'loggers': {}}
        _add_app_loggers(logging_config, config)
        
        # All loggers should have consistent settings
        for logger_config in logging_config['loggers'].values():
            assert logger_config['propagate'] is False
            assert 'handlers' in logger_config
            assert 'level' in logger_config
            assert logger_config['level'] == LogLevel.INFO.value


class TestStandaloneIntegrationComplete:
    """Test complete standalone integration scenarios."""
    
    def test_standalone_logger_inheritance(self):
        """Test StandaloneStormLogger inherits correctly."""
        from storm_logger.core.logger import StormLogger
        assert issubclass(StandaloneStormLogger, StormLogger)
    
    def test_full_production_configuration(self):
        """Test complete production configuration."""
        config = StormLoggerConfig(
            log_level=LogLevel.WARNING,
            production_mode=True,
            debug_mode=False,
        )
        
        with patch('storm_logger.integrations.standalone.create_base_logging_config') as mock_base, \
             patch('os.name', 'posix'):
            
            mock_base.return_value = {
                'version': 1,
                'handlers': {},
                'loggers': {},
            }
            
            result = create_standalone_logging_config(config)
            
            # Should have syslog handler
            assert 'syslog' in result['handlers']
            
            # Should have app loggers
            assert 'app' in result['loggers']
            assert 'service' in result['loggers']
            
            # App loggers should have syslog
            for logger in result['loggers'].values():
                if 'handlers' in logger:
                    assert 'syslog' in logger['handlers']
    
    def test_script_progress_logger_workflow(self):
        """Test complete ScriptProgressLogger workflow."""
        with patch('storm_logger.integrations.standalone.get_standalone_logger') as mock_get_logger:
            mock_logger = Mock()
            mock_get_logger.return_value = mock_logger
            
            # Mock time.time for the start and complete methods
            with patch('time.time') as mock_time:
                mock_time.side_effect = [100, 120]  # Start time, complete time
                
                # Complete workflow
                progress = ScriptProgressLogger("etl_job")
                progress.start("ETL Process")
                
                # Process items
                for i in range(3):
                    progress.update(i + 1, 3, f"Processing item {i + 1}")
                
                progress.complete("Processed 3 items successfully")
                
                # Verify all log calls
                assert mock_logger.info.call_count == 5  # start + 3 updates + complete
                
                # Verify timing in complete message
                complete_call = str(mock_logger.info.call_args_list[-1])
                # Duration should be 120 - 100 = 20 seconds
                assert "Duration: 20.00s" in complete_call


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