"""Area #2 W5 — 4 site state migration verification.

source-grep regression — 4 production files (asset_readiness / scene_reference_service /
detail_steps / render_prompt_card) 의 v12 legacy ``ca.get("gaze_target")`` 읽기 패턴
폐기 + ``is_immobilized_state(ca["subject_state"])`` 단일 SOT 전환 검증.

Gate 1 (semantic regex ban): code 가 literal tuple ``("dead", "unconscious",
"severely_injured")`` 로 semantic state 판단 금지 — helper 만 사용.
Gate 2 (active prompt 오염): line 936 의 ``"dead/unconscious bodies"`` 같은 prompt
오염 표현 중립화 의무.
Gate 4 (fail-fast): ``ca["subject_state"]`` direct read — silent ``.get(..., "")``
fallback 금지.
"""
from __future__ import annotations


def test_asset_readiness_reads_subject_state():
    """asset_readiness.py — legacy gaze_target read 폐기 + helper SOT 전환 + _STATE_LABELS constant 제거."""
    import app.core.asset_readiness as ar
    source = open(ar.__file__).read()
    # legacy gaze_target read 폐기 verify
    assert 'ca.get("gaze_target"' not in source, (
        "asset_readiness.py 안 legacy `ca.get(\"gaze_target\")` 잔존 — W5 미완료"
    )
    # subject_state helper 사용 verify
    assert "is_immobilized_state" in source, (
        "asset_readiness.py 가 is_immobilized_state helper import 안 함 — W5 SOT 미적용"
    )
    # _STATE_LABELS constant 도 제거 verify (사용자 강조 #1)
    assert "_STATE_LABELS" not in source, (
        "asset_readiness.py 안 _STATE_LABELS constant 잔존 — literal state tuple 폐기 의무 (사용자 강조 #1)"
    )


def test_scene_reference_service_reads_subject_state():
    """scene_reference_service.py — gaze_target read 폐기 + helper SOT + label 오염 중립화."""
    import app.services.scene_reference_service as srs
    source = open(srs.__file__).read()
    assert 'ca.get("gaze_target"' not in source, (
        "scene_reference_service.py 안 legacy `ca.get(\"gaze_target\")` 잔존 — W5 미완료"
    )
    assert "is_immobilized_state" in source, (
        "scene_reference_service.py 가 is_immobilized_state helper import 안 함 — W5 SOT 미적용"
    )
    # label 오염 중립화 verify (사용자 강조 #3) — "dead/unconscious bodies" prompt 표현 폐기
    assert "dead/unconscious bodies" not in source, (
        "scene_reference_service.py 안 'dead/unconscious bodies' 오염 prompt 표현 잔존 — 중립화 의무 (사용자 강조 #3)"
    )


def test_detail_steps_reads_subject_state():
    """detail_steps.py — _STATE_VARIANT_GAZE_VALUES tuple 폐기 + helper SOT + eyes→{state} wording 폐기."""
    import app.core.steps.detail_steps as ds
    source = open(ds.__file__).read()
    assert "_STATE_VARIANT_GAZE_VALUES" not in source, (
        "detail_steps.py 안 _STATE_VARIANT_GAZE_VALUES tuple 잔존 — literal state tuple 폐기 의무"
    )
    assert "is_immobilized_state" in source, (
        "detail_steps.py 가 is_immobilized_state helper import 안 함 — W5 SOT 미적용"
    )
    # eyes→{state} 잘못된 wording 폐기 verify (사용자 강조 #4) — v13 3 field labeling 도입
    assert "eyes→" not in source, (
        "detail_steps.py 안 'eyes→' wording 잔존 — v13 3 field labeling (gaze=/state=) 전환 의무 (사용자 강조 #4)"
    )
    # Gate 4 fail-fast — gaze_direction_kind 는 v13 schema required field
    # (schema.json:45 `required: [..., "gaze_direction_kind", "subject_state"]`)
    # silent default `.get(...)` 금지, KeyError = schema violation 의무
    assert "a.get('gaze_direction_kind'" not in source, (
        "detail_steps.py 안 `a.get('gaze_direction_kind', ...)` silent default 잔존 — "
        "v13 schema required field 직접 read 의무 (Gate 4 fail-fast)"
    )
    assert 'a.get("gaze_direction_kind"' not in source, (
        "detail_steps.py 안 `a.get(\"gaze_direction_kind\", ...)` silent default 잔존 — "
        "v13 schema required field 직접 read 의무 (Gate 4 fail-fast)"
    )


def test_render_prompt_card_docstring_sync():
    """render_prompt_card.py — docstring + comment 안 'gaze_target' 언급 → 'subject_state' sync."""
    import app.core.steps.render_prompt_card as rpc
    source = open(rpc.__file__).read()
    # docstring 안 "staging gaze_target" 언급 폐기 또는 subject_state 명시
    assert "staging gaze_target" not in source, (
        "render_prompt_card.py docstring 안 'staging gaze_target' 잔존 — v13 'staging subject_state' 로 sync 의무"
    )
    # comment line 2021 — 'gaze_target dead/unconscious 인물' → 'subject_state immobilized' 로 sync
    assert "gaze_target dead/unconscious" not in source, (
        "render_prompt_card.py comment 안 'gaze_target dead/unconscious' 잔존 — v13 'subject_state immobilized' 로 sync 의무"
    )
