"""
Comprehensive unit tests for Storm Logger console safety module.
Tests all functionality to achieve 100% coverage.
"""

import pytest
import sys
from io import StringIO
from unittest.mock import Mock, MagicMock, patch
from typing import Optional, TextIO, Any

from storm_logger.console.safety import (
    ConsoleChecker, OutputWriter, RichImporter,
    RealConsoleChecker, RealOutputWriter, RealRichImporter,
    SafeConsoleConfig, SafeConsoleWrapper, SimpleProgress,
    get_safety_wrapper, set_safety_wrapper, reset_safety_wrapper
)


# Mock implementations for testing

class MockConsoleChecker(ConsoleChecker):
    """Mock console checker for testing."""
    
    def __init__(self, rich_available: bool = True):
        self.rich_available = rich_available
        self.check_count = 0
    
    def check_rich_availability(self) -> bool:
        self.check_count += 1
        return self.rich_available


class MockOutputWriter(OutputWriter):
    """Mock output writer for testing."""
    
    def __init__(self):
        self.written_messages = []
        self.written_lines = []
    
    def write(self, message: str, file: Optional[TextIO] = None) -> None:
        self.written_messages.append((message, file))
    
    def write_line(self, message: str, file: Optional[TextIO] = None) -> None:
        self.written_lines.append((message, file))


class MockRichImporter(RichImporter):
    """Mock Rich importer for testing."""
    
    def __init__(self, raise_error: bool = False):
        self.raise_error = raise_error
        self.console_class = Mock()
        self.panel_class = Mock()
        self.table_class = Mock()
        self.progress_class = Mock()
    
    def import_console(self):
        if self.raise_error:
            raise ImportError("Mock import error")
        return self.console_class
    
    def import_panel(self):
        if self.raise_error:
            raise ImportError("Mock import error")
        return self.panel_class
    
    def import_table(self):
        if self.raise_error:
            raise ImportError("Mock import error")
        return self.table_class
    
    def import_progress(self):
        if self.raise_error:
            raise ImportError("Mock import error")
        return self.progress_class


class TestRealConsoleChecker:
    """Test the real console checker implementation."""
    
    def test_check_rich_availability_success(self):
        """Test successful Rich availability check."""
        with patch('rich.console.Console') as mock_console:
            mock_instance = Mock()
            mock_console.return_value = mock_instance
            
            checker = RealConsoleChecker()
            assert checker.check_rich_availability() is True
            mock_instance.print.assert_called_once_with("", end="")
    
    def test_check_rich_availability_import_error(self):
        """Test Rich availability check with import error."""
        with patch('rich.console.Console', side_effect=ImportError()):
            checker = RealConsoleChecker()
            assert checker.check_rich_availability() is False
    
    def test_check_rich_availability_os_error(self):
        """Test Rich availability check with OS error."""
        with patch('rich.console.Console') as mock_console:
            mock_instance = Mock()
            mock_instance.print.side_effect = OSError("OS Error")
            mock_console.return_value = mock_instance
            
            checker = RealConsoleChecker()
            assert checker.check_rich_availability() is False
    
    def test_check_rich_availability_unicode_error(self):
        """Test Rich availability check with Unicode error."""
        with patch('rich.console.Console') as mock_console:
            mock_instance = Mock()
            mock_instance.print.side_effect = UnicodeError("Unicode Error")
            mock_console.return_value = mock_instance
            
            checker = RealConsoleChecker()
            assert checker.check_rich_availability() is False


