"""
test_worktree_auto_fix_1993.py — _auto_fix_high_comments 수정사항 검증 (task-1993)

수정사항:
1. _auto_fix_high_comments(): ["claude", "--print", "-p", ...] →
   ["claude", "-p", ..., "--dangerously-skip-permissions"] 으로 변경
2. cmd_finish(): 타임아웃 시 60초 추가 대기 후 Gemini 리뷰 재확인 로직 추가
"""

import subprocess
import sys
import unittest.mock

# worktree_manager 임포트 경로 설정
sys.path.insert(0, "/home/jay/workspace")
sys.path.insert(0, "/home/jay/workspace/scripts")

from worktree_manager import _auto_fix_high_comments  # pyright: ignore[reportMissingImports]  # noqa: E402

# ---------------------------------------------------------------------------
# 공통 픽스처
# ---------------------------------------------------------------------------

SAMPLE_COMMENTS = [
    {
        "severity": "high",
        "path": "src/main.py",
        "line": "10",
        "body": "SQL injection vulnerability",
    }
]

FAKE_COMPLETED = subprocess.CompletedProcess(
    args=[], returncode=0, stdout="", stderr=""
)


# ---------------------------------------------------------------------------
# TC-1: --print 제거, --dangerously-skip-permissions 및 -p 추가 검증
# ---------------------------------------------------------------------------


class TestAutoFixClaudeCommand:
    """TC-1: _auto_fix_high_comments가 올바른 claude 인자로 호출되는지 검증."""

    def test_no_print_flag_in_subprocess_call(self):
        """--print 플래그가 subprocess.run 호출 인자에 없어야 한다."""
        with unittest.mock.patch(
            "worktree_manager.subprocess.run", return_value=FAKE_COMPLETED
        ) as mock_run:
            _auto_fix_high_comments(SAMPLE_COMMENTS, "/tmp/wt", collect_mode=False)

        # subprocess.run이 한 번 이상 호출되었는지 확인
        assert mock_run.called, "subprocess.run이 호출되지 않았습니다."

        # 모든 호출 인자를 평탄화하여 검사
        all_args: list[str] = []
        for call in mock_run.call_args_list:
            cmd = call.args[0] if call.args else call.kwargs.get("args", [])
            all_args.extend(cmd)

        assert "--print" not in all_args, (
            f"--print 플래그가 subprocess.run 인자에서 발견되었습니다: {all_args}"
        )

    def test_dangerously_skip_permissions_in_claude_call(self):
        """--dangerously-skip-permissions 플래그가 claude 호출 인자에 있어야 한다."""
        with unittest.mock.patch(
            "worktree_manager.subprocess.run", return_value=FAKE_COMPLETED
        ) as mock_run:
            _auto_fix_high_comments(SAMPLE_COMMENTS, "/tmp/wt", collect_mode=False)

        assert mock_run.called, "subprocess.run이 호출되지 않았습니다."

        # claude 명령에 해당하는 call을 찾아서 인자 검사
        claude_args: list[str] = []
        for call in mock_run.call_args_list:
            cmd = call.args[0] if call.args else call.kwargs.get("args", [])
            if cmd and cmd[0] == "claude":
                claude_args = cmd
                break

        assert claude_args, "claude를 실행하는 subprocess.run 호출을 찾을 수 없습니다."
        assert "--dangerously-skip-permissions" in claude_args, (
            f"--dangerously-skip-permissions가 claude 호출 인자에 없습니다: {claude_args}"
        )

    def test_p_flag_in_claude_call(self):
        """-p 플래그가 claude 호출 인자에 있어야 한다."""
        with unittest.mock.patch(
            "worktree_manager.subprocess.run", return_value=FAKE_COMPLETED
        ) as mock_run:
            _auto_fix_high_comments(SAMPLE_COMMENTS, "/tmp/wt", collect_mode=False)

        assert mock_run.called, "subprocess.run이 호출되지 않았습니다."

        claude_args: list[str] = []
        for call in mock_run.call_args_list:
            cmd = call.args[0] if call.args else call.kwargs.get("args", [])
            if cmd and cmd[0] == "claude":
                claude_args = cmd
                break

        assert claude_args, "claude를 실행하는 subprocess.run 호출을 찾을 수 없습니다."
        assert "-p" in claude_args, (
            f"-p 플래그가 claude 호출 인자에 없습니다: {claude_args}"
        )


# ---------------------------------------------------------------------------
# TC-2: collect_mode=True 시 claude 미실행 및 executed=False 검증
# ---------------------------------------------------------------------------


class TestAutoFixCollectMode:
    """TC-2: collect_mode=True 일 때 실행을 건너뛰는지 검증."""

    def test_subprocess_not_called_in_collect_mode(self):
        """collect_mode=True 이면 subprocess.run(claude)이 호출되지 않아야 한다."""
        with unittest.mock.patch(
            "worktree_manager.subprocess.run", return_value=FAKE_COMPLETED
        ) as mock_run:
            _auto_fix_high_comments(SAMPLE_COMMENTS, "/tmp/wt", collect_mode=True)

        # claude 를 실행하는 call이 있으면 안 됨
        claude_calls = [
            call
            for call in mock_run.call_args_list
            if (call.args[0] if call.args else call.kwargs.get("args", []))[0:1] == ["claude"]
        ]
        assert len(claude_calls) == 0, (
            f"collect_mode=True 임에도 claude subprocess가 호출되었습니다: {claude_calls}"
        )

    def test_executed_false_in_collect_mode(self):
        """collect_mode=True 이면 반환값의 executed가 False 이어야 한다."""
        with unittest.mock.patch(
            "worktree_manager.subprocess.run", return_value=FAKE_COMPLETED
        ):
            result = _auto_fix_high_comments(
                SAMPLE_COMMENTS, "/tmp/wt", collect_mode=True
            )

        assert result["executed"] is False, (
            f"collect_mode=True 에서 executed={result['executed']} — False여야 합니다."
        )


# ---------------------------------------------------------------------------
# TC-3: Gemini 타임아웃 재시도 로직 소스코드 존재 여부 검증
# ---------------------------------------------------------------------------


class TestGeminiRetryCodePresence:
    """TC-3: worktree_manager.py 에 gemini-retry 재시도 로직이 존재하는지 검증."""

    SOURCE_PATH = "/home/jay/workspace/scripts/worktree_manager.py"

    def _read_source(self) -> str:
        with open(self.SOURCE_PATH, encoding="utf-8") as f:
            return f.read()

    def test_gemini_retry_keyword_exists(self):
        """소스코드에 'gemini-retry' 문자열이 존재해야 한다."""
        source = self._read_source()
        assert "gemini-retry" in source, (
            "worktree_manager.py 에 'gemini-retry' 키워드가 없습니다. "
            "타임아웃 재시도 로직이 추가되지 않은 것 같습니다."
        )

    def test_not_gemini_found_and_pr_number_condition_exists(self):
        """소스코드에 'not gemini_found and pr_number' 조건 패턴이 존재해야 한다."""
        source = self._read_source()
        assert "not gemini_found and pr_number" in source, (
            "worktree_manager.py 에 'not gemini_found and pr_number' 조건 패턴이 없습니다. "
            "타임아웃 후 재확인 분기 로직이 없는 것 같습니다."
        )
