"""Unit tests for CSV stderr redirection functionality."""

import sys
from io import StringIO
from unittest.mock import Mock, patch

import pytest
from rich.console import Console

from forkscout.display.repository_display_service import RepositoryDisplayService
from forkscout.models.ahead_only_filter import FilteredForkResult


class TestCSVStderrRedirectionUnit:
    """Unit tests for CSV stderr redirection."""

    def test_filtering_message_goes_to_stderr_in_csv_mode(self):
        """Test that filtering messages are redirected to stderr in CSV mode."""
        # Create mock objects
        mock_github_client = Mock()
        
        # Create a repository display service
        service = RepositoryDisplayService(
            github_client=mock_github_client,
            console=Console(file=StringIO(), width=80)  # Mock stdout console
        )
        
        # Create a mock filter result with exclusions
        filter_result = Mock(spec=FilteredForkResult)
        filter_result.total_excluded = 5
        filter_result.exclusion_summary = "Filtered 10 forks: 5 included, 2 private excluded, 3 no commits excluded"
        
        # Capture stderr
        stderr_capture = StringIO()
        
        with patch('sys.stderr', stderr_capture):
            # Simulate the filtering message print in CSV mode
            if True:  # csv_export = True
                # Always use stderr for CSV mode to keep stdout clean
                stderr_console = Console(file=sys.stderr, soft_wrap=False, width=400)
                stderr_console.print(f"[dim]{filter_result.exclusion_summary}[/dim]")
        
        # Verify the message went to stderr
        stderr_output = stderr_capture.getvalue()
        assert "Filtered 10 forks: 5 included" in stderr_output
        assert "private excluded" in stderr_output
        assert "no commits excluded" in stderr_output

    def test_filtering_message_goes_to_stdout_in_non_csv_mode(self):
        """Test that filtering messages go to stdout in non-CSV mode."""
        # Create mock objects
        mock_github_client = Mock()
        
        # Create stdout capture
        stdout_capture = StringIO()
        
        # Create a repository display service with captured stdout
        service = RepositoryDisplayService(
            github_client=mock_github_client,
            console=Console(file=stdout_capture, width=80)
        )
        
        # Create a mock filter result with exclusions
        filter_result = Mock(spec=FilteredForkResult)
        filter_result.total_excluded = 3
        filter_result.exclusion_summary = "Filtered 8 forks: 5 included, 1 private excluded, 2 no commits excluded"
        
        # Simulate the filtering message print in non-CSV mode
        if False:  # csv_export = False
            pass  # This branch won't execute
        else:
            service.console.print(f"[dim]{filter_result.exclusion_summary}[/dim]")
        
        # Verify the message went to stdout (the service's console)
        stdout_output = stdout_capture.getvalue()
        assert "Filtered 8 forks: 5 included" in stdout_output
        assert "private excluded" in stdout_output
        assert "no commits excluded" in stdout_output

    def test_no_filtering_message_when_no_exclusions(self):
        """Test that no filtering message appears when no forks are excluded."""
        # Create mock objects
        mock_github_client = Mock()
        
        # Create a repository display service
        service = RepositoryDisplayService(
            github_client=mock_github_client,
            console=Console(file=StringIO(), width=80)
        )
        
        # Create a mock filter result with no exclusions
        filter_result = Mock(spec=FilteredForkResult)
        filter_result.total_excluded = 0
        filter_result.exclusion_summary = "Filtered 5 forks: 5 included, 0 private excluded, 0 no commits excluded"
        
        # Capture stderr
        stderr_capture = StringIO()
        
        with patch('sys.stderr', stderr_capture):
            # Simulate the condition check
            if filter_result.total_excluded > 0:
                # This should not execute
                stderr_console = Console(file=sys.stderr, soft_wrap=False, width=400)
                stderr_console.print(f"[dim]{filter_result.exclusion_summary}[/dim]")
        
        # Verify no message was printed
        stderr_output = stderr_capture.getvalue()
        assert stderr_output == ""