"""최종 자산의 **출처가 실행과 같은가** (감사 0-B).

## 왜 이 시험이 있나 (2026-08-26 실측)

「골목 끝」 주행의 primary 자산 7/7 이 이렇게 기록돼 있었다.

    generation_model : x-ai/grok-imagine-image-2.0   ← 실제는 reve/2.1/edit
    prompt_used      : 빈 문자열                      ← 실제는 변환 문안 전문
    generation_call_id: (올바름 — reve 호출을 정확히 가리킴)

운영 화면과 사후 분석에서 **「grok 이 빈 프롬프트로 최종 이미지를 만들었다」**
고 읽힌다. 원인은 두 자리다.

1. `generation_model` 이 변환 적용 시 설정값(`grok_image_model`)을 박았다.
   변환 제공자가 교체 가능해진 뒤로 실행과 어긋났다 — 바로 위 주석은
   「변환 모델 유지」라고 말하고 있었고 코드만 안 따라왔다.
2. `prompt_used` 가 바깥 `cine_prompt` 를 썼는데, 연출 재료를 넘기는 판에서
   그 값은 **의도적으로 빈 값**이다(문안이 샷마다 달라 루프 안에서 만든다).

여기서 잠그는 계약은 하나다 — **최종 bytes 를 만든 호출의 값이 SOT** 다.
"""

from app.services.still_recipe_service import resolve_generation_model


_GROK = "x-ai/grok-imagine-image-2.0"
_GEM = "gemini-3.1-flash-image-preview"
_REVE = "reve/2.1/edit"


def _resolve(**over):
    base = dict(
        cine_applied=False, cine_model="", cine_call_model="",
        ladder_model="",
        still_image_backend="nb2", gg46_judge_on=False, fix_won=False,
        grok_model=_GROK, gemini_model=_GEM,
    )
    base.update(over)
    return resolve_generation_model(**base)   # type: ignore[arg-type]


def test_변환이_적용되면_변환한_모델이_기록된다():
    """★이 시험이 없어서 7/7 이 grok 으로 남았다."""
    assert _resolve(cine_applied=True, cine_model=_REVE) == _REVE


def test_변환_모델이_grok_이면_grok_으로_남는다():
    """제공자를 바꿔도 **실제 호출한 것**을 따른다 — 설정 추정이 아니다."""
    assert _resolve(cine_applied=True, cine_model=_GROK) == _GROK


def test_실제_호출의_모델이_record_보다_우선이다():
    """★generation_call_id 가 가리키는 호출이 SOT (Codex BLOCK-3)."""
    assert _resolve(cine_applied=True, cine_model=_GROK,
                    cine_call_model=_REVE) == _REVE


def test_모델을_모르면_설정값으로_추측하지_않고_비운다():
    """★설정값을 적으면 빈 칸보다 **더 확정적인 거짓 기록**이 된다.

    backfill 은 `image_asset` 만 고치고 `records.json` 은 그대로다 —
    옛 record 를 다음 JIT 영속이 재사용하면 같은 거짓말이 재발한다.
    `generation_model` 은 nullable 이므로 모르면 비운다.
    """
    assert _resolve(cine_applied=True, cine_model="",
                    cine_call_model="") is None


def test_변환이_없으면_사다리가_실제로_성공한_모델을_따른다():
    assert _resolve(ladder_model=_GROK) == _GROK
    assert _resolve(ladder_model=_GEM) == _GEM


def test_사다리보다_변환이_우선이다():
    """최종 bytes 를 만든 것은 변환이다."""
    assert _resolve(
        cine_applied=True, cine_model=_REVE, ladder_model=_GEM) == _REVE


def test_grok2_백엔드는_grok_으로_남는다():
    assert _resolve(still_image_backend="grok2") == _GROK


def test_gg46_에서_수리가_최종이면_grok_i2i_산출이다():
    assert _resolve(gg46_judge_on=True, fix_won=True) == _GROK
    # 수리가 안 이겼으면 롤 백엔드 그대로.
    assert _resolve(gg46_judge_on=True, fix_won=False) == _GEM


def test_기본_nb2_롤은_gemini():
    assert _resolve() == _GEM
