"""D6 T3 — master_plan prompt schema 검증.

prompt 가 enum 강제 + raw intent fields 의무 출력하는지 — schema-only test
(LLM call 자체는 integration test 에서).

spec: docs/superpowers/specs/2026-05-09-deterministic-bg-id-and-catalog-lineage.md §4.4
plan: T3 (B6 atomic)
"""
from __future__ import annotations

import json
from pathlib import Path

import app.modules.prompt_loader as prompt_loader


def _latest_master_plan_dir() -> Path:
    base = prompt_loader.PROMPTS_BASE / "background_master_plan"
    versions = sorted(
        [p for p in base.iterdir() if p.is_dir()],
        key=lambda d: prompt_loader._version_sort_key(d.name),
        reverse=True,
    )
    assert versions, "background_master_plan 의 prompt version 0건"
    return versions[0]


def test_master_plan_prompt_includes_state_class_enum():
    """현재 활성 master_plan prompt 가 state_class enum 11 개 모두 명시."""
    from app.core.bg_state_vocab import STATE_CLASS_ENUM

    latest = _latest_master_plan_dir()
    text = (latest / "system.md").read_text(encoding="utf-8")
    for enum_val in STATE_CLASS_ENUM:
        assert enum_val in text, f"state_class enum {enum_val!r} 누락 in {latest}"


def test_master_plan_prompt_demands_raw_intent_fields():
    """prompt 가 raw intent 출력 의무 명시 — loc_id/space_key_hint/time_phase/state_class/applies_to_shots."""
    latest = _latest_master_plan_dir()
    text = (latest / "system.md").read_text(encoding="utf-8")
    required = [
        "loc_id", "space_key_hint", "time_phase", "state_class",
        "applies_to_shots", "sub_location_label", "state_label_raw",
    ]
    for field in required:
        assert field in text, f"raw intent field {field!r} 누락 in {latest}"


def test_master_plan_prompt_forbids_bg_id_output():
    """prompt 는 LLM 이 bg_id 를 만들지 못하도록 명시."""
    latest = _latest_master_plan_dir()
    text = (latest / "system.md").read_text(encoding="utf-8")
    # `bg_id` 관련 강제 문구 — code-assigned / 출력 금지 / 코드가 부여
    assert "bg_id" in text
    assert any(p in text for p in [
        "코드가 후처리에서 부여", "코드가 부여", "code-assigned",
        "do not output bg_id", "출력하지 않", "출력 금지",
    ]), f"bg_id 출력 금지 명시 누락 in {latest}/system.md"


def test_master_plan_schema_has_no_bg_id_in_backgrounds():
    """schema.json 의 backgrounds.items 에 bg_id field 없어야 (raw intent only)."""
    latest = _latest_master_plan_dir()
    schema = json.loads((latest / "schema.json").read_text(encoding="utf-8"))
    bg_props = schema["properties"]["backgrounds"]["items"]["properties"]
    assert "bg_id" not in bg_props, (
        f"D6 raw intent schema 위반: backgrounds.items 에 bg_id property "
        f"존재 — LLM 이 bg_id 만들 수 있음 (D6 contract 위반)"
    )


def test_master_plan_schema_state_class_enum_matches_vocab():
    """schema 의 state_class enum 이 STATE_CLASS_ENUM 과 일치."""
    from app.core.bg_state_vocab import STATE_CLASS_ENUM

    latest = _latest_master_plan_dir()
    schema = json.loads((latest / "schema.json").read_text(encoding="utf-8"))
    bg_props = schema["properties"]["backgrounds"]["items"]["properties"]
    state_class_def = bg_props.get("state_class") or {}
    schema_enum = set(state_class_def.get("enum") or [])
    assert schema_enum == set(STATE_CLASS_ENUM), (
        f"schema state_class enum drift — {schema_enum ^ set(STATE_CLASS_ENUM)}"
    )


def test_master_plan_schema_space_key_hint_enum_matches_vocab():
    """schema 의 space_key_hint enum 이 LOCATION_SPACE_KEY_VOCAB 과 일치."""
    from app.core.bg_state_vocab import LOCATION_SPACE_KEY_VOCAB

    latest = _latest_master_plan_dir()
    schema = json.loads((latest / "schema.json").read_text(encoding="utf-8"))
    bg_props = schema["properties"]["backgrounds"]["items"]["properties"]
    hint_def = bg_props.get("space_key_hint") or {}
    schema_enum = set(hint_def.get("enum") or [])
    assert schema_enum == set(LOCATION_SPACE_KEY_VOCAB), (
        f"schema space_key_hint enum drift — {schema_enum ^ set(LOCATION_SPACE_KEY_VOCAB)}"
    )
