"""task md 파일을 6가지 실행 모드로 분류하고 sha256 immutability를 검증하는 단일 helper 모듈."""

from __future__ import annotations

import hashlib
import re
from pathlib import Path
from typing import Tuple

VALID_MODES: Tuple[str, str, str, str, str, str] = (
    "code",
    "docs_only",
    "read_only_watcher",
    "diagnosis",
    "callback_only",
    "closeout_marker_only",
)

MUTATION_FORBIDDEN_MARKER: str = "TASK_MD_POST_DISPATCH_MUTATION_FORBIDDEN"

_LEVEL_LV0_RE = re.compile(r"Level\s*:\s*Lv\.?\s*0", re.IGNORECASE)
_DOCS_ONLY_FRONTMATTER_RE = re.compile(r"docs_only\s*:\s*true", re.IGNORECASE)


def _read_text(task_md_path: str) -> str:
    """task md 경로에서 utf-8 텍스트를 읽어 반환한다."""
    return Path(task_md_path).read_text(encoding="utf-8")


def classify_task_mode(task_md_path: str) -> str:
    """task md 내용을 분석해 6개 실행 모드 중 하나를 반환한다."""
    text = _read_text(task_md_path)
    lower = text.lower()

    # docs_only 우선 검사 (frontmatter / 본문 marker)
    if _DOCS_ONLY_FRONTMATTER_RE.search(text) or "docs only" in lower:
        return "docs_only"

    is_lv0 = bool(_LEVEL_LV0_RE.search(text))

    if is_lv0:
        # watcher 우선 (task-2689 재현 시나리오)
        if "watcher" in lower:
            return "read_only_watcher"
        if ("diagnosis" in lower) or ("진단" in text) or ("분석" in text):
            return "diagnosis"
        if ("callback" in lower) or ("콜백" in text) or ("envelope" in lower):
            return "callback_only"
        if ("closeout" in lower) or (".done marker" in lower) or ("마커만" in text):
            return "closeout_marker_only"

    return "code"


def check_task_md_immutability(
    task_md_path: str, recorded_sha256: str | None = None
) -> Tuple[bool, str]:
    """task md sha256을 계산해 기록값과 비교하고 (is_unchanged, current_sha256)을 반환한다."""
    data = Path(task_md_path).read_bytes()
    current = hashlib.sha256(data).hexdigest()

    if recorded_sha256 is None:
        # 초기 기록용 호출 - 항상 unchanged True
        return (True, current)

    return (current == recorded_sha256, current)


def is_read_only_mode(mode: str) -> bool:
    """read-only 성격의 모드(commit/diff 0이 PASS 증거인 모드)인지 판정한다."""
    return mode in (
        "read_only_watcher",
        "diagnosis",
        "callback_only",
        "closeout_marker_only",
        "docs_only",
    )
