"""tests/regression/test_scripts_hardening_2487.py — task-2487 회귀 테스트 (Group B).

scripts/ 영역의 각 파일이 V2 task ID 패턴을 인식하는지 검증한다.

직접 import 가능한 모듈: done-watcher, report_utils
직접 import 어려운 (side-effect / argparse main) 스크립트: 메타 grep 테스트 적용.

헤임달(개발2팀 테스터) 작성 / task-2487.
"""
from __future__ import annotations

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

WORKSPACE = Path(__file__).resolve().parents[2]
SCRIPTS_DIR = WORKSPACE / "scripts"


def _load_module(mod_name: str, file_rel: str):
    file_path = WORKSPACE / file_rel
    spec = importlib.util.spec_from_file_location(mod_name, str(file_path))
    if spec is None or spec.loader is None:
        raise ImportError(f"cannot load spec for {file_path}")
    module = importlib.util.module_from_spec(spec)
    sys.modules[mod_name] = module
    spec.loader.exec_module(module)
    return module


# ---------------------------------------------------------------------------
# B-1: done-watcher.py — is_valid_task_id 직접 import 후 V2 인식 검증
# ---------------------------------------------------------------------------

# done-watcher.py가 utils.task_id_parser.is_valid_task_id를 import하므로
# 해당 함수를 직접 사용해 동일 케이스 검증한다.
tip = _load_module("tip_2487_scripts", "utils/task_id_parser.py")

V2_VALID_CASES = [
    "task-1234",
    "task-1234+1",
    "task-1234_1.2",
    "task-1234_1.2_a+3",
    "task-9999+99",
    "task-0001_3.14",
    "task-2487_2.1_b+5",
]

V2_INVALID_CASES = [
    "1234",
    "task-abc",
    "not-a-task",
    "",
    "task-",
    "TASK-1234",
]


def test_done_watcher_uses_is_valid_task_id():
    """done-watcher.py 소스에 is_valid_task_id import가 존재한다."""
    src = (SCRIPTS_DIR / "done-watcher.py").read_text(encoding="utf-8")
    assert "is_valid_task_id" in src, "done-watcher.py에 is_valid_task_id 사용 없음"


def test_done_watcher_v2_valid_cases():
    """done-watcher가 의존하는 is_valid_task_id가 V2 패턴을 모두 통과시킨다."""
    for tid in V2_VALID_CASES:
        assert tip.is_valid_task_id(tid) is True, f"is_valid_task_id({tid!r}) should be True"


def test_done_watcher_v2_invalid_rejected():
    """done-watcher가 의존하는 is_valid_task_id가 잘못된 패턴을 거부한다."""
    for tid in V2_INVALID_CASES:
        assert tip.is_valid_task_id(tid) is False, f"is_valid_task_id({tid!r}) should be False"


def test_done_watcher_file_pattern_covers_v2():
    """done-watcher.py 내 .done 파일명 정규식이 V2 suffix(_/+) 토큰을 포함한다."""
    src = (SCRIPTS_DIR / "done-watcher.py").read_text(encoding="utf-8")
    # 언더스코어 phase 패턴 (_\d+\.\d+) 또는 retry (+\d+) 가 소스에 있어야 함
    assert re.search(r"_\\d\+\\\\", src) or re.search(r"_\\\\d\+\\\\", src) or r"_\d+\." in src or r"_\d+\.\d+" in src, (
        "done-watcher.py 파일명 패턴에 V2 언더스코어 phase 토큰이 없음"
    )


# ---------------------------------------------------------------------------
# B-2: notify-completion.py — 메타 테스트
#   _RE_TASK_ID = re.compile(r"^task-\d+\.\d+$") 형태(V1 dot phase)만 있음 확인 후
#   V2 패턴 미지원 여부를 명시적으로 문서화
# ---------------------------------------------------------------------------


