"""G3.2 Phase 6 (Task 20) — step_manifest DAG 재배치 검증.

Round 4/5 override 반영 후의 manifest 상태를 본 테스트가 lock-in 한다:

- scene_detail.order: 20 → 21.70 (background_prompt 21.60 직후)
- shot_dependency_t2i.order: 20.5 → 21.71
- t2i_review.order: 20.7 → 21.72
- scene_detail.depends_on 에 ``background_prompt`` 추가 (round 2 #1).
- scene_detail.allow_partial_downstream = False (round 2 #6, contract_violation
  partial 시 downstream cascade stop).
- scene_detail.schema_version = 7 (G3.2: owned_validation field; G4.1: render_prompt_card + hash top-level).
- background_prompt.schema_version = 2 명시 (single source of truth — schema bump).

DAG 정합성: background_prompt 가 scene_detail 보다 strictly 앞에 오도록
order 가 보장되어야 loader (`_load_chain_bg_owned_by_shot`) 가 bp_cp 를
신뢰하고 scene_detail 진입 시 fail-fast 할 수 있다 (Round 4 BLOCKING 1).
"""

import pytest

from app.core.step_manifest import STEP_MANIFEST


def test_scene_detail_order_relocated_to_21_70():
    """scene_detail order 20 → 21.70."""
    assert STEP_MANIFEST["scene_detail"]["order"] == 21.70


def test_shot_dependency_t2i_order_relocated_to_21_71():
    """shot_dependency_t2i order 20.5 → 21.71."""
    assert STEP_MANIFEST["shot_dependency_t2i"]["order"] == 21.71


def test_t2i_review_order_relocated_to_21_72():
    """t2i_review order 20.7 → 21.72."""
    assert STEP_MANIFEST["t2i_review"]["order"] == 21.72


def test_scene_detail_depends_on_background_prompt():
    """scene_detail.depends_on 에 background_prompt 추가 (G3.2 round 2 #1)."""
    deps = STEP_MANIFEST["scene_detail"]["depends_on"]
    assert "background_prompt" in deps, (
        f"scene_detail.depends_on 에 background_prompt 누락: {deps}"
    )


def test_scene_detail_preserves_existing_depends():
    """기존 6 종 dep 보존 (배경 + scene_consistency + outlook 등)."""
    deps = set(STEP_MANIFEST["scene_detail"]["depends_on"])
    expected_existing = {
        "shot_dependency", "shot_director", "outlook_phase3",
        "entity_t2i", "shot_staging", "scene_consistency",
    }
    missing = expected_existing - deps
    assert not missing, f"기존 deps 손실: {missing}"


def test_scene_detail_allow_partial_downstream_false():
    """contract_violation partial 시 downstream cascade stop (round 2 #6)."""
    assert STEP_MANIFEST["scene_detail"].get("allow_partial_downstream") is False


def test_scene_detail_schema_version_13():
    """reference-necessity Phase 2 (2026-05-23): schema 12 → 13 (render_prompt_card
    가 episode_reference_policy overlay 반영 — text_only subject 의 id_policy/
    asset_requirements 변동 + card hash semantics 변경 → 구 cp invalidation).

    Prior history: G3.2 5→6 / G4.1 6→7 / D6 T5d 7→8 / area-frame-spatial-contract
    T5 8→9 (applied_frame_spatial_constraint_ids required) / Area #1 W5 9→10
    (id_policy.subject_reference_policy) / Area #5 W1 10→11
    (reference_phrase_kinds) / C2 v1 11→12 (owned_object_usage).
    """
    assert STEP_MANIFEST["scene_detail"].get("schema_version") == 13


def test_background_prompt_manifest_schema_version_matches_step():
    """STEP_MANIFEST 의 background_prompt entry schema_version 이 step 본체와 일치.

    History:
        G3.2 (2026-05-04): 1→2 (objects_owned_by_background 추가).
        D6 v6 (2026-05-09): 2→3 (bg_id pattern → BG_ID_RE + state_label_raw 통합).

    SOT 직접 import — 향후 SCHEMA_VERSION bump 시 본 assertion drift 자동 차단.
    """
    from app.core.steps.background_prompt_step import (
        SCHEMA_VERSION as STEP_SCHEMA_VERSION,
    )
    assert (
        STEP_MANIFEST["background_prompt"].get("schema_version")
        == STEP_SCHEMA_VERSION
    ), (
        f"manifest.background_prompt.schema_version 가 step 본체 "
        f"(={STEP_SCHEMA_VERSION}) 와 불일치 — got "
        f"{STEP_MANIFEST['background_prompt'].get('schema_version')!r}. "
        f"resume 시 cp_mismatch BLOCK 위험."
    )


def test_dag_background_prompt_strictly_before_scene_detail():
    """DAG 정합성: background_prompt order < scene_detail order.

    Round 4 BLOCKING 1 — bg-on + bp_cp is None 일 때 loader 가 fail-fast 하려면
    scene_detail 진입 시점에는 background_prompt 가 이미 실행 완료 상태여야 한다.
    order 가 잘못 배치되면 DAG 가 inconsistent — depends_on 만으로는 부족하고
    실제 ordering 도 보장되어야 한다.
    """
    bp_order = STEP_MANIFEST["background_prompt"]["order"]
    sd_order = STEP_MANIFEST["scene_detail"]["order"]
    assert bp_order < sd_order, (
        f"background_prompt(order={bp_order}) 가 scene_detail(order={sd_order})"
        f" 보다 앞이어야 한다 — DAG inconsistent."
    )
