"""
Comprehensive unit tests for console implementations.
Tests all concrete implementations to achieve 100% coverage.
"""

from unittest.mock import Mock, patch

import pytest

from storm_logger.console.console_implementations import (
    DefaultConfigProvider,
    DefaultRichComponentFactory,
    DefaultSafetyProvider,
    DefaultThemeProvider,
    RichConsoleFactory,
    RichProgressFactory,
    RichSyntaxFactory,
)


class TestRichConsoleFactory:
    """Test RichConsoleFactory implementation."""

    def test_create_console(self):
        """Test creating a Rich Console instance."""
        with patch("rich.console.Console") as mock_console_class:
            mock_console = Mock()
            mock_console_class.return_value = mock_console

            factory = RichConsoleFactory()
            theme = Mock()

            result = factory.create_console(
                theme=theme, force_terminal=True, legacy_windows=False, safe_box=True, stderr=False
            )

            assert result is mock_console
            mock_console_class.assert_called_once_with(
                theme=theme, force_terminal=True, legacy_windows=False, safe_box=True, stderr=False
            )


class TestRichSyntaxFactory:
    """Test RichSyntaxFactory implementation."""

    def test_create_syntax(self):
        """Test creating a Rich Syntax instance."""
        with patch("rich.syntax.Syntax") as mock_syntax_class:
            mock_syntax = Mock()
            mock_syntax_class.return_value = mock_syntax

            factory = RichSyntaxFactory()

            result = factory.create_syntax(
                code="print('hello')", language="python", theme="monokai"
            )

            assert result is mock_syntax
            mock_syntax_class.assert_called_once_with("print('hello')", "python", theme="monokai")


class TestRichProgressFactory:
    """Test RichProgressFactory implementation."""

    def test_create_progress(self):
        """Test creating a Rich Progress instance."""
        with patch("rich.progress.Progress") as mock_progress_class:
            mock_progress = Mock()
            mock_progress_class.return_value = mock_progress

            factory = RichProgressFactory()
            mock_console = Mock()
            column1 = Mock()
            column2 = Mock()

            result = factory.create_progress(
                column1, column2, console=mock_console, refresh_per_second=5
            )

            assert result is mock_progress
            mock_progress_class.assert_called_once_with(
                column1, column2, console=mock_console, refresh_per_second=5
            )

    def test_create_spinner_column(self):
        """Test creating a spinner column."""
        with patch("rich.progress.SpinnerColumn") as mock_spinner_class:
            mock_spinner = Mock()
            mock_spinner_class.return_value = mock_spinner

            factory = RichProgressFactory()
            result = factory.create_spinner_column()

            assert result is mock_spinner
            mock_spinner_class.assert_called_once_with()

    def test_create_text_column(self):
        """Test creating a text column."""
        with patch("rich.progress.TextColumn") as mock_text_class:
            mock_text = Mock()
            mock_text_class.return_value = mock_text

            factory = RichProgressFactory()
            result = factory.create_text_column("{task.description}")

            assert result is mock_text
            mock_text_class.assert_called_once_with("{task.description}")

    def test_create_bar_column(self):
        """Test creating a bar column."""
        with patch("rich.progress.BarColumn") as mock_bar_class:
            mock_bar = Mock()
            mock_bar_class.return_value = mock_bar

            factory = RichProgressFactory()
            result = factory.create_bar_column()

            assert result is mock_bar
            mock_bar_class.assert_called_once_with()