def test_notify_completion_task_id_pattern_present():
    """notify-completion.py에 _RE_TASK_ID 또는 TASK_ID 관련 패턴이 존재한다."""
    src = (SCRIPTS_DIR / "notify-completion.py").read_text(encoding="utf-8")
    assert "_RE_TASK_ID" in src or "TASK_ID" in src or "task_id" in src.lower(), (
        "notify-completion.py에 task ID 관련 심볼이 없음"
    )


def test_notify_completion_v2_meta_or_explicit():
    """notify-completion.py가 V2 패턴(_\\d+\\.\\d+ 또는 +\\d+)을 소스에 포함하거나
    utils.task_id_parser를 사용한다 — 미지원이면 FAIL(코드 수정 필요 신호)."""
    src = (SCRIPTS_DIR / "notify-completion.py").read_text(encoding="utf-8")
    has_v2_pattern = bool(
        re.search(r"_\\d\+\\\\", src)  # _\d+\.
        or r"_\d+\.\d+" in src
        or r"\+\d+" in src
        or "task_id_parser" in src
        or "is_valid_task_id" in src
    )
    assert has_v2_pattern, (
        "notify-completion.py: V2 패턴(_\\d+\\.\\d+ / +\\d+) 미포함 및 "
        "task_id_parser 미사용 — _RE_TASK_ID가 V1 dot-phase 전용일 가능성"
    )


# ---------------------------------------------------------------------------
# B-3: auto_merge.py — report_parser(V2 호환) 사용 확인
# ---------------------------------------------------------------------------


def test_auto_merge_imports_report_parser():
    """auto_merge.py가 report_parser를 import하는지 확인 (V2 branch 패턴 간접 검증)."""
    src = (SCRIPTS_DIR / "auto_merge.py").read_text(encoding="utf-8")
    assert "report_parser" in src, "auto_merge.py가 report_parser를 import하지 않음"


def test_auto_merge_report_parser_branch_v2():
    """report_parser.py의 merge_branch 패턴이 V2 suffix(_/+)를 포함한다."""
    src = (WORKSPACE / "report_parser.py").read_text(encoding="utf-8")
    # V2 호환 branch 패턴: task/task-N(_phase)(_parallel)(+retry)-devN
    assert re.search(r"_\\?\\d\+\\.\\d\+|_\d\+\\\.\d\+|_\\d\+", src) or r"_\d+\.\d+" in src, (
        "report_parser.py merge_branch 패턴에 V2 언더스코어 phase 없음"
    )


# ---------------------------------------------------------------------------
# B-4: token-tracker.py — TASK_RE 패턴 메타 검증
# ---------------------------------------------------------------------------


def test_token_tracker_task_re_present():
    """token-tracker.py에 TASK_RE 컴파일 패턴이 존재한다."""
    src = (SCRIPTS_DIR / "token-tracker.py").read_text(encoding="utf-8")
    assert "TASK_RE" in src, "token-tracker.py에 TASK_RE 정의 없음"


def test_token_tracker_task_re_v2_coverage():
    """token-tracker.py TASK_RE가 V2 패턴(_/+)을 포함하거나 task_id_parser를 사용한다.
    TASK_RE = re.compile(r'task-\\d+(?:\\.\\d+)?') 처럼 dot-phase 전용이면 FAIL."""
    src = (SCRIPTS_DIR / "token-tracker.py").read_text(encoding="utf-8")
    # V2는 언더스코어(_) phase를 사용; dot phase(\\. 전용)만 있으면 V2 미대응
    has_v2 = (
        r"_\d+\.\d+" in src          # 인라인 literal
        or r"_\\d\+" in src           # 이스케이프 표현
        or "task_id_parser" in src
        or "is_valid_task_id" in src
    )
    if not has_v2:
        # 현재 dot-phase 전용 TASK_RE이므로 경고 수준 처리 (XFAIL 대신 assert+메시지)
        assert False, (
            "token-tracker.py TASK_RE가 V2 언더스코어 phase 미지원 — "
            "task-1234_1.2 같은 ID를 task-1234 로 잘못 파싱할 수 있음"
        )