class TestRealOutputWriter:
    """Test the real output writer implementation."""
    
    def test_write(self):
        """Test write method."""
        writer = RealOutputWriter()
        output = StringIO()
        
        writer.write("test message", file=output)
        assert output.getvalue() == "test message"
    
    def test_write_default_stdout(self):
        """Test write with default stdout."""
        writer = RealOutputWriter()
        with patch('sys.stdout', new=StringIO()) as mock_stdout:
            writer.write("test message")
            assert mock_stdout.getvalue() == "test message"
    
    def test_write_line(self):
        """Test write_line method."""
        writer = RealOutputWriter()
        output = StringIO()
        
        writer.write_line("test line", file=output)
        assert output.getvalue() == "test line\n"
    
    def test_write_line_default_stdout(self):
        """Test write_line with default stdout."""
        writer = RealOutputWriter()
        with patch('sys.stdout', new=StringIO()) as mock_stdout:
            writer.write_line("test line")
            assert mock_stdout.getvalue() == "test line\n"


class TestRealRichImporter:
    """Test the real Rich importer implementation."""
    
    def test_import_console(self):
        """Test importing Console."""
        with patch('rich.console.Console') as mock_console:
            importer = RealRichImporter()
            result = importer.import_console()
            assert result is mock_console
    
    def test_import_panel(self):
        """Test importing Panel."""
        with patch('rich.panel.Panel') as mock_panel:
            importer = RealRichImporter()
            result = importer.import_panel()
            assert result is mock_panel
    
    def test_import_table(self):
        """Test importing Table."""
        with patch('rich.table.Table') as mock_table:
            importer = RealRichImporter()
            result = importer.import_table()
            assert result is mock_table
    
    def test_import_progress(self):
        """Test importing Progress."""
        with patch('rich.progress.Progress') as mock_progress:
            importer = RealRichImporter()
            result = importer.import_progress()
            assert result is mock_progress


class TestSafeConsoleConfig:
    """Test SafeConsoleConfig dataclass."""
    
    def test_default_config(self):
        """Test default configuration values."""
        config = SafeConsoleConfig()
        assert config.fallback_to_print is True
        assert config.check_on_init is True
        assert config.console_checker is None
        assert config.output_writer is None
        assert config.rich_importer is None
    
    def test_custom_config(self):
        """Test custom configuration values."""
        checker = MockConsoleChecker()
        writer = MockOutputWriter()
        importer = MockRichImporter()
        
        config = SafeConsoleConfig(
            fallback_to_print=False,
            check_on_init=False,
            console_checker=checker,
            output_writer=writer,
            rich_importer=importer
        )
        
        assert config.fallback_to_print is False
        assert config.check_on_init is False
        assert config.console_checker is checker
        assert config.output_writer is writer
        assert config.rich_importer is importer


