"""
Tests for wittrans

SPDX-FileCopyrightText: 2024 Jiri Grönroos <jiri.gronroos@iki.fi>

SPDX-License-Identifier: LGPL-3.0-or-later
"""

import sys
from pathlib import Path
from unittest.mock import MagicMock, patch

import pytest

from wittrans.exceptions import InvalidLanguageCode, TranslationDirectoryNotFound
from wittrans.main import main
from wittrans.models import TranslationPaths


@pytest.fixture
def mock_console():
    """Create a mock Rich Console."""
    console = MagicMock()
    console.print = MagicMock()
    return console


@pytest.fixture
def mock_progress():
    """Create a mock Rich Progress context manager."""
    progress = MagicMock()
    progress.__enter__ = MagicMock(return_value=progress)
    progress.__exit__ = MagicMock(return_value=None)
    return progress


@pytest.fixture
def sample_translation_paths():
    """Create sample TranslationPaths for testing."""
    return TranslationPaths(
        system_locale=[Path("/usr/share/locale/fi/LC_MESSAGES")],
        user_locale=[],
        system_gnome_extensions=[],
        system_kde_plasmoids=[],
        user_gnome_extensions=[],
        user_kde_plasmoids=[],
        system_flatpak=[],
        user_flatpak=[],
    )


class TestMainBasicExecution:
    """Tests for basic main() execution flow."""

    def test_main_successful_search_with_results(
        self, monkeypatch, mock_console, mock_progress, sample_translation_paths
    ):
        """Test successful search that finds results."""
        # Mock command line arguments
        monkeypatch.setattr(sys, "argv", ["wittrans", "hello", "fi"])

        # Mock all the function calls
        with patch("wittrans.main.Console", return_value=mock_console):
            with patch("wittrans.main.check_platform"):
                with patch("wittrans.main.parse_arguments") as mock_parse:
                    with patch(
                        "wittrans.main.validate_language_paths",
                        return_value=sample_translation_paths,
                    ):
                        with patch(
                            "wittrans.main.Progress", return_value=mock_progress
                        ):
                            with patch("wittrans.main.search_directory") as mock_search:
                                with patch(
                                    "wittrans.main.display_results"
                                ) as mock_display:
                                    # Setup mocks
                                    args = MagicMock()
                                    args.search_term = "hello"
                                    args.language_code = "fi"
                                    args.no_flatpak = False
                                    args.translation = False
                                    args.source = False
                                    args.whole_word = False
                                    args.indicate = False
                                    args.output = None
                                    args.all = False
                                    mock_parse.return_value = args

                                    # Mock search results
                                    mock_search.return_value = (
                                        [
                                            (
                                                Path("/test/file.mo"),
                                                [("Hello", "Terve", None)],
                                            )
                                        ],
                                        1,
                                    )

                                    # Run main
                                    main()

                                    # Verify search was called
                                    assert mock_search.called
                                    # Verify results were displayed
                                    assert mock_display.called

    def test_main_successful_search_no_results(
        self, monkeypatch, mock_console, mock_progress, sample_translation_paths
    ):
        """Test successful search that finds no results."""
        monkeypatch.setattr(sys, "argv", ["wittrans", "nonexistent", "fi"])

        with patch("wittrans.main.Console", return_value=mock_console):
            with patch("wittrans.main.check_platform"):
                with patch("wittrans.main.parse_arguments") as mock_parse:
                    with patch(
                        "wittrans.main.validate_language_paths",
                        return_value=sample_translation_paths,
                    ):
                        with patch(
                            "wittrans.main.Progress", return_value=mock_progress
                        ):
                            with patch(
                                "wittrans.main.search_directory", return_value=([], 0)
                            ):
                                with pytest.raises(SystemExit) as exc_info:
                                    args = MagicMock()
                                    args.search_term = "nonexistent"
                                    args.language_code = "fi"
                                    args.no_flatpak = False
                                    args.translation = False
                                    args.source = False
                                    args.whole_word = False
                                    args.output = None
                                    args.all = False
                                    mock_parse.return_value = args

                                    main()

                                # Should exit with code 0
                                assert exc_info.value.code == 0
                                # Should print "No matches found" message
                                assert mock_console.print.called