class TestDefaultRichComponentFactory:
    """Test DefaultRichComponentFactory implementation."""

    def test_create_table(self):
        """Test creating a Rich Table instance."""
        with patch("rich.table.Table") as mock_table_class:
            mock_table = Mock()
            mock_table_class.return_value = mock_table

            factory = DefaultRichComponentFactory()

            result = factory.create_table(title="Test Table", show_header=True, header_style="bold")

            assert result is mock_table
            mock_table_class.assert_called_once_with(
                title="Test Table", show_header=True, header_style="bold"
            )

    def test_create_table_defaults(self):
        """Test creating table with default values."""
        with patch("rich.table.Table") as mock_table_class:
            mock_table = Mock()
            mock_table_class.return_value = mock_table

            factory = DefaultRichComponentFactory()
            result = factory.create_table()

            assert result is mock_table
            mock_table_class.assert_called_once_with(
                title=None, show_header=True, header_style=None
            )

    def test_create_panel(self):
        """Test creating a Rich Panel instance."""
        with patch("rich.panel.Panel") as mock_panel_class:
            mock_panel = Mock()
            mock_panel_class.return_value = mock_panel

            factory = DefaultRichComponentFactory()
            content = "Test content"

            result = factory.create_panel(
                content=content, title="Test Panel", style="blue", padding=(1, 2)
            )

            assert result is mock_panel
            mock_panel_class.assert_called_once_with(
                content, title="Test Panel", style="blue", padding=(1, 2)
            )

    def test_create_panel_defaults(self):
        """Test creating panel with default values."""
        with patch("rich.panel.Panel") as mock_panel_class:
            mock_panel = Mock()
            mock_panel_class.return_value = mock_panel

            factory = DefaultRichComponentFactory()
            content = "Test content"

            result = factory.create_panel(content)

            assert result is mock_panel
            mock_panel_class.assert_called_once_with(
                content, title=None, style=None, padding=(0, 1)
            )

    def test_create_text(self):
        """Test creating a Rich Text instance."""
        with patch("rich.text.Text") as mock_text_class:
            mock_text = Mock()
            mock_text_class.return_value = mock_text

            factory = DefaultRichComponentFactory()

            result = factory.create_text("Hello", style="bold red")

            assert result is mock_text
            mock_text_class.assert_called_once_with("Hello", style="bold red")

    def test_create_text_no_style(self):
        """Test creating text without style."""
        with patch("rich.text.Text") as mock_text_class:
            mock_text = Mock()
            mock_text_class.return_value = mock_text

            factory = DefaultRichComponentFactory()

            result = factory.create_text("Hello")

            assert result is mock_text
            mock_text_class.assert_called_once_with("Hello", style=None)

    def test_create_columns(self):
        """Test creating Rich Columns layout."""
        with patch("rich.columns.Columns") as mock_columns_class:
            mock_columns = Mock()
            mock_columns_class.return_value = mock_columns

            factory = DefaultRichComponentFactory()
            renderables = [Mock(), Mock(), Mock()]

            result = factory.create_columns(renderables)

            assert result is mock_columns
            mock_columns_class.assert_called_once_with(renderables)

    def test_create_layout(self):
        """Test creating a Rich Layout instance."""
        with patch("rich.layout.Layout") as mock_layout_class:
            mock_layout = Mock()
            mock_layout_class.return_value = mock_layout

            factory = DefaultRichComponentFactory()

            result = factory.create_layout()

            assert result is mock_layout
            mock_layout_class.assert_called_once_with()

    def test_create_live(self):
        """Test creating a Rich Live display instance."""
        with patch("rich.live.Live") as mock_live_class:
            mock_live = Mock()
            mock_live_class.return_value = mock_live

            factory = DefaultRichComponentFactory()
            renderable = Mock()
            console = Mock()

            result = factory.create_live(
                renderable=renderable, console=console, refresh_per_second=8
            )

            assert result is mock_live
            mock_live_class.assert_called_once_with(
                renderable, console=console, refresh_per_second=8
            )

    def test_create_live_default_refresh(self):
        """Test creating live display with default refresh rate."""
        with patch("rich.live.Live") as mock_live_class:
            mock_live = Mock()
            mock_live_class.return_value = mock_live

            factory = DefaultRichComponentFactory()
            renderable = Mock()
            console = Mock()

            result = factory.create_live(renderable, console)

            assert result is mock_live
            mock_live_class.assert_called_once_with(
                renderable, console=console, refresh_per_second=4
            )


class TestDefaultThemeProvider:
    """Test DefaultThemeProvider implementation."""

    def test_get_theme(self):
        """Test getting theme by name."""
        with patch("storm_logger.console.themes.get_theme") as mock_get_theme:
            mock_theme = Mock()
            mock_get_theme.return_value = mock_theme

            provider = DefaultThemeProvider()
            result = provider.get_theme("professional")

            assert result is mock_theme
            mock_get_theme.assert_called_once_with("professional")


class TestDefaultConfigProvider:
    """Test DefaultConfigProvider implementation."""

    def test_get_config(self):
        """Test getting configuration."""
        with patch("storm_logger.config.get_config") as mock_get_config:
            mock_config = Mock()
            mock_get_config.return_value = mock_config

            provider = DefaultConfigProvider()
            result = provider.get_config()

            assert result is mock_config
            mock_get_config.assert_called_once_with()


class TestDefaultSafetyProvider:
    """Test DefaultSafetyProvider implementation."""

    def test_get_safety_wrapper(self):
        """Test getting safety wrapper instance."""
        with patch("storm_logger.console.safety.SafeConsoleWrapper") as mock_wrapper_class:
            mock_wrapper = Mock()
            mock_wrapper_class.return_value = mock_wrapper

            provider = DefaultSafetyProvider()
            result = provider.get_safety_wrapper()

            assert result is mock_wrapper
            mock_wrapper_class.assert_called_once_with()


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