class TestSafeConsoleWrapper:
    """Test SafeConsoleWrapper class."""
    
    def test_init_default_config(self):
        """Test initialization with default config."""
        wrapper = SafeConsoleWrapper()
        assert wrapper.fallback_to_print is True
        assert wrapper._rich_available is True  # Default checker returns True
    
    def test_init_custom_config(self):
        """Test initialization with custom config."""
        checker = MockConsoleChecker(rich_available=False)
        writer = MockOutputWriter()
        importer = MockRichImporter()
        
        config = SafeConsoleConfig(
            fallback_to_print=False,
            check_on_init=True,
            console_checker=checker,
            output_writer=writer,
            rich_importer=importer
        )
        
        wrapper = SafeConsoleWrapper(config)
        assert wrapper.fallback_to_print is False
        assert wrapper._rich_available is False
        assert checker.check_count == 1
    
    def test_init_no_check_on_init(self):
        """Test initialization without checking on init."""
        checker = MockConsoleChecker(rich_available=False)
        config = SafeConsoleConfig(check_on_init=False, console_checker=checker)
        
        wrapper = SafeConsoleWrapper(config)
        assert wrapper._rich_available is True  # Assumes available
        assert checker.check_count == 0  # Not checked
    
    def test_safe_print_rich_available_with_style(self):
        """Test safe_print when Rich is available with style."""
        mock_console = Mock()
        wrapper = SafeConsoleWrapper()
        
        wrapper.safe_print(mock_console, "test message", style="bold red")
        mock_console.print.assert_called_once_with("test message", style="bold red")
    
    def test_safe_print_rich_available_without_style(self):
        """Test safe_print when Rich is available without style."""
        mock_console = Mock()
        wrapper = SafeConsoleWrapper()
        
        wrapper.safe_print(mock_console, "test message")
        mock_console.print.assert_called_once_with("test message")
    
    def test_safe_print_rich_available_with_kwargs(self):
        """Test safe_print when Rich is available with extra kwargs."""
        mock_console = Mock()
        mock_file = StringIO()
        wrapper = SafeConsoleWrapper()
        
        wrapper.safe_print(mock_console, "test message", file=mock_file, end="")
        mock_console.print.assert_called_once_with("test message", file=mock_file, end="")
    
    def test_safe_print_rich_fails_fallback(self):
        """Test safe_print when Rich fails and falls back."""
        mock_console = Mock()
        mock_console.print.side_effect = OSError("Console error")
        writer = MockOutputWriter()
        
        config = SafeConsoleConfig(output_writer=writer)
        wrapper = SafeConsoleWrapper(config)
        
        wrapper.safe_print(mock_console, "test message")
        assert writer.written_lines == [("test message", sys.stdout)]
        assert wrapper._rich_available is False
    
    def test_safe_print_rich_fails_unicode_error(self):
        """Test safe_print when Rich fails with Unicode error."""
        mock_console = Mock()
        mock_console.print.side_effect = UnicodeError("Unicode error")
        writer = MockOutputWriter()
        
        config = SafeConsoleConfig(output_writer=writer)
        wrapper = SafeConsoleWrapper(config)
        
        wrapper.safe_print(mock_console, "test message")
        assert writer.written_lines == [("test message", sys.stdout)]
        assert wrapper._rich_available is False
    
    def test_safe_print_rich_fails_attribute_error(self):
        """Test safe_print when Rich fails with AttributeError."""
        mock_console = Mock()
        mock_console.print.side_effect = AttributeError("Attribute error")
        writer = MockOutputWriter()
        
        config = SafeConsoleConfig(output_writer=writer)
        wrapper = SafeConsoleWrapper(config)
        
        wrapper.safe_print(mock_console, "test message")
        assert writer.written_lines == [("test message", sys.stdout)]
        assert wrapper._rich_available is False
    
    def test_safe_print_no_fallback(self):
        """Test safe_print with no fallback to print."""
        mock_console = Mock()
        writer = MockOutputWriter()
        
        config = SafeConsoleConfig(
            fallback_to_print=False,
            console_checker=MockConsoleChecker(rich_available=False),
            output_writer=writer
        )
        wrapper = SafeConsoleWrapper(config)
        
        wrapper.safe_print(mock_console, "test message")
        assert writer.written_lines == []  # No output
    
    def test_safe_print_custom_file(self):
        """Test safe_print with custom file output."""
        mock_file = StringIO()
        writer = MockOutputWriter()
        
        config = SafeConsoleConfig(
            console_checker=MockConsoleChecker(rich_available=False),
            output_writer=writer
        )
        wrapper = SafeConsoleWrapper(config)
        
        wrapper.safe_print(None, "test message", file=mock_file)
        assert writer.written_lines == [("test message", mock_file)]
    
    def test_safe_panel_rich_available(self):
        """Test safe_panel when Rich is available."""
        mock_console = Mock()
        mock_panel_class = Mock()
        mock_panel_instance = Mock()
        mock_panel_class.return_value = mock_panel_instance
        
        importer = MockRichImporter()
        importer.panel_class = mock_panel_class
        
        config = SafeConsoleConfig(rich_importer=importer)
        wrapper = SafeConsoleWrapper(config)
        
        wrapper.safe_panel(mock_console, "content", title="Title", style="blue")
        
        mock_panel_class.assert_called_once_with("content", title="Title", style="blue")
        mock_console.print.assert_called_once_with(mock_panel_instance)
    
    def test_safe_panel_import_error_fallback(self):
        """Test safe_panel when import fails."""
        mock_console = Mock()
        writer = MockOutputWriter()
        importer = MockRichImporter(raise_error=True)
        
        config = SafeConsoleConfig(
            rich_importer=importer,
            output_writer=writer
        )
        wrapper = SafeConsoleWrapper(config)
        
        wrapper.safe_panel(mock_console, "content", title="Title")
        
        assert writer.written_lines == [
            ("=== Title ===", None),
            ("content", None),
            ("=============", None)
        ]
        assert wrapper._rich_available is False
    
    def test_safe_panel_print_error_fallback(self):
        """Test safe_panel when console.print fails."""
        mock_console = Mock()
        mock_console.print.side_effect = OSError("Print error")
        writer = MockOutputWriter()
        
        config = SafeConsoleConfig(output_writer=writer)
        wrapper = SafeConsoleWrapper(config)
        
        wrapper.safe_panel(mock_console, "content", title="Title")
        
        assert writer.written_lines == [
            ("=== Title ===", None),
            ("content", None),
            ("=============", None)
        ]
    
    def test_safe_panel_no_title(self):
        """Test safe_panel without title."""
        writer = MockOutputWriter()
        
        config = SafeConsoleConfig(
            console_checker=MockConsoleChecker(rich_available=False),
            output_writer=writer
        )
        wrapper = SafeConsoleWrapper(config)
        
        wrapper.safe_panel(None, "content")
        
        assert writer.written_lines == [("content", None)]
    
    def test_safe_panel_no_fallback(self):
        """Test safe_panel with no fallback."""
        mock_console = Mock()
        writer = MockOutputWriter()
        
        config = SafeConsoleConfig(
            fallback_to_print=False,
            console_checker=MockConsoleChecker(rich_available=False),
            output_writer=writer
        )
        wrapper = SafeConsoleWrapper(config)
        
        wrapper.safe_panel(mock_console, "content", title="Title")
        assert writer.written_lines == []  # No output
    
    def test_safe_table_rich_available(self):
        """Test safe_table when Rich is available."""
        mock_console = Mock()
        mock_table_class = Mock()
        mock_table_instance = Mock()
        mock_table_class.return_value = mock_table_instance
        
        importer = MockRichImporter()
        importer.table_class = mock_table_class
        
        config = SafeConsoleConfig(rich_importer=importer)
        wrapper = SafeConsoleWrapper(config)
        
        headers = ["Col1", "Col2"]
        rows = [["A", "B"], ["C", "D"]]
        
        wrapper.safe_table(mock_console, headers, rows, title="Test Table")
        
        mock_table_class.assert_called_once_with(title="Test Table")
        assert mock_table_instance.add_column.call_count == 2
        assert mock_table_instance.add_row.call_count == 2
        mock_console.print.assert_called_once_with(mock_table_instance)
    
    def test_safe_table_import_error_fallback(self):
        """Test safe_table when import fails."""
        mock_console = Mock()
        writer = MockOutputWriter()
        importer = MockRichImporter(raise_error=True)
        
        config = SafeConsoleConfig(
            rich_importer=importer,
            output_writer=writer
        )
        wrapper = SafeConsoleWrapper(config)
        
        headers = ["Col1", "Col2"]
        rows = [["A", "B"], ["C", "D"]]
        
        wrapper.safe_table(mock_console, headers, rows, title="Test Table")
        
        assert writer.written_lines == [
            ("=== Test Table ===", None),
            ("Col1 | Col2", None),
            ("-----------", None),
            ("A | B", None),
            ("C | D", None)
        ]
    
    def test_safe_table_no_title(self):
        """Test safe_table without title."""
        writer = MockOutputWriter()
        
        config = SafeConsoleConfig(
            console_checker=MockConsoleChecker(rich_available=False),
            output_writer=writer
        )
        wrapper = SafeConsoleWrapper(config)
        
        headers = ["Col1", "Col2"]
        rows = [["A", "B"]]
        
        wrapper.safe_table(None, headers, rows)
        
        assert writer.written_lines == [
            ("Col1 | Col2", None),
            ("-----------", None),
            ("A | B", None)
        ]
    
    def test_safe_table_no_fallback(self):
        """Test safe_table with no fallback."""
        mock_console = Mock()
        writer = MockOutputWriter()
        
        config = SafeConsoleConfig(
            fallback_to_print=False,
            console_checker=MockConsoleChecker(rich_available=False),
            output_writer=writer
        )
        wrapper = SafeConsoleWrapper(config)
        
        wrapper.safe_table(mock_console, ["H1"], [["R1"]])
        assert writer.written_lines == []  # No output
    
    def test_safe_table_with_non_string_cells(self):
        """Test safe_table with non-string cell values."""
        writer = MockOutputWriter()
        
        config = SafeConsoleConfig(
            console_checker=MockConsoleChecker(rich_available=False),
            output_writer=writer
        )
        wrapper = SafeConsoleWrapper(config)
        
        headers = ["String", "Number", "None"]
        rows = [["text", 42, None]]
        
        wrapper.safe_table(None, headers, rows)
        
        assert writer.written_lines[2] == ("text | 42 | None", None)
    
    def test_safe_progress_rich_available(self):
        """Test safe_progress when Rich is available."""
        mock_console = Mock()
        mock_progress_class = Mock()
        mock_progress_instance = Mock()
        mock_progress_class.return_value = mock_progress_instance
        
        importer = MockRichImporter()
        importer.progress_class = mock_progress_class
        
        config = SafeConsoleConfig(rich_importer=importer)
        wrapper = SafeConsoleWrapper(config)
        
        tasks = ["Task 1", "Task 2"]
        result = wrapper.safe_progress(mock_console, tasks, refresh_per_second=10)
        
        mock_progress_class.assert_called_once_with(console=mock_console, refresh_per_second=10)
        assert result is mock_progress_instance
    
    def test_safe_progress_import_error_fallback(self):
        """Test safe_progress when import fails."""
        mock_console = Mock()
        writer = MockOutputWriter()
        importer = MockRichImporter(raise_error=True)
        
        config = SafeConsoleConfig(
            rich_importer=importer,
            output_writer=writer
        )
        wrapper = SafeConsoleWrapper(config)
        
        tasks = ["Task 1", "Task 2"]
        result = wrapper.safe_progress(mock_console, tasks)
        
        assert isinstance(result, SimpleProgress)
        assert result.tasks == tasks
        assert result._output_writer is writer
    
    def test_is_rich_available(self):
        """Test is_rich_available method."""
        wrapper = SafeConsoleWrapper()
        assert wrapper.is_rich_available() is True
        
        wrapper._rich_available = False
        assert wrapper.is_rich_available() is False
    
    def test_set_rich_availability(self):
        """Test set_rich_availability method."""
        wrapper = SafeConsoleWrapper()
        
        wrapper.set_rich_availability(False)
        assert wrapper._rich_available is False
        
        wrapper.set_rich_availability(True)
        assert wrapper._rich_available is True


