"""RPC reproduction_surface_rule shape gate (Area C migration 2026-05-12).

Producer (render_prompt_card.build_id_policy) 가 항상 다음 shape 출력 보장:
- require: {applies: bool, id_use: str, rationale_summary: str}
- deny: {applies_to_surfaces, source}
- future extra key 허용 (warning level, gate fail X)

External review (NEEDS_REVISION_MAJOR) flagged Important 3 — production
_assert_id_policy_shape did not deny these legacy/debug keys.
"""
import pytest

from app.core.steps.render_prompt_card import build_id_policy


def _make_element(dc: str) -> dict:
    return {
        "element": "test",
        "state": "neutral",
        "orientation": "front" if dc in {"content_surface", "reflective_surface"} else "",
        "camera_use": "ambient",
        "directionality_class": dc,
    }


@pytest.fixture
def sample_policy():
    return build_id_policy(
        visible_entities=["C01"],
        outlook_pairs=[{"character_id": "C01", "outlook_id": "O01"}],
        perception_mode=None,
        key_bg_elements=[_make_element("content_surface")],
        subject_reference_policies=[],
    )


def test_reproduction_surface_rule_is_dict(sample_policy):
    rule = sample_policy.get("reproduction_surface_rule")
    assert isinstance(rule, dict)


def test_applies_present_and_bool(sample_policy):
    rule = sample_policy["reproduction_surface_rule"]
    assert "applies" in rule
    assert isinstance(rule["applies"], bool)


def test_id_use_present_and_str(sample_policy):
    rule = sample_policy["reproduction_surface_rule"]
    assert "id_use" in rule
    assert isinstance(rule["id_use"], str)
    assert rule["id_use"]  # non-empty


def test_rationale_summary_present_and_str(sample_policy):
    rule = sample_policy["reproduction_surface_rule"]
    assert "rationale_summary" in rule
    assert isinstance(rule["rationale_summary"], str)
    assert rule["rationale_summary"]  # non-empty


def test_applies_to_surfaces_deny(sample_policy):
    """Area C migration 핵심 — applies_to_surfaces 회귀 차단."""
    rule = sample_policy["reproduction_surface_rule"]
    assert "applies_to_surfaces" not in rule


def test_source_deny(sample_policy):
    """Debug field source 회귀 차단 (Area C spec §2.7)."""
    rule = sample_policy["reproduction_surface_rule"]
    assert "source" not in rule


def test_current_builder_emits_only_3_keys(sample_policy):
    """현 builder 가 3 known key 만 출력 — future schema 진화 시 본 test 의도적 완화."""
    rule = sample_policy["reproduction_surface_rule"]
    known = {"applies", "id_use", "rationale_summary"}
    extra = set(rule.keys()) - known
    assert extra == set(), (
        f"현 builder 는 3 key 만 출력해야 하는데 extra={extra}. "
        f"새 key 추가 시 본 test 를 의도적으로 완화 (gate fail 아님)."
    )
