"""검열로 거절된 cine 변환을 **다른 제공자로** 한 번 더 태운다 (2026-09-09).

## 왜 필요한가 — 실측

파청(한말 의병 실화, 66씬) 최종 i2i 에서 MAI-Image-2.6 변환 194건 중
**34건이 실패**했고 사유가 갈렸다:

    검열 24건 — ViolenceScore 14 · imagegen safety 6 · mainline 2
                 · DallEBlockList 2
    429   9건 — 재시도로 5건 회복
    기타   1건

전투·부상 묘사가 많은 작품은 **한 제공자 기준에 통째로 막힌다.** 재시도해도
같은 기준이라 안 풀린다. 사용자 지시: 「검열에 걸린 부분은 재시도해서 안 되면
grok image 2 로 해줘」.

## 여기서 재는 것

    ① 주 제공자와 **다른** 것이 나온다
    ② 주 제공자와 **같으면** 안 넘긴다 (같은 기준에 또 막힐 뿐 — 돈만 쓴다)
    ③ 설정이 비면 안 넘긴다 (종전 동작)
    ④ 모르는 제공자면 조용히 넘기지 않고 **안 쓴다**
"""
from __future__ import annotations

import pytest


def _f():
    from app.services.still_recipe_service import _cine_moderation_fallbacks
    return _cine_moderation_fallbacks


def test_주와_다른_제공자들을_순서대로_준다(monkeypatch):
    """★사용자 지시: 「검열 문제는 grok → seedream 으로 처리하자」."""
    from app.core.config import settings
    monkeypatch.setattr(settings, "still_cine_moderation_fallback_providers",
                        "grok,seedream", raising=False)
    got = _f()(main_provider="mai")
    assert [i[2]["provider"] for i in got] == ["grok", "seedream"], (
        f"순서가 다르다: {[i[2]['provider'] for i in got]}")
    for slot, client, ident in got:
        assert ident["provider"] != "mai"
        assert ident["model"], "물리 모델이 비었다"
        assert slot == f"fb_{ident['provider']}", (
            "슬롯이 제공자 이름이 아니다 — 순번으로 지으면 목록 순서를 바꿀 때 "
            "옛 기록이 다른 제공자 것으로 읽힌다")
        assert hasattr(client, "generate_image"), (
            "호출부가 쓰는 슬롯이 없다 — 대체 client 가 같은 모양이어야 한다")


def test_주와_같은_것은_목록에서_걸러진다(monkeypatch):
    """★같은 제공자로 다시 부르면 같은 기준에 또 막힌다 — 돈만 쓴다."""
    from app.core.config import settings
    monkeypatch.setattr(settings, "still_cine_moderation_fallback_providers",
                        "grok,seedream", raising=False)
    got = _f()(main_provider="grok")
    assert [i[2]["provider"] for i in got] == ["seedream"], got


def test_설정이_비면_안_넘긴다_종전_동작(monkeypatch):
    from app.core.config import settings
    monkeypatch.setattr(settings, "still_cine_moderation_fallback_providers",
                        "", raising=False)
    assert _f()(main_provider="mai") == []


def test_모르는_제공자는_조용히_안_넘긴다(monkeypatch, caplog):
    from app.core.config import settings
    monkeypatch.setattr(settings, "still_cine_moderation_fallback_providers",
                        "no-such-provider", raising=False)
    with caplog.at_level("WARNING"):
        assert _f()(main_provider="mai") == []
    assert any("모르는 제공자" in r.message or "모르는 제공자" in str(r)
               for r in caplog.records), "조용히 넘어갔다 — 로그가 없다"


def test_신원이_지문에_실릴_모양이다(monkeypatch):
    """★provider·endpoint·model 셋 다 있어야 한다 — 같은 문안·같은 원본이라도
    다른 제공자가 만든 그림은 **다른 산출**이라 지문이 그것을 봐야 한다."""
    from app.core.config import settings
    monkeypatch.setattr(settings, "still_cine_moderation_fallback_providers",
                        "grok,seedream", raising=False)
    for _slot, _c, ident in _f()(main_provider="mai"):
        assert set(ident) >= {"provider", "endpoint", "model"}, ident