class TestSimpleProgress:
    """Test SimpleProgress class."""
    
    def test_init(self):
        """Test SimpleProgress initialization."""
        tasks = ["Task 1", "Task 2", "Task 3"]
        progress = SimpleProgress(tasks)
        
        assert progress.tasks == tasks
        assert progress.current_task == 0
        assert progress.total_tasks == 3
        assert progress._completed_tasks == {}
    
    def test_init_with_custom_writer(self):
        """Test SimpleProgress with custom output writer."""
        writer = MockOutputWriter()
        tasks = ["Task 1"]
        progress = SimpleProgress(tasks, output_writer=writer)
        
        assert progress._output_writer is writer
    
    def test_context_manager_success(self):
        """Test SimpleProgress as context manager with success."""
        writer = MockOutputWriter()
        tasks = ["Task 1", "Task 2"]
        
        with SimpleProgress(tasks, output_writer=writer) as progress:
            assert writer.written_lines[0] == ("Starting 2 tasks...", None)
        
        assert writer.written_lines[-1] == ("All tasks completed!", None)
    
    def test_context_manager_exception(self):
        """Test SimpleProgress as context manager with exception."""
        writer = MockOutputWriter()
        tasks = ["Task 1"]
        
        with pytest.raises(ValueError):
            with SimpleProgress(tasks, output_writer=writer) as progress:
                raise ValueError("Test error")
        
        assert writer.written_lines[-1] == ("Task failed: Test error", None)
    
    def test_add_task(self):
        """Test add_task method."""
        writer = MockOutputWriter()
        progress = SimpleProgress(["Task 1", "Task 2"], output_writer=writer)
        
        task_id = progress.add_task("First task", _total=50)
        assert task_id == 0
        assert progress.current_task == 1
        assert progress._completed_tasks[0] == 0
        assert writer.written_lines[-1] == ("Task 1/2: First task", None)
        
        task_id2 = progress.add_task("Second task")
        assert task_id2 == 1
        assert progress.current_task == 2
        assert progress._completed_tasks[1] == 0
        assert writer.written_lines[-1] == ("Task 2/2: Second task", None)
    
    def test_update_with_description(self):
        """Test update method with description."""
        writer = MockOutputWriter()
        progress = SimpleProgress(["Task 1"], output_writer=writer)
        
        task_id = progress.add_task("Task")
        progress.update(task_id, description="Processing...")
        
        assert writer.written_lines[-1] == ("  Processing...", None)
    
    def test_update_with_completed(self):
        """Test update method with completed percentage."""
        writer = MockOutputWriter()
        progress = SimpleProgress(["Task 1"], output_writer=writer)
        
        task_id = progress.add_task("Task")
        progress.update(task_id, completed=50)
        
        assert progress._completed_tasks[task_id] == 50
        assert writer.written_lines[-1] == ("  Progress: 50%", None)
    
    def test_update_with_both(self):
        """Test update method with both description and completed."""
        writer = MockOutputWriter()
        progress = SimpleProgress(["Task 1"], output_writer=writer)
        
        task_id = progress.add_task("Task")
        progress.update(task_id, completed=75, description="Almost done")
        
        assert writer.written_lines[-2] == ("  Almost done", None)
        assert writer.written_lines[-1] == ("  Progress: 75%", None)
    
    def test_update_zero_completed(self):
        """Test update method with zero completed (should not print)."""
        writer = MockOutputWriter()
        progress = SimpleProgress(["Task 1"], output_writer=writer)
        
        task_id = progress.add_task("Task")
        lines_before = len(writer.written_lines)
        progress.update(task_id, completed=0)
        
        assert len(writer.written_lines) == lines_before  # No new lines
    
    def test_advance(self):
        """Test advance method."""
        writer = MockOutputWriter()
        progress = SimpleProgress(["Task 1"], output_writer=writer)
        
        task_id = progress.add_task("Task")
        
        progress.advance(task_id, 25)
        assert progress._completed_tasks[task_id] == 25
        assert writer.written_lines[-1] == ("  Advanced to: 25%", None)
        
        progress.advance(task_id, 30)
        assert progress._completed_tasks[task_id] == 55
        assert writer.written_lines[-1] == ("  Advanced to: 55%", None)
    
    def test_advance_zero(self):
        """Test advance with zero (should not print)."""
        writer = MockOutputWriter()
        progress = SimpleProgress(["Task 1"], output_writer=writer)
        
        task_id = progress.add_task("Task")
        lines_before = len(writer.written_lines)
        progress.advance(task_id, 0)
        
        assert len(writer.written_lines) == lines_before  # No new lines
    
    def test_advance_over_100(self):
        """Test advance that would go over 100%."""
        writer = MockOutputWriter()
        progress = SimpleProgress(["Task 1"], output_writer=writer)
        
        task_id = progress.add_task("Task")
        progress.advance(task_id, 80)
        progress.advance(task_id, 30)  # Would be 110, should cap at 100
        
        assert progress._completed_tasks[task_id] == 100
        assert writer.written_lines[-1] == ("  Advanced to: 100%", None)
    
    def test_advance_unknown_task(self):
        """Test advance on unknown task ID."""
        writer = MockOutputWriter()
        progress = SimpleProgress(["Task 1"], output_writer=writer)
        
        progress.advance(999, 50)  # Unknown task ID
        assert progress._completed_tasks[999] == 50
        assert writer.written_lines[-1] == ("  Advanced to: 50%", None)
    
    def test_get_progress(self):
        """Test get_progress method."""
        progress = SimpleProgress(["Task 1"])
        
        task_id = progress.add_task("Task")
        assert progress.get_progress(task_id) == 0
        
        progress.advance(task_id, 42)
        assert progress.get_progress(task_id) == 42
        
        # Unknown task ID
        assert progress.get_progress(999) == 0


