"""G4.6 Phase 4 Wave A3 — v21 scene_detail prompt active body grep gate.

Codex iter 1 M1 carry — production code / authored test 외에 v21 prompt
active body 도 별도 grep gate 강제. v21 system.md 가 LLM-input 이라
시나리오 의존 어휘 / censor preemption / violence palette 잔재가 직접
모델 prompt 에 들어가면 A-prime binding 위반.

검사 대상:
- A-prime nationality / ethnicity / 작품 고유명사 token (RC-C carry)
- Codex iter 1 B2 — scenario-derived violence palette
  (attacker / victim / tearing flesh / spurting blood / etc.)
- Codex iter 1 B3 — preemptive censor handling wording
  (safety filter / 회피 루틴 / film previs / aftermath 재작성)

User binding refs:
- feedback_no_scenario_keywords.md
- feedback_no_preemptive_censor_handling.md
- feedback_no_scenario_names.md
"""
from __future__ import annotations

import re
from pathlib import Path

import pytest


_REPO_ROOT = Path(__file__).resolve().parents[3]
_SCENE_DETAIL_BASE = _REPO_ROOT / "prompts" / "_base" / "scene_detail"


def _v21_system_md_path() -> Path:
    """current latest scene_detail v21 system.md path."""
    candidates = sorted(
        (p for p in _SCENE_DETAIL_BASE.glob("21.*/system.md") if p.is_file()),
        key=lambda p: p.parent.name,
    )
    if not candidates:
        pytest.skip("no v21 system.md found")
    return candidates[-1]


_FORBIDDEN_PATTERN = re.compile(
    r"(?i)("
    # nationality / ethnicity / 작품 고유명사 (RC-C carry)
    r"korean|east asian|asian woman|asian man|"
    r"한국인|일본인|중국인|어린 소녀|남자 직원|여직원|여자 직원|"
    r"yokai|요괴|fang|vampire|흡혈|red iris|sharp pointed teeth|"
    r"날카로운 이빨|monstrous|괴물|"
    # scenario-derived violence palette (Codex iter 1 B2)
    r"attacker|assailant|aggressor|predator|victim|prey|"
    r"tearing flesh|ripped skin|spurting blood|broken knuckles|"
    r"gaping wound|jagged gash|raw tissue|"
    # preemptive censor handling (Codex iter 1 B3)
    r"safety filter|안전 필터|회피 루틴|film previs|"
    r"movie poster|aftermath 재작성"
    r")"
)


def test_v21_system_md_no_forbidden_tokens():
    """A-prime + violence palette + censor preemption — active v21 prompt 0 hits."""
    path = _v21_system_md_path()
    content = path.read_text(encoding="utf-8")
    matches = sorted(set(m.lower() for m in _FORBIDDEN_PATTERN.findall(content)))
    assert not matches, (
        f"v21 system.md ({path.relative_to(_REPO_ROOT)}) contains forbidden "
        f"tokens: {matches}. Phase 4 binding (A-prime / no preemptive censor "
        f"/ no scenario violence palette) violation. "
        f"Refs: feedback_no_scenario_keywords.md, "
        f"feedback_no_preemptive_censor_handling.md."
    )


def test_v21_system_md_present_and_not_empty():
    """v21 prompt directory + system.md 존재 + non-empty."""
    path = _v21_system_md_path()
    assert path.exists()
    content = path.read_text(encoding="utf-8")
    assert len(content) > 1000, (
        f"v21 system.md too short ({len(content)} chars) — production prompt "
        f"is expected to be ~500 lines / ~30KB."
    )