class TestMainCommandLineOptions:
    """Tests for different command-line option combinations."""

    def test_main_with_source_only_flag(
        self, monkeypatch, mock_console, mock_progress, sample_translation_paths
    ):
        """Test main with -s/--source flag."""
        monkeypatch.setattr(sys, "argv", ["wittrans", "hello", "fi", "-s"])

        with patch("wittrans.main.Console", return_value=mock_console):
            with patch("wittrans.main.check_platform"):
                with patch("wittrans.main.parse_arguments") as mock_parse:
                    with patch(
                        "wittrans.main.validate_language_paths",
                        return_value=sample_translation_paths,
                    ):
                        with patch(
                            "wittrans.main.Progress", return_value=mock_progress
                        ):
                            with patch("wittrans.main.search_directory") as mock_search:
                                with patch("wittrans.main.display_results"):
                                    args = MagicMock()
                                    args.search_term = "hello"
                                    args.language_code = "fi"
                                    args.no_flatpak = False
                                    args.translation = False
                                    args.source = True  # Source only
                                    args.whole_word = False
                                    args.indicate = False
                                    args.output = None
                                    args.all = False
                                    mock_parse.return_value = args

                                    mock_search.return_value = (
                                        [
                                            (
                                                Path("/test/file.mo"),
                                                [("Hello", "Terve", None)],
                                            )
                                        ],
                                        1,
                                    )

                                    main()

                                    # Verify search_directory was called with correct parameters
                                    mock_search.assert_called()
                                    call_kwargs = mock_search.call_args[1]
                                    assert call_kwargs["search_source"] is True
                                    assert call_kwargs["search_translation"] is False

    def test_main_with_translation_only_flag(
        self, monkeypatch, mock_console, mock_progress, sample_translation_paths
    ):
        """Test main with -t/--translation flag."""
        monkeypatch.setattr(sys, "argv", ["wittrans", "hello", "fi", "-t"])

        with patch("wittrans.main.Console", return_value=mock_console):
            with patch("wittrans.main.check_platform"):
                with patch("wittrans.main.parse_arguments") as mock_parse:
                    with patch(
                        "wittrans.main.validate_language_paths",
                        return_value=sample_translation_paths,
                    ):
                        with patch(
                            "wittrans.main.Progress", return_value=mock_progress
                        ):
                            with patch("wittrans.main.search_directory") as mock_search:
                                with patch("wittrans.main.display_results"):
                                    args = MagicMock()
                                    args.search_term = "hello"
                                    args.language_code = "fi"
                                    args.no_flatpak = False
                                    args.translation = True  # Translation only
                                    args.source = False
                                    args.whole_word = False
                                    args.indicate = False
                                    args.output = None
                                    args.all = False
                                    mock_parse.return_value = args

                                    mock_search.return_value = (
                                        [
                                            (
                                                Path("/test/file.mo"),
                                                [("Hello", "Terve", None)],
                                            )
                                        ],
                                        1,
                                    )

                                    main()

                                    # Verify search_directory was called with correct parameters
                                    call_kwargs = mock_search.call_args[1]
                                    assert call_kwargs["search_source"] is False
                                    assert call_kwargs["search_translation"] is True

    def test_main_with_whole_word_flag(
        self, monkeypatch, mock_console, mock_progress, sample_translation_paths
    ):
        """Test main with -w/--whole-word flag."""
        monkeypatch.setattr(sys, "argv", ["wittrans", "day", "fi", "-w"])

        with patch("wittrans.main.Console", return_value=mock_console):
            with patch("wittrans.main.check_platform"):
                with patch("wittrans.main.parse_arguments") as mock_parse:
                    with patch(
                        "wittrans.main.validate_language_paths",
                        return_value=sample_translation_paths,
                    ):
                        with patch(
                            "wittrans.main.Progress", return_value=mock_progress
                        ):
                            with patch("wittrans.main.search_directory") as mock_search:
                                with patch("wittrans.main.display_results"):
                                    args = MagicMock()
                                    args.search_term = "day"
                                    args.language_code = "fi"
                                    args.no_flatpak = False
                                    args.translation = False
                                    args.source = False
                                    args.whole_word = True  # Whole word
                                    args.indicate = False
                                    args.output = None
                                    args.all = False
                                    mock_parse.return_value = args

                                    mock_search.return_value = (
                                        [
                                            (
                                                Path("/test/file.mo"),
                                                [("day", "päivä", None)],
                                            )
                                        ],
                                        1,  # mo_file_count
                                    )

                                    main()

                                    # Verify whole_word parameter was passed
                                    call_kwargs = mock_search.call_args[1]
                                    assert call_kwargs["whole_word"] is True

    def test_main_with_no_flatpak_flag(self, monkeypatch, mock_console, mock_progress):
        """Test main with -f/--no-flatpak flag."""
        monkeypatch.setattr(sys, "argv", ["wittrans", "hello", "fi", "-f"])

        with patch("wittrans.main.Console", return_value=mock_console):
            with patch("wittrans.main.check_platform"):
                with patch("wittrans.main.parse_arguments") as mock_parse:
                    with patch(
                        "wittrans.main.validate_language_paths"
                    ) as mock_validate:
                        with patch(
                            "wittrans.main.Progress", return_value=mock_progress
                        ):
                            with patch(
                                "wittrans.main.search_directory", return_value=([], 0)
                            ):
                                with pytest.raises(SystemExit):
                                    args = MagicMock()
                                    args.search_term = "hello"
                                    args.language_code = "fi"
                                    args.no_flatpak = True  # Skip Flatpak
                                    args.translation = False
                                    args.source = False
                                    args.whole_word = False
                                    args.output = None
                                    args.all = False
                                    mock_parse.return_value = args

                                    mock_validate.return_value = TranslationPaths(
                                        system_locale=[
                                            Path("/usr/share/locale/fi/LC_MESSAGES")
                                        ],
                                        user_locale=[],
                                        system_gnome_extensions=[],
                                        system_kde_plasmoids=[],
                                        user_gnome_extensions=[],
                                        user_kde_plasmoids=[],
                                        system_flatpak=[],
                                        user_flatpak=[],
                                    )

                                    main()

                                    # Verify validate_language_paths was called with include_flatpak=False
                                    mock_validate.assert_called_with(
                                        "fi", include_flatpak=False
                                    )

    def test_main_with_indicate_flag(
        self, monkeypatch, mock_console, mock_progress, sample_translation_paths
    ):
        """Test main with -i/--indicate flag for highlighting."""
        monkeypatch.setattr(sys, "argv", ["wittrans", "hello", "fi", "-i"])

        with patch("wittrans.main.Console", return_value=mock_console):
            with patch("wittrans.main.check_platform"):
                with patch("wittrans.main.parse_arguments") as mock_parse:
                    with patch(
                        "wittrans.main.validate_language_paths",
                        return_value=sample_translation_paths,
                    ):
                        with patch(
                            "wittrans.main.Progress", return_value=mock_progress
                        ):
                            with patch("wittrans.main.search_directory") as mock_search:
                                with patch(
                                    "wittrans.main.display_results"
                                ) as mock_display:
                                    args = MagicMock()
                                    args.search_term = "hello"
                                    args.language_code = "fi"
                                    args.no_flatpak = False
                                    args.translation = False
                                    args.source = False
                                    args.whole_word = False
                                    args.indicate = True  # Highlight matches
                                    args.output = None
                                    args.all = False
                                    mock_parse.return_value = args

                                    mock_search.return_value = (
                                        [
                                            (
                                                Path("/test/file.mo"),
                                                [("Hello", "Terve", None)],
                                            )
                                        ],
                                        1,
                                    )

                                    main()

                                    # Verify display_results was called with indicate=True
                                    mock_display.assert_called()
                                    call_args = mock_display.call_args[0]
                                    assert (
                                        call_args[4] is True
                                    )  # Fifth argument is indicate


