"""
Full integration tests for Storm Logger
"""

import logging
import tempfile
from pathlib import Path

import pytest

from storm_logger import (
    Framework,
    LogLevel,
    StormLogger,
    StormLoggerConfig,
    get_storm_logger,
    setup_storm_logging,
)
from storm_logger.integrations.standalone import configure_standalone_logging


class TestStormLoggerIntegration:
    """Test full Storm Logger integration."""

    def test_end_to_end_logging(self):
        """Test complete end-to-end logging functionality."""
        with tempfile.TemporaryDirectory() as temp_dir:
            # Create configuration
            config = StormLoggerConfig(
                log_directory=Path(temp_dir),
                log_level=LogLevel.DEBUG,
                enable_console=True,
                enable_business_metrics=True,
                debug_mode=True
            )
            
            # Setup logging
            setup_storm_logging(config)
            
            # Get logger
            logger = get_storm_logger("integration_test", config)
            
            # Test all logging methods
            logger.debug("Debug message")
            logger.info("Info message")
            logger.warning("Warning message")
            logger.error("Error message")
            logger.critical("Critical message")
            
            # Test business features
            logger.business_metric("response_time", 0.5, threshold=1.0)
            logger.test_result("test_integration", "passed", 0.1)
            logger.performance_metric("api_call", 0.3, threshold=0.5)
            logger.security_event("login_attempt", "User login", "info")
            logger.user_action("user123", "login", "Successful login")
            
            # Check log files were created
            assert (Path(temp_dir) / "app" / "storm_app.log").exists()
            assert (Path(temp_dir) / "errors" / "errors.log").exists()
            assert (Path(temp_dir) / "app" / "debug.log").exists()
            
            # Check metrics were collected
            metrics = logger.get_business_metrics()
            assert "response_time" in metrics

    def test_standalone_integration(self):
        """Test standalone framework integration."""
        with tempfile.TemporaryDirectory() as temp_dir:
            config = StormLoggerConfig(
                log_directory=Path(temp_dir),
                framework=Framework.STANDALONE
            )
            
            configure_standalone_logging(config)
            
            logger = get_storm_logger("standalone_test", config)
            
            logger.info("Standalone logging test")
            
            # Check log file was created
            assert (Path(temp_dir) / "app" / "storm_app.log").exists()

    def test_multiple_loggers(self):
        """Test using multiple loggers simultaneously."""
        with tempfile.TemporaryDirectory() as temp_dir:
            config = StormLoggerConfig(log_directory=Path(temp_dir))
            
            # Create multiple loggers
            logger1 = get_storm_logger("logger1", config)
            logger2 = get_storm_logger("logger2", config)
            logger3 = get_storm_logger("logger3", config)
            
            # Log from different loggers
            logger1.info("Message from logger1")
            logger2.warning("Message from logger2")
            logger3.error("Message from logger3")
            
            # Each logger should have its own metrics
            logger1.business_metric("metric1", 100)
            logger2.business_metric("metric2", 200)
            
            assert len(logger1.get_business_metrics()) == 1
            assert len(logger2.get_business_metrics()) == 1
            assert len(logger3.get_business_metrics()) == 0

    def test_configuration_changes(self):
        """Test changing configuration during runtime."""
        with tempfile.TemporaryDirectory() as temp_dir:
            # Start with one configuration
            config1 = StormLoggerConfig(
                log_directory=Path(temp_dir),
                log_level=LogLevel.INFO
            )
            
            logger = get_storm_logger("config_test", config1)
            logger.info("Info message")
            
            # Change configuration
            config2 = StormLoggerConfig(
                log_directory=Path(temp_dir),
                log_level=LogLevel.ERROR
            )
            
            logger2 = get_storm_logger("config_test2", config2)
            logger2.error("Error message")
            
            # Both should work
            assert (Path(temp_dir) / "app" / "storm_app.log").exists()

    def test_professional_logger_compatibility(self):
        """Test compatibility with professional logger."""
        with tempfile.TemporaryDirectory() as temp_dir:
            from storm_logger import get_professional_logger
            
            config = StormLoggerConfig(log_directory=Path(temp_dir))
            
            # Should work with professional logger
            prof_logger = get_professional_logger("professional_test")
            prof_logger.info("Professional logger test")

    def test_context_detection_integration(self):
        """Test context detection integration."""
        with tempfile.TemporaryDirectory() as temp_dir:
            config = StormLoggerConfig(
                log_directory=Path(temp_dir),
                enable_context_detection=True
            )
            
            logger = get_storm_logger("context_test", config)
            
            # Set manual context
            logger.set_context({"user": "test_user", "session": "abc123"})
            
            logger.info("Message with context")
            
            # Should not raise exceptions
            assert (Path(temp_dir) / "app" / "storm_app.log").exists()

    def test_business_metrics_integration(self):
        """Test business metrics integration."""
        with tempfile.TemporaryDirectory() as temp_dir:
            config = StormLoggerConfig(
                log_directory=Path(temp_dir),
                enable_business_metrics=True
            )
            
            logger = get_storm_logger("metrics_test", config)
            
            # Add various metrics
            logger.business_metric("users_active", 1000)
            logger.business_metric("response_time", 0.5, threshold=1.0)
            logger.business_metric("error_rate", 0.01, threshold=0.05)
            
            # Performance metrics
            logger.performance_metric("database_query", 0.1, threshold=0.2)
            logger.performance_metric("slow_query", 0.5, threshold=0.2)
            
            # Test results
            logger.test_result("test_login", "passed", 0.1)
            logger.test_result("test_logout", "failed", 0.2)
            
            # Check metrics were collected
            metrics = logger.get_business_metrics()
            assert len(metrics) == 3  # Only business_metric calls are stored
            
            # Check log files
            assert (Path(temp_dir) / "app" / "storm_app.log").exists()


