"""tests/regression/test_task_id_parser_hardening.py — task-2485 회귀.

task-N+M (retry suffix) 형식이 parser/extractor에서 정상 인식되는지 검증.
"""
from __future__ import annotations

import os as _os
import sys as _sys

# 워크트리/메인 어느 환경이든 자신의 워크스페이스 루트를 sys.path[0]에 우선 등록.
_WROOT = _os.path.dirname(_os.path.dirname(_os.path.dirname(_os.path.abspath(__file__))))
if _WROOT in _sys.path:
    _sys.path.remove(_WROOT)
_sys.path.insert(0, _WROOT)

import pytest
from utils.task_id_parser import (  # type: ignore[import-not-found]  # noqa: E402
    is_valid_task_id,
    extract_task_id,
    TASK_ID_RE,
    TASK_ID_PATTERN,
    extract_task_id_from_branch,
    extract_task_id_from_filename,
)


# (회귀 7-1) task-N legacy valid
@pytest.mark.parametrize("tid", ["task-2472", "task-1", "task-9999"])
def test_legacy_task_id_still_valid(tid):
    assert is_valid_task_id(tid)


# (회귀 7-2) task-N+M suffix valid
@pytest.mark.parametrize("tid", ["task-2472+1", "task-2472+2", "task-2467+3", "task-1+0"])
def test_retry_suffix_valid(tid):
    assert is_valid_task_id(tid), f"{tid} should be valid"


# (회귀 7-3) invalid task_id reject
@pytest.mark.parametrize("tid", ["task-abc", "task-2472+", "task-2472++1", "task-", "", "TASK-2472", "task--2472"])
def test_invalid_task_id_rejected(tid):
    assert not is_valid_task_id(tid), f"{tid} should NOT be valid"


# (회귀 7-3 보강) malformed 입력에서 extractor가 잘라먹지 않음 (Codex high #3 대응)
@pytest.mark.parametrize("text", ["task-2472++1", "task-2472+", "task-2472abc"])
def test_extract_task_id_rejects_malformed(text):
    """경계 위반 입력에서 task id 를 잘라서 추출하지 않아야 함."""
    assert extract_task_id(text) is None, (
        f"malformed {text!r} 에서 잘라낸 추출 발생 — 경계 검사 미흡"
    )


# (회귀) extractor 경계: task-2472+1 검사 시 task-2472+10 을 task-2472+1 로 잘라먹지 않음
def test_extract_task_id_boundary_no_truncation():
    # task-2472+10 은 valid V2 (retry=+10) 이므로 그대로 매치되어야 함
    assert extract_task_id("foo task-2472+10 bar") == "task-2472+10"
    # task-24720 은 valid V2 (num=24720) 이므로 그대로 매치
    assert extract_task_id("foo task-24720 bar") == "task-24720"


# (회귀 7-4) extract_task_id 다양한 텍스트 케이스
@pytest.mark.parametrize("text,expected", [
    ("foo-task-2472+1-bar", "task-2472+1"),
    ("task/task-2467+3-dev6", "task-2467+3"),
    ("memory/tasks/task-2472+2.md", "task-2472+2"),
    ("[task-2472+1] retry merge", "task-2472+1"),
    ("nothing here", None),
])
def test_extract_task_id_from_text(text, expected):
    assert extract_task_id(text) == expected


def test_extract_task_id_from_branch_retry_suffix():
    assert extract_task_id_from_branch("task/task-2472+1-dev2") == "task-2472+1"


def test_extract_task_id_from_filename_retry_suffix():
    assert extract_task_id_from_filename("memory/tasks/task-2467+3.md") == "task-2467+3"


def test_TASK_ID_RE_is_compiled_pattern():
    # TASK_ID_RE는 compiled re.Pattern이어야 함
    import re
    assert isinstance(TASK_ID_RE, re.Pattern)
    assert TASK_ID_RE.match("task-2472+2") is not None
    assert TASK_ID_RE.match("task-abc") is None


def test_TASK_ID_PATTERN_is_string():
    assert isinstance(TASK_ID_PATTERN, str)
    # pattern string으로 다시 컴파일해도 동등 동작
    import re
    p = re.compile(TASK_ID_PATTERN)
    assert p.match("task-2472+2") is not None