class TestMainTSVOutput:
    """Tests for TSV output functionality."""

    def test_main_tsv_output_with_results(
        self, monkeypatch, mock_console, mock_progress, sample_translation_paths
    ):
        """Test TSV output when results are found."""
        monkeypatch.setattr(sys, "argv", ["wittrans", "hello", "fi", "-o", "tsv"])

        with patch("wittrans.main.Console", return_value=mock_console):
            with patch("wittrans.main.check_platform"):
                with patch("wittrans.main.parse_arguments") as mock_parse:
                    with patch(
                        "wittrans.main.validate_language_paths",
                        return_value=sample_translation_paths,
                    ):
                        with patch(
                            "wittrans.main.Progress", return_value=mock_progress
                        ):
                            with patch("wittrans.main.search_directory") as mock_search:
                                with patch(
                                    "wittrans.main.write_tsv_output"
                                ) as mock_write_tsv:
                                    with pytest.raises(SystemExit) as exc_info:
                                        args = MagicMock()
                                        args.search_term = "hello"
                                        args.language_code = "fi"
                                        args.no_flatpak = False
                                        args.translation = False
                                        args.source = False
                                        args.whole_word = False
                                        args.output = "tsv"
                                        args.output_file = None
                                        args.all = False
                                        mock_parse.return_value = args

                                        mock_search.return_value = (
                                            [
                                                (
                                                    Path("/test/file.mo"),
                                                    [("Hello", "Terve", None)],
                                                )
                                            ],
                                            1,
                                        )

                                        main()

                                    # Verify exit code (must be 0)
                                    assert exc_info.value.code == 0
                                    # Verify write_tsv_output was called
                                    assert mock_write_tsv.called
                                    # Verify success message was printed
                                    assert mock_console.print.called

    def test_main_tsv_output_with_custom_filename(
        self, monkeypatch, mock_console, mock_progress, sample_translation_paths
    ):
        """Test TSV output with custom filename."""
        monkeypatch.setattr(
            sys,
            "argv",
            ["wittrans", "hello", "fi", "-o", "tsv", "--output-file", "custom.tsv"],
        )

        with patch("wittrans.main.Console", return_value=mock_console):
            with patch("wittrans.main.check_platform"):
                with patch("wittrans.main.parse_arguments") as mock_parse:
                    with patch(
                        "wittrans.main.validate_language_paths",
                        return_value=sample_translation_paths,
                    ):
                        with patch(
                            "wittrans.main.Progress", return_value=mock_progress
                        ):
                            with patch("wittrans.main.search_directory") as mock_search:
                                with patch(
                                    "wittrans.main.write_tsv_output"
                                ) as mock_write_tsv:
                                    with pytest.raises(SystemExit) as exc_info:
                                        args = MagicMock()
                                        args.search_term = "hello"
                                        args.language_code = "fi"
                                        args.no_flatpak = False
                                        args.translation = False
                                        args.source = False
                                        args.whole_word = False
                                        args.output = "tsv"
                                        args.output_file = "custom.tsv"
                                        args.all = False
                                        mock_parse.return_value = args

                                        mock_search.return_value = (
                                            [
                                                (
                                                    Path("/test/file.mo"),
                                                    [("Hello", "Terve", None)],
                                                )
                                            ],
                                            1,
                                        )

                                        main()

                                    assert exc_info.value.code == 0
                                    # Verify write_tsv_output was called with custom filename
                                    call_args = mock_write_tsv.call_args[0]
                                    assert call_args[3] == "custom.tsv"

    def test_main_tsv_output_no_results(
        self, monkeypatch, mock_console, mock_progress, sample_translation_paths
    ):
        """Test TSV output when no results are found."""
        monkeypatch.setattr(sys, "argv", ["wittrans", "nonexistent", "fi", "-o", "tsv"])

        with patch("wittrans.main.Console", return_value=mock_console):
            with patch("wittrans.main.check_platform"):
                with patch("wittrans.main.parse_arguments") as mock_parse:
                    with patch(
                        "wittrans.main.validate_language_paths",
                        return_value=sample_translation_paths,
                    ):
                        with patch(
                            "wittrans.main.Progress", return_value=mock_progress
                        ):
                            with patch(
                                "wittrans.main.search_directory", return_value=([], 0)
                            ):
                                with patch(
                                    "wittrans.main.write_tsv_output"
                                ) as mock_write_tsv:
                                    with pytest.raises(SystemExit) as exc_info:
                                        args = MagicMock()
                                        args.search_term = "nonexistent"
                                        args.language_code = "fi"
                                        args.no_flatpak = False
                                        args.translation = False
                                        args.source = False
                                        args.whole_word = False
                                        args.output = "tsv"
                                        args.output_file = None
                                        args.all = False
                                        mock_parse.return_value = args

                                        main()

                                    # Should exit with 0
                                    assert exc_info.value.code == 0
                                    # Should still write empty TSV
                                    assert mock_write_tsv.called