class TestGlobalFunctions:
    """Test global functions."""
    
    def test_get_safety_wrapper(self):
        """Test get_safety_wrapper returns the global instance."""
        wrapper = get_safety_wrapper()
        assert isinstance(wrapper, SafeConsoleWrapper)
        
        # Should return the same instance
        wrapper2 = get_safety_wrapper()
        assert wrapper is wrapper2
    
    def test_set_safety_wrapper(self):
        """Test set_safety_wrapper replaces the global instance."""
        original = get_safety_wrapper()
        
        custom_wrapper = SafeConsoleWrapper(
            SafeConsoleConfig(fallback_to_print=False)
        )
        set_safety_wrapper(custom_wrapper)
        
        current = get_safety_wrapper()
        assert current is custom_wrapper
        assert current is not original
        
        # Restore original for other tests
        set_safety_wrapper(original)
    
    def test_reset_safety_wrapper(self):
        """Test reset_safety_wrapper creates a new default instance."""
        original = get_safety_wrapper()
        
        # Modify the original
        original.set_rich_availability(False)
        
        # Reset
        reset_safety_wrapper()
        
        new_wrapper = get_safety_wrapper()
        assert new_wrapper is not original
        assert new_wrapper._rich_available is True  # Default state


class TestIntegrationScenarios:
    """Test complete integration scenarios."""
    
    def test_complete_fallback_scenario(self):
        """Test complete scenario where Rich fails and falls back."""
        # Set up a wrapper that will fail Rich operations
        mock_console = Mock()
        mock_console.print.side_effect = OSError("Console error")
        
        output = StringIO()
        writer = MockOutputWriter()
        
        config = SafeConsoleConfig(
            output_writer=writer,
            rich_importer=MockRichImporter(raise_error=True)
        )
        wrapper = SafeConsoleWrapper(config)
        
        # Test all methods falling back
        wrapper.safe_print(mock_console, "Print test")
        wrapper.safe_panel(mock_console, "Panel content", title="Panel")
        wrapper.safe_table(mock_console, ["H1", "H2"], [["A", "B"]], title="Table")
        progress = wrapper.safe_progress(mock_console, ["Task 1"])
        
        # Verify fallback outputs
        assert len(writer.written_lines) > 0
        assert isinstance(progress, SimpleProgress)
        assert wrapper._rich_available is False
    
    def test_mixed_success_and_failure(self):
        """Test scenario where some Rich operations succeed and others fail."""
        mock_console = Mock()
        importer = MockRichImporter()
        
        # Make table import fail
        def import_table_fail():
            raise ImportError("Table not available")
        importer.import_table = import_table_fail
        
        config = SafeConsoleConfig(rich_importer=importer)
        wrapper = SafeConsoleWrapper(config)
        
        # Print should work
        wrapper.safe_print(mock_console, "This works")
        mock_console.print.assert_called()
        
        # Table should fall back
        writer = MockOutputWriter()
        wrapper._output_writer = writer
        wrapper.safe_table(mock_console, ["H1"], [["R1"]])
        assert len(writer.written_lines) > 0


if __name__ == "__main__":
    pytest.main([__file__, "-v"])