class TestErrorHandling:
    """Test error handling and edge cases."""

    def test_invalid_log_directory(self):
        """Test handling of invalid log directory."""
        # Try to create logger with invalid directory
        config = StormLoggerConfig(log_directory=Path("/invalid/path"))
        
        logger = get_storm_logger("error_test", config)
        
        # Should not raise exception during logger creation
        assert logger is not None
        
        # Logging should still work (may fall back to console only)
        logger.info("Test message")

    def test_missing_dependencies(self):
        """Test behavior when optional dependencies are missing."""
        with tempfile.TemporaryDirectory() as temp_dir:
            config = StormLoggerConfig(log_directory=Path(temp_dir))
            logger = get_storm_logger("deps_test", config)
            
            # Should work even if rich/colorlog are not available
            logger.info("Test message")
            
            assert (Path(temp_dir) / "app" / "storm_app.log").exists()

    def test_concurrent_logging(self):
        """Test concurrent logging from multiple threads."""
        import threading
        import time
        
        with tempfile.TemporaryDirectory() as temp_dir:
            config = StormLoggerConfig(log_directory=Path(temp_dir))
            logger = get_storm_logger("concurrent_test", config)
            
            def log_messages(thread_id):
                for i in range(10):
                    logger.info(f"Thread {thread_id} - Message {i}")
                    pass  # Removed sleep for faster tests
            
            # Create multiple threads
            threads = []
            for i in range(3):
                thread = threading.Thread(target=log_messages, args=(i,))
                threads.append(thread)
                thread.start()
            
            # Wait for all threads to complete
            for thread in threads:
                thread.join()
            
            # Check log file was created
            assert (Path(temp_dir) / "app" / "storm_app.log").exists()

    def test_large_log_messages(self):
        """Test handling of large log messages."""
        with tempfile.TemporaryDirectory() as temp_dir:
            config = StormLoggerConfig(log_directory=Path(temp_dir))
            logger = get_storm_logger("large_test", config)
            
            # Create a large message
            large_message = "A" * 10000
            
            logger.info(large_message)
            
            # Should handle large messages without issues
            assert (Path(temp_dir) / "app" / "storm_app.log").exists()