"""tests/dev7/test_post_merge_probe.py — post-merge health probe (task-2367 P1)"""
# pyright: reportAttributeAccessIssue=false, reportUnusedExpression=false, reportUnusedVariable=false
import json
import sys
from pathlib import Path

import pytest

sys.path.insert(0, str(Path(__file__).resolve().parents[2] / "scripts"))


@pytest.fixture
def probe_workspace(tmp_path, monkeypatch):
    (tmp_path / "memory" / "events").mkdir(parents=True)
    (tmp_path / "memory" / "audit").mkdir(parents=True)
    (tmp_path / "logs").mkdir(parents=True)
    monkeypatch.setenv("WORKSPACE_ROOT", str(tmp_path))
    import importlib.util
    spec = importlib.util.spec_from_file_location(
        "post_merge_probe",
        str(Path(__file__).resolve().parents[2] / "scripts" / "post_merge_probe.py"),
    )
    assert spec is not None and spec.loader is not None
    pmp = importlib.util.module_from_spec(spec)
    spec.loader.exec_module(pmp)
    pmp.WORKSPACE = tmp_path
    pmp.AUDIT_LOG = tmp_path / "memory" / "audit" / "auto-merge.log"
    pmp.PROBE_MARK_DIR = tmp_path / "memory" / "events"
    return tmp_path, pmp


def test_probe_pass(probe_workspace, tmp_path):
    """build/test 모두 PASS — outcome=probe_pass."""
    workspace, pmp = probe_workspace
    # 빈 디렉토리는 build/test 모두 skip → True 반환
    project = tmp_path / "empty_project"
    project.mkdir()

    result = pmp.run_probe("task-test-pass", "abc123", project, delay=0)
    assert result["outcome"] == "probe_pass"
    assert result["probe"]["build_ok"] is True
    assert result["probe"]["test_ok"] is True

    # audit log 기록 확인
    log = workspace / "memory" / "audit" / "auto-merge.log"
    assert log.exists()
    lines = log.read_text().strip().split("\n")
    record = json.loads(lines[0])
    assert record["task_id"] == "task-test-pass"
    assert record["outcome"] == "probe_pass"


def test_probe_idempotent(probe_workspace, tmp_path):
    """이미 probe-done 마크가 있으면 재실행 스킵."""
    workspace, pmp = probe_workspace
    project = tmp_path / "p2"
    project.mkdir()
    mark = workspace / "memory" / "events" / "task-test-idem.probe-done"
    mark.write_text("{}")

    result = pmp.run_probe("task-test-idem", "abc", project, delay=0)
    assert result["status"] == "already_run"


def test_probe_fail_triggers_revert(probe_workspace, tmp_path, monkeypatch):
    """build FAIL 시 auto_revert 호출 시도."""
    _, pmp = probe_workspace
    project = tmp_path / "broken_project"
    project.mkdir()
    monkeypatch.setattr(pmp, "_run_build", lambda _p: (False, "fake build error"))
    # task-2431: _run_tests 제거됨 → _run_tests_scoped로 대체 (단일 책임 재정렬)
    monkeypatch.setattr(pmp, "_run_tests_scoped", lambda _p, _tp: (True, "ok"))
    # task-2431: scope 판정 분기가 추가되어 _changed_paths가 subprocess를 호출하므로 mock
    monkeypatch.setattr(pmp, "_changed_paths", lambda _p, _sha: [])

    calls = []
    class _MockPopen:
        def __init__(self, args, **_kw):
            calls.append(args)
    monkeypatch.setattr(pmp.subprocess, "Popen", _MockPopen)

    result = pmp.run_probe("task-test-fail", "deadbeef", project, delay=0)
    assert result["outcome"] == "probe_fail"
    assert result["probe"]["build_ok"] is False
    # auto_revert 호출 1건
    assert len(calls) == 1
    assert "auto_revert.py" in " ".join(calls[0])
    assert "--task-id" in calls[0]
    assert "task-test-fail" in calls[0]
