"""check_conflict_likelihood decision 분기 회귀 테스트."""

from __future__ import annotations

import subprocess
import sys
from pathlib import Path

import pytest

# workspace root → sys.path (기존 regression 테스트 패턴 준수)
_WORKSPACE = Path(__file__).resolve().parent.parent.parent.parent
if str(_WORKSPACE) in sys.path:
    sys.path.remove(str(_WORKSPACE))
sys.path.insert(0, str(_WORKSPACE))

from utils import main_conflict_preflight as mcp  # type: ignore[reportMissingImports] # noqa: E402


def _make_completed(
    args: list[str],
    returncode: int = 0,
    stdout: str = "",
    stderr: str = "",
) -> subprocess.CompletedProcess:
    return subprocess.CompletedProcess(
        args=args,
        returncode=returncode,
        stdout=stdout,
        stderr=stderr,
    )


def _build_fake_run(step_outputs: dict[str, subprocess.CompletedProcess]):
    """git 서브커맨드별 mock CompletedProcess 매핑."""

    def fake_run(args, **_kwargs):
        # _kwargs: cwd / capture_output / text / timeout (mock에서 검증 안 함)
        # args[0] == "git", args[1] == subcommand
        sub = args[1] if len(args) > 1 else ""
        if sub in step_outputs:
            return step_outputs[sub]
        return _make_completed(args, returncode=0, stdout="")

    return fake_run


def test_safe_when_no_intersection(monkeypatch: pytest.MonkeyPatch) -> None:
    step_outputs = {
        "fetch": _make_completed(["git", "fetch"], returncode=0),
        "ls-remote": _make_completed(
            ["git", "ls-remote"],
            returncode=0,
            stdout="abc123\trefs/heads/main\n",
        ),
        "rev-parse": _make_completed(
            ["git", "rev-parse"], returncode=0, stdout="abc123\n"
        ),
        "diff": _make_completed(
            ["git", "diff"], returncode=0, stdout="a\nb\n"
        ),
    }
    monkeypatch.setattr(
        mcp.subprocess, "run", _build_fake_run(step_outputs)
    )

    decision, evidence = mcp.check_conflict_likelihood(
        "/tmp/fake-worktree", ["c", "d"]
    )

    assert decision == "SAFE"
    assert evidence["fetch_ok"] is True
    assert evidence["diff_files"] == ["a", "b"]
    assert evidence["conflict_files"] == []
    assert evidence["remote_sha"] == "abc123"


def test_likely_conflict_when_intersection(
    monkeypatch: pytest.MonkeyPatch,
) -> None:
    step_outputs = {
        "fetch": _make_completed(["git", "fetch"], returncode=0),
        "ls-remote": _make_completed(
            ["git", "ls-remote"],
            returncode=0,
            stdout="deadbeef\trefs/heads/main\n",
        ),
        "rev-parse": _make_completed(
            ["git", "rev-parse"], returncode=0, stdout="deadbeef\n"
        ),
        "diff": _make_completed(
            ["git", "diff"], returncode=0, stdout="a\nb\nc\n"
        ),
    }
    monkeypatch.setattr(
        mcp.subprocess, "run", _build_fake_run(step_outputs)
    )

    decision, evidence = mcp.check_conflict_likelihood(
        "/tmp/fake-worktree", ["c", "d"]
    )

    assert decision == "LIKELY_CONFLICT"
    assert evidence["conflict_files"] == ["c"]
    assert "c" in evidence["diff_files"]


def test_abort_fetch_retry_when_fetch_fails(
    monkeypatch: pytest.MonkeyPatch,
) -> None:
    step_outputs = {
        "fetch": _make_completed(
            ["git", "fetch"],
            returncode=128,
            stderr="fatal: unable to access remote",
        ),
    }
    monkeypatch.setattr(
        mcp.subprocess, "run", _build_fake_run(step_outputs)
    )

    decision, evidence = mcp.check_conflict_likelihood(
        "/tmp/fake-worktree", ["c", "d"]
    )

    assert decision == "ABORT_FETCH_RETRY"
    assert evidence["fetch_ok"] is False
    assert "step1 fetch failed" in evidence["decision_reason"]
