#!/usr/bin/env python3
from __future__ import annotations

import sys
import unittest
from pathlib import Path


HERE = Path(__file__).resolve().parent
if str(HERE) not in sys.path:
    sys.path.insert(0, str(HERE))

from prompt_stack_runtime import audit_plan_against_prompt_stack  # noqa: E402


FORTUNE_PROMPT = (
    "Build a simple but fun one-page interactive Founder Fortune Cookie. "
    "It should feel playful and polished, with a big fortune cookie at the center, "
    "a crack-open interaction, and 6 witty startup fortunes people can cycle through."
)


def build_base_plan(*engines: str) -> dict:
    sections = []
    for index, engine in enumerate(engines, start=1):
        sections.append(
            {
                "id": f"section-{index}",
                "title": f"Section {index}",
                "content": {
                    "headline": f"Section {index}",
                    "body": "Test section",
                },
                "components": [
                    {
                        "engine": engine,
                        "instance_id": f"component-{index}",
                        "role": "Test component",
                        "data": {},
                    }
                ],
            }
        )
    return {
        "meta": {
            "title": "Founder Fortune Cookie",
            "description": "Playful startup fortune artifact",
            "narrative_spine": {
                "source": "planned",
                "core_thesis": "Playful startup wisdom can be memorable.",
                "audience": "Founders",
                "desired_action": "Reveal fortunes",
                "throughlines": ["Playful", "Fortunes"],
                "must_keep_facts": ["6 fortunes"],
                "must_not_claim": [],
                "key_entities": ["fortune cookie"],
                "claim_map": [{"claim": "Reveal fortunes", "support_sections": [1]}],
                "closing_obligation": "Keep it fun",
                "section_jobs": [
                    {"section_index": index - 1, "title": f"Section {index}", "job": "Do the thing"}
                    for index in range(1, len(sections) + 1)
                ],
            },
        },
        "theme": "forest",
        "wrapper": {"engine": "12"},
        "sections": sections,
    }


class PromptStackAuditTests(unittest.TestCase):
    def test_fun_fortune_prompt_rejects_forms_counters_and_missing_reveal_card_engine(self) -> None:
        plan = build_base_plan("34", "35", "16")
        audit = audit_plan_against_prompt_stack(plan=plan, prompt=FORTUNE_PROMPT)
        warning_types = {warning.get("type") for warning in audit.get("warnings") or []}

        self.assertTrue(audit.get("critical"))
        self.assertTrue(audit.get("should_retry"))
        self.assertIn("reveal_card_mismatch", warning_types)
        self.assertIn("form_scope_drift", warning_types)
        self.assertIn("unsupported_metric_surface", warning_types)

    def test_fun_fortune_prompt_rejects_before_after_slider(self) -> None:
        plan = build_base_plan("14")
        audit = audit_plan_against_prompt_stack(plan=plan, prompt=FORTUNE_PROMPT)
        warning_types = {warning.get("type") for warning in audit.get("warnings") or []}

        self.assertTrue(audit.get("critical"))
        self.assertIn("before_after_scope_drift", warning_types)

    def test_explicit_form_prompt_allows_form_engine(self) -> None:
        prompt = "Build a short newsletter signup landing page with a simple email form and playful copy."
        plan = build_base_plan("16")
        audit = audit_plan_against_prompt_stack(plan=plan, prompt=prompt)
        warning_types = {warning.get("type") for warning in audit.get("warnings") or []}

        self.assertNotIn("form_scope_drift", warning_types)

    def test_reveal_card_prompt_passes_when_flashcard_engine_is_used(self) -> None:
        plan = build_base_plan("13")
        audit = audit_plan_against_prompt_stack(plan=plan, prompt=FORTUNE_PROMPT)
        warning_types = {warning.get("type") for warning in audit.get("warnings") or []}

        self.assertNotIn("reveal_card_mismatch", warning_types)


if __name__ == "__main__":
    unittest.main()