class TestMainErrorHandling:
    """Tests for error handling in main()."""

    def test_main_invalid_language_code(self, monkeypatch, mock_console):
        """Test main with invalid language code."""
        monkeypatch.setattr(sys, "argv", ["wittrans", "hello", "invalid123"])

        with patch("wittrans.main.Console", return_value=mock_console):
            with patch("wittrans.main.check_platform"):
                with patch("wittrans.main.parse_arguments") as mock_parse:
                    with patch(
                        "wittrans.main.validate_language_paths"
                    ) as mock_validate:
                        with pytest.raises(SystemExit) as exc_info:
                            args = MagicMock()
                            args.search_term = "hello"
                            args.language_code = "invalid123"
                            args.no_flatpak = False
                            args.all = False
                            mock_parse.return_value = args

                            # Simulate InvalidLanguageCode exception
                            mock_validate.side_effect = InvalidLanguageCode(
                                "Invalid language code: 'invalid123'"
                            )

                            main()

                        # Should exit with code 1
                        assert exc_info.value.code == 1
                        # Should print error panel
                        assert mock_console.print.called

    def test_main_translation_directory_not_found(self, monkeypatch, mock_console):
        """Test main when translation directory is not found."""
        monkeypatch.setattr(sys, "argv", ["wittrans", "hello", "xyz"])

        with patch("wittrans.main.Console", return_value=mock_console):
            with patch("wittrans.main.check_platform"):
                with patch("wittrans.main.parse_arguments") as mock_parse:
                    with patch(
                        "wittrans.main.validate_language_paths"
                    ) as mock_validate:
                        with pytest.raises(SystemExit) as exc_info:
                            args = MagicMock()
                            args.search_term = "hello"
                            args.language_code = "xyz"
                            args.no_flatpak = False
                            args.all = False
                            mock_parse.return_value = args

                            # Simulate TranslationDirectoryNotFound exception
                            mock_validate.side_effect = TranslationDirectoryNotFound(
                                "No translation directories found"
                            )

                            main()

                        # Should exit with code 1
                        assert exc_info.value.code == 1
                        # Should print error panel
                        assert mock_console.print.called

    def test_main_keyboard_interrupt(
        self, monkeypatch, mock_console, mock_progress, sample_translation_paths
    ):
        """Test main handles KeyboardInterrupt (Ctrl+C)."""
        monkeypatch.setattr(sys, "argv", ["wittrans", "hello", "fi"])

        with patch("wittrans.main.Console", return_value=mock_console):
            with patch("wittrans.main.check_platform"):
                with patch("wittrans.main.parse_arguments") as mock_parse:
                    with patch(
                        "wittrans.main.validate_language_paths",
                        return_value=sample_translation_paths,
                    ):
                        with patch(
                            "wittrans.main.Progress", return_value=mock_progress
                        ):
                            with patch("wittrans.main.search_directory") as mock_search:
                                with pytest.raises(SystemExit) as exc_info:
                                    args = MagicMock()
                                    args.search_term = "hello"
                                    args.language_code = "fi"
                                    args.no_flatpak = False
                                    args.translation = False
                                    args.source = False
                                    args.whole_word = False
                                    args.all = False
                                    mock_parse.return_value = args

                                    # Simulate KeyboardInterrupt
                                    mock_search.side_effect = KeyboardInterrupt()

                                    main()

                                # Should exit with code 0
                                assert exc_info.value.code == 0
                                # Should print cancellation message
                                assert mock_console.print.called

    def test_main_unexpected_exception(
        self, monkeypatch, mock_console, mock_progress, sample_translation_paths
    ):
        """Test main handles unexpected exceptions."""
        monkeypatch.setattr(sys, "argv", ["wittrans", "hello", "fi"])

        with patch("wittrans.main.Console", return_value=mock_console):
            with patch("wittrans.main.check_platform"):
                with patch("wittrans.main.parse_arguments") as mock_parse:
                    with patch(
                        "wittrans.main.validate_language_paths",
                        return_value=sample_translation_paths,
                    ):
                        with patch(
                            "wittrans.main.Progress", return_value=mock_progress
                        ):
                            with patch("wittrans.main.search_directory") as mock_search:
                                with pytest.raises(SystemExit) as exc_info:
                                    args = MagicMock()
                                    args.search_term = "hello"
                                    args.language_code = "fi"
                                    args.no_flatpak = False
                                    args.translation = False
                                    args.source = False
                                    args.whole_word = False
                                    args.all = False
                                    mock_parse.return_value = args

                                    # Simulate unexpected exception
                                    mock_search.side_effect = RuntimeError(
                                        "Unexpected error"
                                    )

                                    main()

                                # Should exit with code 1
                                assert exc_info.value.code == 1
                                # Should print error panel
                                assert mock_console.print.called


