"""Tests for scripts/lock_in_verify.py — Lock-in First-line guard AST verifier."""

from __future__ import annotations

import importlib.util
import sys
import textwrap
from pathlib import Path

import pytest

ROOT = Path(__file__).resolve().parents[2]
SCRIPT = ROOT / "scripts" / "lock_in_verify.py"


@pytest.fixture(scope="module")
def lock_in_module():
    spec = importlib.util.spec_from_file_location("lock_in_verify", SCRIPT)
    assert spec and spec.loader
    mod = importlib.util.module_from_spec(spec)
    sys.modules["lock_in_verify"] = mod
    spec.loader.exec_module(mod)
    return mod


def _write(tmp_path: Path, name: str, body: str) -> Path:
    p = tmp_path / name
    p.parent.mkdir(parents=True, exist_ok=True)
    p.write_text(textwrap.dedent(body), encoding="utf-8")
    return p


def test_pass_anu_pattern(lock_in_module, tmp_path: Path) -> None:
    p = _write(tmp_path, "main.py", '''
        import subprocess
        from pathlib import Path
        WORKSPACE_ROOT = "/x"
        def _execute_approve(task_num: int, pr_num: int) -> dict:
            _cancelled_marker = Path(WORKSPACE_ROOT) / "memory" / "events" / f"task-{task_num}.cancelled"
            if _cancelled_marker.exists():
                return {"ok": False}
            _guard_sh = Path(WORKSPACE_ROOT) / "scripts" / "guard.sh"
            _gp = subprocess.run(["bash", str(_guard_sh), "pre-push", f"task-{task_num}"], capture_output=True, text=True, timeout=60)
            if _gp.returncode != 0:
                return {"ok": False}
            cmd = ["gh", "pr", "merge", str(pr_num), "--merge"]
            proc = subprocess.run(cmd, capture_output=True, text=True, timeout=60)
            return {"ok": proc.returncode == 0}
        ''')
    errs = lock_in_module.verify_function(p, "_execute_approve", ("gh", "pr", "merge"))
    assert errs == []


def test_fail_no_first_line_guard(lock_in_module, tmp_path: Path) -> None:
    p = _write(tmp_path, "bad.py", '''
        import subprocess
        from pathlib import Path
        def _execute_approve(task_num: int, pr_num: int) -> dict:
            cmd = ["gh", "pr", "merge", str(pr_num), "--merge"]
            proc = subprocess.run(cmd, capture_output=True, text=True, timeout=60)
            return {"ok": proc.returncode == 0}
        ''')
    errs = lock_in_module.verify_function(p, "_execute_approve", ("gh", "pr", "merge"))
    assert errs, "should have flagged missing first-line guard"
    joined = " ".join(errs)
    assert "cancelled" in joined.lower() or "body too short" in joined


def test_fail_guard_after_merge(lock_in_module, tmp_path: Path) -> None:
    p = _write(tmp_path, "wrong_order.py", '''
        import subprocess
        from pathlib import Path
        WORKSPACE_ROOT = "/x"
        def _execute_approve(task_num: int, pr_num: int) -> dict:
            _cancelled_marker = Path(WORKSPACE_ROOT) / "memory" / "events" / f"task-{task_num}.cancelled"
            if _cancelled_marker.exists():
                return {"ok": False}
            cmd = ["gh", "pr", "merge", str(pr_num), "--merge"]
            proc = subprocess.run(cmd, capture_output=True, text=True, timeout=60)
            _guard_sh = Path(WORKSPACE_ROOT) / "scripts" / "guard.sh"
            subprocess.run(["bash", str(_guard_sh), "pre-push", "x"])
            return {"ok": True}
        ''')
    errs = lock_in_module.verify_function(p, "_execute_approve", ("gh", "pr", "merge"))
    assert errs
    assert any("Lock-in 위반" in e or "늦음" in e for e in errs), errs


def test_pass_auto_merge_pattern(lock_in_module, tmp_path: Path) -> None:
    p = _write(tmp_path, "auto_merge.py", '''
        import subprocess
        from pathlib import Path
        class C:
            def __init__(self):
                self.workspace = Path("/x")
            def execute_merge(self, project_path, task_id, team_id):
                _cancelled_marker = self.workspace / "memory" / "events" / f"{task_id}.cancelled"
                if _cancelled_marker.exists():
                    raise RuntimeError("cancelled")
                _guard_sh = self.workspace / "scripts" / "guard.sh"
                _gp = subprocess.run(["bash", str(_guard_sh), "pre-push", task_id], capture_output=True, text=True, timeout=60)
                if _gp.returncode != 0:
                    raise RuntimeError("guard fail")
                worktree_manager = Path(__file__).parent / "worktree_manager.py"
                cmd = ["python3", str(worktree_manager), "finish", project_path, task_id, team_id, "--action", "merge"]
                result = subprocess.run(cmd, capture_output=True, text=True, timeout=120)
                return result
        ''')
    errs = lock_in_module.verify_function(p, "execute_merge", ("worktree_manager", "finish"))
    assert errs == []


def test_real_workspace_paths_pass(lock_in_module) -> None:
    """Sanity: the real anu_confirm_bot/main.py and auto_merge.py PASS."""
    for spec in lock_in_module.CHECKS:
        target = ROOT / spec["file"]
        errs = lock_in_module.verify_function(target, spec["func"], spec["merge_signature_tokens"])
        assert errs == [], f"{spec['file']}::{spec['func']} broke: {errs}"
