"""표기 정책 팩 계약 — 2026-09-20 사용자 지시 (v42/v43).

> "본래 의도는 자막 처럼 풍선모양 형태로 들어가는등 이상한 문자가 들어가는
>  것을 방지 하기 위함이야, 이제는 글자가 들어가는게 당연한 것 같아."

막을 것은 **사진 위에 얹히는 것**이고, 화면 안 실물 표기는 허용한다.
이 시험이 잠그는 것 셋:

1. 옛 전면 금지("No readable writing anywhere" / "No readable wording
   anywhere")가 **어느 스템에도 되살아나지 않는다.** 이 어구가 바로
   2026-08-27 에 사용자가 v20 에서 푼 제약을 되잠근 문장이다.
2. `no_text` 와 `no_text_none` 이 **같은 정책**을 말한다 — 저작 문안이
   있고 없고에 따라 같은 로고가 허용됐다 금지됐다 하지 않는다(정책 불연속,
   Codex 설계 리뷰).
3. 현행 selector 디렉토리에 **스템이 다 있다.** loader 는 명시 버전에서
   빠진 파일을 옛 판으로 찾아주지 않는다(prompt_loader 계약) — 하나라도
   빠지면 그 경로가 통째로 죽는다.
"""
import pytest

from app.modules.pipeline.still_recipe import (
    TEXT_POLICY_GROK_PROMPT_VERSION,
    TEXT_POLICY_PROMPT_VERSION,
    resolve_prompt_version,
)
from app.modules.prompt_loader import load_prompt

# 되살아나면 안 되는 어구 — 결함을 **이름으로** 적는다.
BANNED = ("No readable writing anywhere", "No readable wording anywhere")
# 사진 위에 얹히는 것 — 사용자가 본래 막으려던 것.
OVERLAY_WORDS = ("caption", "watermark", "overlay")

GENERAL_STEMS = ("no_text", "no_text_none", "bg_reproject_tail",
                 "bg_fill_tail", "groupbg_tail")
GROK_STEMS = ("no_text", "no_text_none")


def _load(stem: str, selector: str) -> str:
    return load_prompt(
        "still_recipe", stem, version=resolve_prompt_version(selector))


@pytest.mark.parametrize("stem", GENERAL_STEMS)
def test_general_stem_exists_and_drops_the_blanket_ban(stem):
    body = _load(stem, TEXT_POLICY_PROMPT_VERSION)
    assert body.strip(), f"{stem} 이 비었다"
    for phrase in BANNED:
        assert phrase not in body, (
            f"{stem} 에 옛 전면 금지가 되살아났다: {phrase!r}")


@pytest.mark.parametrize("stem", GROK_STEMS)
def test_grok_stem_exists_and_drops_the_blanket_ban(stem):
    body = _load(stem, TEXT_POLICY_GROK_PROMPT_VERSION)
    assert body.strip(), f"grok/{stem} 이 비었다"
    for phrase in BANNED:
        assert phrase not in body, (
            f"grok/{stem} 에 옛 전면 금지가 되살아났다: {phrase!r}")


@pytest.mark.parametrize("selector", [TEXT_POLICY_PROMPT_VERSION,
                                      TEXT_POLICY_GROK_PROMPT_VERSION])
def test_two_branches_say_the_same_policy(selector):
    """저작 문안의 유무가 **다른 정책**을 부르면 안 된다.

    반례(이 시험이 막는 것): `no_text_none` 만 풀고 `no_text` 를 옛
    「저작 문안만 읽히고 나머지는 가려라」로 두면, 문안이 한 줄 있는
    샷에서만 같은 로고가 금지된다.
    """
    with_words = _load("no_text", selector)
    without = _load("no_text_none", selector)
    # 양쪽 다 얹히는 것을 막는다
    for word in OVERLAY_WORDS:
        assert word in with_words.lower(), f"no_text 에 {word} 금지가 없다"
        assert word in without.lower(), f"no_text_none 에 {word} 금지가 없다"
    # 양쪽 다 「실물 표기는 읽혀도 된다」를 말한다
    for body, name in ((with_words, "no_text"), (without, "no_text_none")):
        assert "may" in body and "readable" in body, (
            f"{name} 이 실물 표기 허용을 말하지 않는다")
    # 양쪽 다 문자 체계를 그 물건 것으로 고정한다
    for body, name in ((with_words, "no_text"), (without, "no_text_none")):
        assert "script" in body, f"{name} 에 문자 체계 조항이 없다"


def test_bg_fill_keeps_its_other_contract():
    """배경 채움의 **제작용 표식 제거**는 글자 정책과 다른 계약이다.

    스케치의 도식 기호·선·마커는 실제 장소의 간판이 아니다 — 글자를
    허용한다고 이것까지 같이 풀면 도면 기호가 최종 그림에 남는다.
    """
    body = _load("bg_fill_tail", TEXT_POLICY_PROMPT_VERSION)
    assert "sketch" in body and "marker" in body, (
        "bg_fill_tail 이 제작용 표식 제거 조항을 잃었다")


def test_groupbg_does_not_freeze_one_shots_wording():
    """공유 배경에 한 샷만 필요한 문구를 박아 넣지 않는다."""
    body = _load("groupbg_tail", TEXT_POLICY_PROMPT_VERSION)
    assert "shared" in body.lower(), (
        "groupbg_tail 에 공유 배경 조항이 없다")