class TestMainMultipleCategories:
    """Tests for searching across multiple translation categories."""

    def test_main_searches_all_categories(
        self, monkeypatch, mock_console, mock_progress
    ):
        """Test that main searches all translation categories."""
        monkeypatch.setattr(sys, "argv", ["wittrans", "hello", "fi"])

        # Paths with multiple categories
        all_paths = TranslationPaths(
            system_locale=[Path("/usr/share/locale/fi/LC_MESSAGES")],
            user_locale=[Path("/home/user/.local/share/locale/fi/LC_MESSAGES")],
            system_gnome_extensions=[
                Path("/usr/share/gnome-shell/extensions/ext/locale/fi/LC_MESSAGES")
            ],
            system_kde_plasmoids=[],
            user_gnome_extensions=[],
            user_kde_plasmoids=[],
            system_flatpak=[
                Path(
                    "/var/lib/flatpak/app/org.app/x86_64/stable/active/files/share/locale/fi/LC_MESSAGES"
                )
            ],
            user_flatpak=[],
        )

        with patch("wittrans.main.Console", return_value=mock_console):
            with patch("wittrans.main.check_platform"):
                with patch("wittrans.main.parse_arguments") as mock_parse:
                    with patch(
                        "wittrans.main.validate_language_paths", return_value=all_paths
                    ):
                        with patch(
                            "wittrans.main.Progress", return_value=mock_progress
                        ):
                            with patch("wittrans.main.search_directory") as mock_search:
                                with patch("wittrans.main.display_results"):
                                    args = MagicMock()
                                    args.search_term = "hello"
                                    args.language_code = "fi"
                                    args.no_flatpak = False
                                    args.translation = False
                                    args.source = False
                                    args.whole_word = False
                                    args.indicate = False
                                    args.output = None
                                    args.all = False
                                    mock_parse.return_value = args

                                    mock_search.return_value = (
                                        [
                                            (
                                                Path("/test/file.mo"),
                                                [("Hello", "Terve", None)],
                                            )
                                        ],
                                        1,
                                    )

                                    main()

                                    # Should call search_directory for each path
                                    # There are 4 paths with content
                                    assert mock_search.call_count == 4

    def test_main_displays_results_by_category(
        self, monkeypatch, mock_console, mock_progress
    ):
        """Test that results are displayed grouped by category."""
        monkeypatch.setattr(sys, "argv", ["wittrans", "hello", "fi"])

        all_paths = TranslationPaths(
            system_locale=[Path("/usr/share/locale/fi/LC_MESSAGES")],
            user_locale=[Path("/home/user/.local/share/locale/fi/LC_MESSAGES")],
            system_gnome_extensions=[],
            system_kde_plasmoids=[],
            user_gnome_extensions=[],
            user_kde_plasmoids=[],
            system_flatpak=[],
            user_flatpak=[],
        )

        with patch("wittrans.main.Console", return_value=mock_console):
            with patch("wittrans.main.check_platform"):
                with patch("wittrans.main.parse_arguments") as mock_parse:
                    with patch(
                        "wittrans.main.validate_language_paths", return_value=all_paths
                    ):
                        with patch(
                            "wittrans.main.Progress", return_value=mock_progress
                        ):
                            with patch("wittrans.main.search_directory") as mock_search:
                                with patch(
                                    "wittrans.main.display_results"
                                ) as mock_display:
                                    args = MagicMock()
                                    args.search_term = "hello"
                                    args.language_code = "fi"
                                    args.no_flatpak = False
                                    args.translation = False
                                    args.source = False
                                    args.whole_word = False
                                    args.indicate = False
                                    args.output = None
                                    args.all = False
                                    mock_parse.return_value = args

                                    mock_search.return_value = (
                                        [
                                            (
                                                Path("/test/file.mo"),
                                                [("Hello", "Terve", None)],
                                            )
                                        ],
                                        1,
                                    )

                                    main()

                                    # Call display_results for each category with results
                                    assert mock_display.call_count >= 1
                                    # Verify category names are passed
                                    call_args = mock_display.call_args_list[0][0]
                                    # Third argument should be category display name
                                    assert isinstance(call_args[3], str)


