"""Tests for the Gitingest CLI."""

from __future__ import annotations

from inspect import signature
from pathlib import Path

import pytest
from click.testing import CliRunner, Result

from gitingest.__main__ import main
from gitingest.config import MAX_FILE_SIZE, OUTPUT_FILE_NAME


@pytest.mark.parametrize(
    ("cli_args", "expect_file"),
    [
        pytest.param(["./"], True, id="default-options"),
        pytest.param(
            [
                "./",
                "--output",
                str(OUTPUT_FILE_NAME),
                "--max-size",
                str(MAX_FILE_SIZE),
                "--exclude-pattern",
                "tests/",
                "--include-pattern",
                "src/",
                "--include-submodules",
            ],
            True,
            id="custom-options",
        ),
    ],
)
def test_cli_writes_file(
    tmp_path: Path,
    monkeypatch: pytest.MonkeyPatch,
    *,
    cli_args: list[str],
    expect_file: bool,
) -> None:
    """Run the CLI and verify that the SARIF file is created (or not)."""
    expectes_exit_code = 0
    # Work inside an isolated temp directory
    monkeypatch.chdir(tmp_path)

    result = _invoke_isolated_cli_runner(cli_args)

    assert result.exit_code == expectes_exit_code, result.stderr

    # Summary line should be on STDOUT
    stdout_lines = result.stdout.splitlines()
    assert f"Analysis complete! Output written to: {OUTPUT_FILE_NAME}" in stdout_lines

    # File side-effect
    sarif_file = tmp_path / OUTPUT_FILE_NAME
    assert sarif_file.exists() is expect_file, f"{OUTPUT_FILE_NAME} existence did not match expectation"


def test_cli_with_stdout_output() -> None:
    """Test CLI invocation with output directed to STDOUT."""
    output_file = Path(OUTPUT_FILE_NAME)
    # Clean up any existing digest.txt file before test
    if output_file.exists():
        output_file.unlink()

    try:
        result = _invoke_isolated_cli_runner(["./", "--output", "-", "--exclude-pattern", "tests/"])

        # ─── core expectations (stdout) ────────────────────────────────────-
        assert result.exit_code == 0, f"CLI exited with code {result.exit_code}, stderr: {result.stderr}"
        assert "---" in result.stdout, "Expected file separator '---' not found in STDOUT"
        assert "src/gitingest/__main__.py" in result.stdout, (
            "Expected content (e.g., src/gitingest/__main__.py) not found in STDOUT"
        )
        assert not output_file.exists(), f"Output file {output_file} was unexpectedly created."

        # ─── the summary must *not* pollute STDOUT, must appear on STDERR ───
        summary = "Analysis complete! Output sent to stdout."
        stdout_lines = result.stdout.splitlines()
        stderr_lines = result.stderr.splitlines()
        assert summary not in stdout_lines, "Unexpected summary message found in STDOUT"
        assert summary in stderr_lines, "Expected summary message not found in STDERR"
        assert f"Output written to: {output_file.name}" not in stderr_lines
    finally:
        # Clean up any digest.txt file that might have been created during test
        if output_file.exists():
            output_file.unlink()


def _invoke_isolated_cli_runner(args: list[str]) -> Result:
    """Return a ``CliRunner`` that keeps ``stderr`` separate on Click 8.0-8.1."""
    kwargs = {}
    if "mix_stderr" in signature(CliRunner.__init__).parameters:
        kwargs["mix_stderr"] = False  # Click 8.0-8.1
    runner = CliRunner(**kwargs)
    return runner.invoke(main, args)
