"""final-verification 판정이 release-handoff 진입을 허용하는지 판정한다.

검증기(`validators/validate-run.py`)와 핸드오프(`handoff.py`), 그리고 HTML 리포트가
모두 같은 답을 내야 하므로 규칙은 여기 한 번만 산다.

`accepted` 는 그대로 통과한다. `conditional-accept` 는 모든 조건이 스스로
`blocksReleaseHandoff: false` 라고 선언했을 때만 통과한다 — 릴리스를 막는다고 적힌
조건이 하나라도 있으면 막힌다. 조건 목록이 비어 있는 `conditional-accept` 는
그 자체가 계약 위반이므로(조건을 빠짐없이 적어야 한다) 여기서도 막는다.
"""
from __future__ import annotations

from collections.abc import Mapping
from typing import Any

RELEASE_HANDOFF_TARGETS = frozenset({"release-handoff", "release-handoff(stage-group)"})


def verdict_token(data: Mapping[str, Any]) -> str:
    """리포트의 유일한 판정 토큰 자리에서 읽은 값(소문자, 공백 제거)."""
    final_verdict = data.get("finalVerdict")
    if not isinstance(final_verdict, Mapping):
        return ""
    return str(final_verdict.get("verdictToken") or "").strip().lower()


def _conditions(data: Mapping[str, Any]) -> list[Mapping[str, Any]]:
    final_verdict = data.get("finalVerdict")
    if not isinstance(final_verdict, Mapping):
        return []
    rows = final_verdict.get("conditionalAcceptanceConditions")
    if not isinstance(rows, list):
        return []
    return [row for row in rows if isinstance(row, Mapping)]


def blocking_condition_ids(data: Mapping[str, Any]) -> list[str]:
    """릴리스를 막는다고 선언된 조건의 id. 선언이 없거나 참이면 막는 것으로 읽는다."""
    return [
        str(row.get("id") or "<id 없음>")
        for row in _conditions(data)
        if row.get("blocksReleaseHandoff") is not False
    ]


def release_handoff_allowed(data: Mapping[str, Any]) -> bool:
    """이 final-verification 리포트가 release-handoff 로 넘어가도 되는가."""
    token = verdict_token(data)
    if token == "accepted":
        return True
    if token != "conditional-accept":
        return False
    conditions = _conditions(data)
    if not conditions:
        return False
    return not blocking_condition_ids(data)
