"""tests/regression/test_legacy_compat_2487.py — task-2487 회귀 테스트 (legacy 호환).

V2 패턴 도입 이후에도 기존 단순 ID(task-1234)와 dot-phase(task-1234.5)가
파괴되지 않는지 검증한다. 회장 명시 합격 조건.

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

import importlib.util
import re
import sys
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


tip = _load_module("tip_2487_legacy", "utils/task_id_parser.py")


# ---------------------------------------------------------------------------
# L-1: is_valid_task_id — 기존 단순 ID 인식
# ---------------------------------------------------------------------------


def test_legacy_base_id_valid():
    """기존 단순 task-1234 ID가 V2 parser에서 valid로 인식된다 (미파괴 확인)."""
    assert tip.is_valid_task_id("task-1234") is True


def test_legacy_base_id_large_number():
    """큰 번호 task-99999 도 valid로 인식된다."""
    assert tip.is_valid_task_id("task-99999") is True


def test_legacy_base_id_small_number():
    """단자리 번호 task-1 도 valid로 인식된다."""
    assert tip.is_valid_task_id("task-1") is True


# ---------------------------------------------------------------------------
# L-2: dot phase (task-1234.5) — V2 TASK_ID_V2_PATTERN 인식 여부 명확화
#   V2 패턴은 언더스코어(_)를 사용하므로 dot phase는 V2 strict 패턴에서 invalid.
#   단, legacy 파이프라인에서 dot phase가 여전히 처리 가능한지 확인.
# ---------------------------------------------------------------------------


def test_legacy_dot_phase_not_valid_in_v2():
    """dot phase 'task-1234.5'는 V2 strict 패턴에서 invalid (언더스코어 아님).
    이 동작은 의도된 것으로, dot phase는 V1 호환 경로에서 처리해야 한다."""
    # V2 패턴은 _\d+\.\d+ 형식만 허용하므로 dot-phase는 False가 맞음
    result = tip.is_valid_task_id("task-1234.5")
    # 명시적 문서화: V2에서 False인 것이 정상 동작
    # 만약 True로 변경되면 V2 패턴이 dot-phase를 흡수했다는 의미이므로 별도 확인 필요
    assert result is False, (
        f"task-1234.5는 V2 패턴에서 False여야 함. True이면 dot-phase가 V2로 흡수됨 — 확인 필요"
    )


def test_legacy_dot_phase_loose_pattern_search():
    """_TASK_ID_LOOSE_PATTERN 으로는 dot phase 내 base('task-1234')가 추출된다.
    실제 filename/branch 파이프라인에서 dot-phase 처리가 완전히 망가지지 않음을 검증."""
    # extract_task_id_from_filename은 loose pattern 사용 — dot phase 파일도 처리 가능
    result = tip.extract_task_id_from_filename("task-1234.5.md")
    # dot phase 파일에서 base ID는 추출되어야 함 (설령 .5가 탈락해도)
    assert result is not None and "task-1234" in result, (
        f"task-1234.5.md 에서 base task-1234 추출 실패: got {result!r}"
    )


def test_legacy_dot_phase_branch_base_extractable():
    """'task/task-1234.5-dev1' 브랜치에서 base ID가 추출된다."""
    result = tip.extract_task_id_from_branch("task/task-1234.5-dev1")
    assert result is not None and "task-1234" in result, (
        f"task/task-1234.5-dev1 에서 base task-1234 추출 실패: got {result!r}"
    )


# ---------------------------------------------------------------------------
# L-3: parse_task_id_v2 — base 추출 fallback 검증
# ---------------------------------------------------------------------------


def test_legacy_parse_returns_none_for_dot_phase():
    """parse_task_id_v2('task-1234.5')는 모든 필드 None (V2 패턴 불일치)."""
    out = tip.parse_task_id_v2("task-1234.5")
    assert out["base"] is None, f"dot phase가 V2 base로 파싱됨: {out}"


def test_legacy_parse_v2_base_ok():
    """parse_task_id_v2('task-1234')는 base='task-1234'를 정상 반환."""
    out = tip.parse_task_id_v2("task-1234")
    assert out["base"] == "task-1234"
    assert out["phase"] is None
    assert out["retry"] is None


def test_legacy_parse_v2_phase_underscore_ok():
    """V2 언더스코어 phase 'task-1234_1.2'는 정상 파싱된다."""
    out = tip.parse_task_id_v2("task-1234_1.2")
    assert out["base"] == "task-1234"
    assert out["phase"] == "_1.2"


# ---------------------------------------------------------------------------
# L-4: report_parser.py — dot phase 파일명/title fallback 검증
# ---------------------------------------------------------------------------


def test_legacy_report_parser_dot_phase_basename():
    """report_parser가 'task-1234.5.md' basename 에서 최소한 task-1234를 추출한다.
    V2 regex는 dot phase 미지원이지만 basename fallback이 작동해야 한다."""
    import tempfile, os

    rp = _load_module("rp_legacy_2487", "report_parser.py")
    content = "# 완료 보고서\n\n내용"
    tmp_dir = tempfile.mkdtemp()
    tmp = os.path.join(tmp_dir, "task-1234.5.md")
    with open(tmp, "w", encoding="utf-8") as f:
        f.write(content)
    try:
        result = rp.parse_report(tmp)
        # V2 regex는 task-1234.5를 못 잡지만 title이나 basename에서 task-1234는 잡아야 함
        if result["task_id"] is not None:
            assert "task-1234" in result["task_id"], (
                f"report_parser가 task-1234.5.md에서 잘못된 task_id 반환: {result['task_id']!r}"
            )
        # task_id가 None이어도 크래시가 없으면 OK (graceful degradation)
    finally:
        os.unlink(tmp)
        os.rmdir(tmp_dir)


# ---------------------------------------------------------------------------
# L-5: extract_task_id_from_filename — legacy 파일명 호환
# ---------------------------------------------------------------------------


def test_legacy_extract_filename_simple():
    """'task-1234.md' → 'task-1234' 추출 (기존 동작 미파괴)."""
    result = tip.extract_task_id_from_filename("task-1234.md")
    assert result == "task-1234", f"got {result!r}"


def test_legacy_extract_filename_v2_retry():
    """'task-1234+1.md' → 'task-1234+1' 추출 (V2 신규 동작)."""
    result = tip.extract_task_id_from_filename("task-1234+1.md")
    assert result == "task-1234+1", f"got {result!r}"


def test_legacy_extract_filename_v2_phase():
    """'task-1234_1.2.md' → 'task-1234_1.2' 추출 (V2 신규 동작)."""
    result = tip.extract_task_id_from_filename("task-1234_1.2.md")
    assert result == "task-1234_1.2", f"got {result!r}"


def test_legacy_extract_branch_simple():
    """'task/task-1234-dev1' → 'task-1234' (기존 동작 미파괴)."""
    result = tip.extract_task_id_from_branch("task/task-1234-dev1")
    assert result == "task-1234", f"got {result!r}"


def test_legacy_extract_branch_v2_retry():
    """'task/task-1234+1-dev1' → 'task-1234+1' (V2 신규 동작)."""
    result = tip.extract_task_id_from_branch("task/task-1234+1-dev1")
    assert result == "task-1234+1", f"got {result!r}"


# ---------------------------------------------------------------------------
# L-6: dashboard/helpers.py prefix 정규식 — legacy dot phase 제거 호환
# ---------------------------------------------------------------------------

_DASH_PREFIX_RE_LEGACY = re.compile(
    r"^(?:task-\d+(?:_\d+\.\d+)?(?:_[a-z])?(?:\+\d+)?|Task\s+\d+[\.\d]*)\s*[:：]?\s*",
    re.IGNORECASE,
)


def test_dashboard_prefix_legacy_base_strip():
    """대시보드 prefix 제거가 'task-1234: 제목'을 정상 처리한다 (legacy)."""
    result = _DASH_PREFIX_RE_LEGACY.sub("", "task-1234: 제목").strip()
    assert result == "제목", f"got {result!r}"


def test_dashboard_prefix_dot_phase_title_strip():
    """'Task 1234.5: 제목' (숫자.숫자 dot 형식)을 prefix 제거 정규식이 처리할 수 있다."""
    # Task N.N 형식도 _DASH_PREFIX_RE에 포함되어 있음 (Task\s+\d+[\.\d]*)
    result = _DASH_PREFIX_RE_LEGACY.sub("", "Task 1234.5: 제목").strip()
    assert result == "제목", f"got {result!r}"