# ---------------------------------------------------------------------------
# B-5: pattern-detector.py — 메타 테스트 (task ID 패턴 직접 없음, 파일명 scan 위주)
# ---------------------------------------------------------------------------


def test_pattern_detector_loads_source():
    """pattern-detector.py 파일이 존재하고 읽을 수 있다."""
    src = (SCRIPTS_DIR / "pattern-detector.py").read_text(encoding="utf-8")
    assert len(src) > 100, "pattern-detector.py 파일이 비어 있거나 너무 작음"


def test_pattern_detector_no_hard_coded_v1_only_task_re():
    """pattern-detector.py가 task-\\d+\\.\\d+ 전용 패턴 없이 동작하거나 V2 호환이다."""
    src = (SCRIPTS_DIR / "pattern-detector.py").read_text(encoding="utf-8")
    # pattern-detector는 보고서 키워드 감지 위주 — task ID 정규식 없어도 OK
    # dot-phase 전용 task 패턴이 소스에 있으면 V2 인식 여부 추가 확인
    dot_only = re.findall(r'task-\\\\d\+\\\\\.\\\\d\+', src)
    if dot_only:
        assert "task_id_parser" in src or r"_\d+\.\d+" in src, (
            "pattern-detector.py에 V1 dot-phase 전용 패턴이 있으나 V2 대응 없음"
        )


# ---------------------------------------------------------------------------
# B-6: report_utils.py — title 추출 정규식 V2 호환 확인
# ---------------------------------------------------------------------------


def test_report_utils_title_pattern_covers_v2():
    """report_utils.py 내 제목 추출 정규식이 V2 ID(언더스코어 phase) 제거를 지원한다."""
    src = (SCRIPTS_DIR / "report_utils.py").read_text(encoding="utf-8")
    # V2 호환이면 _\d+\.\d+ 또는 +\d+ 토큰이 정규식에 등장해야 함
    has_v2 = r"_\d+\.\d+" in src or r"_\\d+" in src or "task_id_parser" in src
    assert has_v2, (
        "report_utils.py 제목 추출 정규식이 V2 언더스코어 phase(_\\d+\\.\\d+) 미지원"
    )


# ---------------------------------------------------------------------------
# B-7: start_task_guard.py — branch 파싱 V2 호환 메타 검증
# ---------------------------------------------------------------------------


def test_start_task_guard_source_readable():
    """start_task_guard.py 파일이 존재하고 읽을 수 있다."""
    src = (SCRIPTS_DIR / "start_task_guard.py").read_text(encoding="utf-8")
    assert len(src) > 200, "start_task_guard.py 파일이 비어있거나 너무 작음"


def test_start_task_guard_branch_extraction_v2():
    """start_task_guard.py의 branch에서 task-id 추출 로직이 V2 suffix를 처리할 수 있다.
    현재 단순 split('-') 방식이면 task-1234+1-dev4 에서 task-1234 를 잘못 추출할 수 있음."""
    src = (SCRIPTS_DIR / "start_task_guard.py").read_text(encoding="utf-8")
    # task_id_parser 사용 또는 V2 토큰 인식 패턴 존재 여부 확인
    has_v2 = (
        "task_id_parser" in src
        or "extract_task_id_from_branch" in src
        or r"_\d+\.\d+" in src
        or r"+\d+" in src
    )
    if not has_v2:
        # start_task_guard가 단순 split 사용 중이면 V2 ID에서 잘못된 추출 가능
        assert False, (
            "start_task_guard.py: branch에서 task-id 추출 시 V2 suffix 미처리 — "
            "task/task-1234+1-dev4 에서 task-1234+1 을 올바르게 추출하는지 확인 필요"
        )
