"""tests/regression/test_dashboard_report_hardening_2487.py — task-2487 회귀 (Group C, task-2547 corrected).

dashboard/helpers.py + report_parser.py 의 V2 + legacy dot-phase 호환 hardening 검증.

검증 대상:
- dashboard/helpers.py        : get_records_list 의 task-ID 접두사 제거 패턴 3개
- report_parser.py            : task_id 추출 + merge_branch 추출 패턴
"""
from __future__ import annotations

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

WORKSPACE = Path(__file__).resolve().parents[2]


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


# --- Source level regex inspection (dashboard/helpers.py 직접 import 는 무거우므로 회피) ---


def test_dashboard_helpers_v2_pattern_in_first_desc():
    """get_records_list 의 first_desc task-ID 접두사 제거 패턴이 V2 retry/_phase 인식."""
    src = (WORKSPACE / "dashboard" / "helpers.py").read_text(encoding="utf-8")
    # task-2487+1 같은 retry suffix 가 패턴에 포함되어야 함
    assert "(?:\\+\\d+)?" in src, "dashboard/helpers.py V2 retry suffix 패턴 누락"


def test_dashboard_helpers_preserves_task_2543_mtime_fallback():
    """task-2543 mtime fallback off 변경이 보존되어야 한다."""
    src = (WORKSPACE / "dashboard" / "helpers.py").read_text(encoding="utf-8")
    # mtime fallback off marker — task-2543 핵심 변경
    # task-2543 commit: helpers mtime fallback off
    # mtime 사용 여부 자체보다 task-2543 reconcile 동작 보존이 중요
    # 단순화: 변경 직후 라인 marker 가 있어야 함 (task-2543 마커)
    assert "task-2543" in src or "mtime" not in src.split("def get_records_list")[1][:5000].split("mtime")[0], (
        "task-2543 mtime fallback off 변경 흔적이 사라짐 — 회귀 가능성"
    )


def test_report_parser_v2_pattern_in_title_extraction():
    """report_parser.parse_report 가 # task-2487+1 헤더에서 V2 task_id 를 추출한다."""
    rp = _load_module("rp_2487", "report_parser.py")
    with tempfile.NamedTemporaryFile(mode="w", suffix=".md", delete=False, encoding="utf-8") as tf:
        tf.write("# task-2487+1 — sample title\n\n- **팀**: dev2-team\n")
        tmp_path = tf.name
    try:
        out = rp.parse_report(tmp_path)
        assert out["task_id"] == "task-2487+1", f"V2 retry suffix 추출 실패: {out}"
    finally:
        Path(tmp_path).unlink(missing_ok=True)


def test_report_parser_legacy_pattern_in_title_extraction():
    """report_parser.parse_report 가 legacy # task-1234.5 헤더에서도 task_id 를 추출한다."""
    rp = _load_module("rp_2487_legacy", "report_parser.py")
    with tempfile.NamedTemporaryFile(mode="w", suffix=".md", delete=False, encoding="utf-8") as tf:
        tf.write("# task-1234.5 — legacy title\n\n- **팀**: dev2-team\n")
        tmp_path = tf.name
    try:
        out = rp.parse_report(tmp_path)
        # V2 anchored pattern 은 1234 부분만 잡고 .5 는 못 잡음.
        # 그러나 우선순위 1은 **작업 ID** 필드, 그 다음 # 헤더, 그 다음 파일명.
        # 파일명 fallback 으로도 task-1234.5 추출 가능해야 함.
        # 또한 # 헤더 task-\d+(?:\.\d+)? 으로 task-1234.5 도 매칭 가능.
        assert out["task_id"] is not None
        assert out["task_id"].startswith("task-1234"), f"legacy task_id 추출 실패: {out}"
    finally:
        Path(tmp_path).unlink(missing_ok=True)


def test_report_parser_merge_branch_v2_pattern():
    """report_parser.parse_report 가 V2 branch task/task-2487+1-dev2 를 추출한다."""
    rp = _load_module("rp_2487_branch", "report_parser.py")
    with tempfile.NamedTemporaryFile(mode="w", suffix=".md", delete=False, encoding="utf-8") as tf:
        tf.write(
            "# task-2487+1 — merge sample\n\n"
            "- **머지 브랜치**: task/task-2487+1-dev2\n"
            "- **상태**: 머지 필요\n"
        )
        tmp_path = tf.name
    try:
        out = rp.parse_report(tmp_path)
        assert out.get("merge_branch") == "task/task-2487+1-dev2", (
            f"V2 retry suffix branch 추출 실패: {out.get('merge_branch')}"
        )
    finally:
        Path(tmp_path).unlink(missing_ok=True)


def test_report_parser_merge_branch_legacy_pattern():
    """report_parser.parse_report 가 legacy task/task-1234.5-dev1 branch 도 추출한다."""
    rp = _load_module("rp_2487_branch_legacy", "report_parser.py")
    with tempfile.NamedTemporaryFile(mode="w", suffix=".md", delete=False, encoding="utf-8") as tf:
        tf.write(
            "# task-1234.5 — legacy merge\n\n"
            "- **머지 브랜치**: task/task-1234.5-dev1\n"
        )
        tmp_path = tf.name
    try:
        out = rp.parse_report(tmp_path)
        assert out.get("merge_branch") == "task/task-1234.5-dev1", (
            f"legacy branch 추출 실패: {out.get('merge_branch')}"
        )
    finally:
        Path(tmp_path).unlink(missing_ok=True)


def test_dashboard_helpers_retry_suffix_strip():
    """dashboard/helpers.py 의 prefix-strip regex 가 task-2487+1: 를 제거하는지 직접 검증."""
    src = (WORKSPACE / "dashboard" / "helpers.py").read_text(encoding="utf-8")
    # corrected hardening 패턴 marker
    assert "task-\\d+(?:\\.\\d+)?(?:_\\d+\\.\\d+)?(?:_[a-z])?(?:\\+\\d+)?" in src, (
        "dashboard/helpers.py V2 task-ID strip pattern 누락"
    )

    # Smoke: re.sub 직접 적용
    pattern = r"^(?:task-\d+(?:\.\d+)?(?:_\d+\.\d+)?(?:_[a-z])?(?:\+\d+)?|Task\s+\d+[\.\d]*)\s*[:：]?\s*"
    assert re.sub(pattern, "", "task-2487+1: sample title").strip() == "sample title"
    assert re.sub(pattern, "", "task-1234.5: legacy title").strip() == "legacy title"