class TestMainAllFlag:
    """Tests for --all flag functionality in main()."""

    def test_main_all_flag_with_tsv_output(
        self, monkeypatch, mock_console, mock_progress, sample_translation_paths
    ):
        """Test --all flag with TSV output."""
        monkeypatch.setattr(sys, "argv", ["wittrans", "--all", "fi", "-o", "tsv"])

        with patch("wittrans.main.Console", return_value=mock_console):
            with patch("wittrans.main.check_platform"):
                with patch("wittrans.main.parse_arguments") as mock_parse:
                    with patch(
                        "wittrans.main.validate_language_paths",
                        return_value=sample_translation_paths,
                    ):
                        with patch(
                            "wittrans.main.Progress", return_value=mock_progress
                        ):
                            with patch("wittrans.main.search_directory") as mock_search:
                                with patch(
                                    "wittrans.main.write_tsv_output"
                                ) as mock_write_tsv:
                                    with pytest.raises(SystemExit) as exc_info:
                                        args = MagicMock()
                                        args.search_term = ""  # Must be empty for --all
                                        args.language_code = "fi"
                                        args.no_flatpak = False
                                        args.translation = False
                                        args.source = False
                                        args.whole_word = False
                                        args.output = "tsv"
                                        args.output_file = None
                                        args.all = True
                                        mock_parse.return_value = args

                                        # Mock returning all translations
                                        mock_search.return_value = (
                                            [
                                                (
                                                    Path("/test/file.mo"),
                                                    [
                                                        ("Hello", "Terve", None),
                                                        ("Goodbye", "Näkemiin", None),
                                                        ("Yes", "Kyllä", None),
                                                    ],
                                                )
                                            ],
                                            1,
                                        )

                                        main()

                                    # Should exit with 0
                                    assert exc_info.value.code == 0
                                    # Call search_directory with empty search term
                                    mock_search.assert_called()
                                    call_args = mock_search.call_args[0]
                                    assert call_args[1] == ""  # search_term is empty
                                    # Write TSV
                                    assert mock_write_tsv.called

    def test_main_all_flag_searches_everything(
        self, monkeypatch, mock_console, mock_progress, sample_translation_paths
    ):
        """Test that --all flag searches with empty string (matches all)."""
        monkeypatch.setattr(sys, "argv", ["wittrans", "--all", "fi", "-o", "tsv"])

        with patch("wittrans.main.Console", return_value=mock_console):
            with patch("wittrans.main.check_platform"):
                with patch("wittrans.main.parse_arguments") as mock_parse:
                    with patch(
                        "wittrans.main.validate_language_paths",
                        return_value=sample_translation_paths,
                    ):
                        with patch(
                            "wittrans.main.Progress", return_value=mock_progress
                        ):
                            with patch("wittrans.main.search_directory") as mock_search:
                                with patch("wittrans.main.write_tsv_output"):
                                    with pytest.raises(SystemExit):
                                        args = MagicMock()
                                        args.search_term = ""
                                        args.language_code = "fi"
                                        args.no_flatpak = False
                                        args.translation = False
                                        args.source = False
                                        args.whole_word = False
                                        args.output = "tsv"
                                        args.output_file = None
                                        args.all = True
                                        mock_parse.return_value = args

                                        mock_search.return_value = ([], 0)

                                        main()

                                    # Verify search_directory called with empty string
                                    assert mock_search.called
                                    search_term_arg = mock_search.call_args[0][1]
                                    assert search_term_arg == ""

    def test_main_all_flag_with_source_only(
        self, monkeypatch, mock_console, mock_progress, sample_translation_paths
    ):
        """Test --all flag combined with -s (source only)."""
        monkeypatch.setattr(sys, "argv", ["wittrans", "--all", "fi", "-o", "tsv", "-s"])

        with patch("wittrans.main.Console", return_value=mock_console):
            with patch("wittrans.main.check_platform"):
                with patch("wittrans.main.parse_arguments") as mock_parse:
                    with patch(
                        "wittrans.main.validate_language_paths",
                        return_value=sample_translation_paths,
                    ):
                        with patch(
                            "wittrans.main.Progress", return_value=mock_progress
                        ):
                            with patch("wittrans.main.search_directory") as mock_search:
                                with patch("wittrans.main.write_tsv_output"):
                                    with pytest.raises(SystemExit):
                                        args = MagicMock()
                                        args.search_term = ""
                                        args.language_code = "fi"
                                        args.no_flatpak = False
                                        args.translation = False
                                        args.source = True
                                        args.whole_word = False
                                        args.output = "tsv"
                                        args.output_file = None
                                        args.all = True
                                        mock_parse.return_value = args

                                        mock_search.return_value = ([], 0)

                                        main()

                                    # Verify search_source=True, search_translation=False
                                    call_kwargs = mock_search.call_args[1]
                                    assert call_kwargs["search_source"] is True
                                    assert call_kwargs["search_translation"] is False

    def test_main_all_flag_with_no_flatpak(
        self, monkeypatch, mock_console, mock_progress, sample_translation_paths
    ):
        """Test --all flag combined with --no-flatpak."""
        monkeypatch.setattr(
            sys, "argv", ["wittrans", "--all", "fi", "-o", "tsv", "--no-flatpak"]
        )

        with patch("wittrans.main.Console", return_value=mock_console):
            with patch("wittrans.main.check_platform"):
                with patch("wittrans.main.parse_arguments") as mock_parse:
                    with patch(
                        "wittrans.main.validate_language_paths"
                    ) as mock_validate:
                        with patch(
                            "wittrans.main.Progress", return_value=mock_progress
                        ):
                            with patch(
                                "wittrans.main.search_directory", return_value=([], 0)
                            ):
                                with patch("wittrans.main.write_tsv_output"):
                                    with pytest.raises(SystemExit):
                                        args = MagicMock()
                                        args.search_term = ""
                                        args.language_code = "fi"
                                        args.no_flatpak = True
                                        args.translation = False
                                        args.source = False
                                        args.whole_word = False
                                        args.output = "tsv"
                                        args.output_file = None
                                        args.all = True
                                        mock_parse.return_value = args

                                        mock_validate.return_value = (
                                            sample_translation_paths
                                        )

                                        main()

                                    # Verify include_flatpak=False
                                    mock_validate.assert_called_with(
                                        "fi", include_flatpak=False
                                    )

    def test_main_all_flag_with_custom_output_file(
        self, monkeypatch, mock_console, mock_progress, sample_translation_paths
    ):
        """Test --all flag with custom output filename."""
        monkeypatch.setattr(
            sys,
            "argv",
            [
                "wittrans",
                "--all",
                "fi",
                "-o",
                "tsv",
                "--output-file",
                "all_finnish.tsv",
            ],
        )

        with patch("wittrans.main.Console", return_value=mock_console):
            with patch("wittrans.main.check_platform"):
                with patch("wittrans.main.parse_arguments") as mock_parse:
                    with patch(
                        "wittrans.main.validate_language_paths",
                        return_value=sample_translation_paths,
                    ):
                        with patch(
                            "wittrans.main.Progress", return_value=mock_progress
                        ):
                            with patch(
                                "wittrans.main.search_directory", return_value=([], 0)
                            ):
                                with patch(
                                    "wittrans.main.write_tsv_output"
                                ) as mock_write_tsv:
                                    with pytest.raises(SystemExit):
                                        args = MagicMock()
                                        args.search_term = ""
                                        args.language_code = "fi"
                                        args.no_flatpak = False
                                        args.translation = False
                                        args.source = False
                                        args.whole_word = False
                                        args.output = "tsv"
                                        args.output_file = "all_finnish.tsv"
                                        args.all = True
                                        mock_parse.return_value = args

                                        main()

                                    # Verify custom filename
                                    call_args = mock_write_tsv.call_args[0]
                                    assert call_args[3] == "all_finnish.tsv"
