"""W22 W4a coordinator 배선 helper 결정론 테스트 (Codex NARROW_1 잠금)."""

from app.services.scene_generation_coordinator import (
    _direct_resolver_prompts,
    _insert_outdoor_canon_refs,
)


def _od():
    return {
        "prompt": "DIRECT-9절",
        "master_bytes": b"MASTER",
        "map_bytes": b"MAP",
        "master_asset_id": "asset-master",
        "map_asset_id": "asset-map",
        "place_id": "g1",
    }


def test_resolver_prompts_use_direct_prompt_when_od():
    """직행 = [9절]+scene_detail 원 프롬프트 union (2026-07-10 RCV 실측 fix).

    9절은 ID-free 라 resolver 의 C##O## 정규식 캐릭터 매칭이 불가능 —
    캐릭터/아웃룩 해석은 ID 보유 scene_detail 프롬프트가 담당해야 한다.
    """
    assert _direct_resolver_prompts(_od(), ["var1", "var2"]) == [
        "DIRECT-9절", "var1", "var2",
    ]


def test_resolver_prompts_fallback_without_od():
    assert _direct_resolver_prompts(None, ["var1"]) == ["var1"]
    assert _direct_resolver_prompts({"prompt": ""}, ["var1"]) == ["var1"]


def test_insert_canon_refs_order_parity_and_lineage():
    labeled_refs = [("CHAR", b"c")]
    attached_meta = [("character", "C01")]
    ref_roles = ["character_ref"]
    ref_role_metadata = [{}]

    _insert_outdoor_canon_refs(
        labeled_refs, attached_meta, ref_roles, ref_role_metadata, _od(),
        scene_index=3, shot_index=1, where="test",
    )

    # 4-list parity + 순서: index0=실사 마스터(룩), index1=맵(배치), 기존 ref 뒤로
    assert len(labeled_refs) == len(attached_meta) == len(ref_roles) \
        == len(ref_role_metadata) == 3
    assert labeled_refs[0][1] == b"MASTER" and "LOCATION PHOTOGRAPH" in labeled_refs[0][0]
    assert labeled_refs[1][1] == b"MAP" and "SITE PLAN" in labeled_refs[1][0]
    assert labeled_refs[2] == ("CHAR", b"c")
    # attached kind=background + outdoor_canon: prefix (RCV waiver 계약)
    assert attached_meta[0] == ("background", "outdoor_canon:g1")
    assert attached_meta[1] == ("background", "outdoor_canon:g1")
    assert ref_roles[:2] == ["outdoor_canon_photo_ref", "outdoor_canon_map_ref"]
    # asset_id lineage stamp
    assert ref_role_metadata[0]["asset_id"] == "asset-master"
    assert ref_role_metadata[1]["asset_id"] == "asset-map"
    assert ref_role_metadata[0]["pipeline_role"] == "outdoor_canon_photo"
    assert ref_role_metadata[1]["pipeline_role"] == "outdoor_canon_map"


def test_insert_canon_refs_missing_asset_id_omitted():
    od = _od()
    od["master_asset_id"] = ""
    lr, am, rr, rm = [], [], [], []
    _insert_outdoor_canon_refs(
        lr, am, rr, rm, od, scene_index=3, shot_index=1, where="test",
    )
    assert "asset_id" not in rm[0]  # 미해결 시 생략 (unresolved lineage 계약)
    assert rm[1]["asset_id"] == "asset-map"
