"""
test_scope_guard_lock_sha_2569.py
MT-T3: AD-1~3 검증 (lock_sha..HEAD scope guard)
  - pre-push hook lock_sha 추출 + _DIFF_BASE 분기 + worktree 감지 로직
  - pre_push_guard.py _resolve_diff_base() 정의 + lock_sha 키 사용
  - task_scope.py base_sha auto 분기 + _resolve_diff_base 호출
  - _resolve_diff_base() 동작 검증 (lock_sha fallback vs origin/main fallback)
"""
import importlib.util
import json
import sys
from pathlib import Path

import pytest

WORKSPACE = Path(__file__).resolve().parents[2]
PRE_PUSH_HOOK = WORKSPACE / "scripts" / "git-hooks" / "pre-push"
PRE_PUSH_GUARD_PY = WORKSPACE / "scripts" / "pre_push_guard.py"
TASK_SCOPE_PY = WORKSPACE / "scripts" / "task_scope.py"


def _load_task_scope():
    """task_scope.py를 importlib으로 로드."""
    scripts_dir = str(WORKSPACE / "scripts")
    workspace_root = str(WORKSPACE)
    for p in [scripts_dir, workspace_root]:
        if p not in sys.path:
            sys.path.insert(0, p)
    spec = importlib.util.spec_from_file_location("task_scope_mod", TASK_SCOPE_PY)
    if spec is None or spec.loader is None:
        return None
    mod = importlib.util.module_from_spec(spec)
    try:
        spec.loader.exec_module(mod)
    except Exception:
        return None
    return mod


# ── 픽스처 ──────────────────────────────────────────────────────────────────────

@pytest.fixture(scope="module")
def pre_push_content() -> str:
    assert PRE_PUSH_HOOK.exists(), f"pre-push hook 없음: {PRE_PUSH_HOOK}"
    return PRE_PUSH_HOOK.read_text(encoding="utf-8")


@pytest.fixture(scope="module")
def guard_py_content() -> str:
    assert PRE_PUSH_GUARD_PY.exists(), f"pre_push_guard.py 없음: {PRE_PUSH_GUARD_PY}"
    return PRE_PUSH_GUARD_PY.read_text(encoding="utf-8")


@pytest.fixture(scope="module")
def task_scope_content() -> str:
    assert TASK_SCOPE_PY.exists(), f"task_scope.py 없음: {TASK_SCOPE_PY}"
    return TASK_SCOPE_PY.read_text(encoding="utf-8")


# ── 테스트 1: pre-push hook lock_sha + _DIFF_BASE + worktree 감지 ──────────────

def test_pre_push_hook_uses_lock_sha(pre_push_content: str):
    """pre-push hook에 lock_sha 추출, _DIFF_BASE 분기, worktree 컨텍스트 감지 로직이 있어야 한다."""
    assert "lock_sha" in pre_push_content, (
        "pre-push hook에 'lock_sha' 키 참조가 없습니다. AD-1~3 구현을 확인하세요."
    )
    assert "_DIFF_BASE" in pre_push_content, (
        "pre-push hook에 '_DIFF_BASE' 변수가 없습니다. AD-1~3 구현을 확인하세요."
    )
    # worktree 감지: .worktrees 경로 포함 여부 확인
    assert ".worktrees" in pre_push_content, (
        "pre-push hook에 worktree 컨텍스트 감지 로직이 없습니다. "
        "'.worktrees' 경로 패턴이 필요합니다."
    )


# ── 테스트 2: pre_push_guard.py _resolve_diff_base() 함수 정의 ────────────────

def test_pre_push_guard_has_resolve_diff_base(guard_py_content: str):
    """pre_push_guard.py에 _resolve_diff_base() 함수 정의와 lock_sha 키 사용이 있어야 한다."""
    assert "_resolve_diff_base" in guard_py_content, (
        "pre_push_guard.py에 '_resolve_diff_base' 함수가 없습니다. AD-1~3 구현을 확인하세요."
    )
    assert "lock_sha" in guard_py_content, (
        "pre_push_guard.py에 'lock_sha' 키 사용이 없습니다. AD-2 구현을 확인하세요."
    )


# ── 테스트 3: task_scope.py base_sha auto 분기 + _resolve_diff_base 호출 ────────

def test_task_scope_accepts_auto_base_sha(task_scope_content: str):
    """task_scope.py에 base_sha auto/AUTO 분기와 _resolve_diff_base 호출이 있어야 한다."""
    # auto/AUTO 분기 확인
    has_auto_branch = (
        'base_sha in ("auto", "AUTO")' in task_scope_content
        or "base_sha == \"auto\"" in task_scope_content
        or "base_sha == 'auto'" in task_scope_content
    )
    assert has_auto_branch, (
        "task_scope.py에 base_sha auto/AUTO 분기 로직이 없습니다. AD-3 구현을 확인하세요."
    )
    assert "_resolve_diff_base" in task_scope_content, (
        "task_scope.py에 '_resolve_diff_base' 호출이 없습니다. AD-1~3 구현을 확인하세요."
    )


# ── 테스트 4: _resolve_diff_base() 동작 검증 ───────────────────────────────────

def test_resolve_diff_base_lock_sha_fallback(tmp_path: Path, monkeypatch):
    """_resolve_diff_base() 동작 검증.

    시나리오 A: 일반 컨텍스트(worktree 아님) + lock_sha 있어도 → origin/main 반환.
    시나리오 B: worktree 컨텍스트(GIT_DIR에 .worktrees 포함) + lock_sha → lock_sha 반환.
    """
    # 가짜 lock 파일 생성
    task_id = "task-9999"
    fake_sha = "abcdef1234567890abcdef1234567890abcdef12"
    lock_dir = tmp_path / ".tasks" / "locks"
    lock_dir.mkdir(parents=True)
    lock_file = lock_dir / f"{task_id}.lock"
    lock_file.write_text(json.dumps({"task_id": task_id, "lock_sha": fake_sha}))

    # task_scope 모듈 로드
    ts_mod = _load_task_scope()
    if ts_mod is None:
        pytest.skip("task_scope.py 로드 실패 — 의존성 누락 (정적 검증으로 대체됨)")

    # 시나리오 A: 일반 컨텍스트 (worktree 아님)
    monkeypatch.setenv("GIT_DIR", "")
    monkeypatch.chdir(tmp_path)  # .worktrees 없는 경로

    result_a = ts_mod._resolve_diff_base(task_id, tmp_path)
    assert result_a == "origin/main", (
        f"일반 컨텍스트에서 origin/main 반환 기대, 실제: {result_a}"
    )

    # 시나리오 B: worktree 컨텍스트 (GIT_DIR에 .worktrees 포함)
    worktree_git_dir = tmp_path / ".worktrees" / (task_id + "-dev1") / ".git"
    monkeypatch.setenv("GIT_DIR", str(worktree_git_dir))

    result_b = ts_mod._resolve_diff_base(task_id, tmp_path)
    assert result_b == fake_sha, (
        f"worktree 컨텍스트 + lock_sha에서 lock_sha 반환 기대, 실제: {result_b}"
    )
