"""YAML loading example: define static structure in YAML, inject dynamic content in Python.

Best for reusable prompt templates where the structure is fixed but the
input data, context, and history change per request.
"""

from prompt_builder import (
    ContextBlock,
    InputData,
    Message,
    TokenBudget,
    compile,
    loads,  # parse YAML string
    # load,  # or load("path/to/file.prompt.yaml") for files
)

# ── Define the static prompt skeleton in YAML ────────────────────────────

SUMMARIZER_YAML = """\
version: "0.1.0"

persona:
  role: Technical writer specializing in clear, concise summaries.
  tone: professional, neutral
  domain:
    - technical writing
    - software documentation
  anti_patterns:
    - Don't add information not present in the source
    - Don't use marketing language

rules:
  - constraint: Summary must be shorter than the original
    priority: hard
  - constraint: Preserve all numerical data and proper nouns exactly
    priority: hard
  - constraint: Use active voice
    priority: soft

instruction:
  task: Summarize the provided document into key points.
  subtasks:
    - Identify the main thesis or purpose
    - Extract 3-5 key findings or decisions
    - Note any action items or deadlines
  intent: Give a busy reader the essential information in 60 seconds.

output_spec:
  format: markdown
  length: 3-5 bullet points, max 200 words
  constraints:
    - Start with a one-sentence TL;DR
    - Each bullet must be self-contained

examples:
  - input: |
      Meeting notes from Q3 planning. The team decided to migrate from
      PostgreSQL to CockroachDB by November 15. Budget approved at $45k.
      John will lead the migration. Risk: downtime during cutover.
    output: |
      **TL;DR:** Team approved a $45k database migration to CockroachDB by Nov 15.

      - **Decision:** Migrate from PostgreSQL to CockroachDB
      - **Budget:** $45,000 approved
      - **Owner:** John leading the migration
      - **Deadline:** November 15
      - **Risk:** Potential downtime during cutover
    weight: 1.0

priority:
  context: cut_by_relevance
  examples: cut_by_weight
  history: truncate_oldest
  persona: never_cut
  rules: never_cut
  instruction: never_cut
  output_spec: never_cut
  input_data: never_cut
"""

# ── Load and inject dynamic content ──────────────────────────────────────

def summarize(document: str, related_docs: list[str] | None = None):
    """Load the YAML skeleton, inject the document, compile."""

    # Parse YAML into a Prompt object
    prompt = loads(SUMMARIZER_YAML)

    # Inject the document to summarize
    prompt.input_data = InputData(
        content=document,
        format="plain",
        label="document",
    )

    # Optionally add related docs as context (for cross-referencing)
    if related_docs:
        for i, doc in enumerate(related_docs):
            prompt.context.append(ContextBlock(
                content=doc,
                source=f"related_doc_{i}",
                relevance=0.5,  # lower priority than the main document
            ))

    # Inject conversation history if this is a multi-turn refinement
    prompt.history = [
        Message(role="user", content="Can you summarize the architecture doc?"),
    ]

    result = compile(prompt, TokenBudget(context_window=4_000))

    print(result.report())
    print("\n--- Compiled messages ---")
    for msg in result.messages:
        print(f"\n[{msg['role']}]")
        print(msg["content"])


# ── Run it ───────────────────────────────────────────────────────────────

if __name__ == "__main__":
    sample_doc = """
    Sockudo Architecture Overview

    Sockudo is a WebSocket infrastructure service written in Rust that provides
    Pusher-compatible APIs. The system uses a sharded architecture where channels
    are distributed across nodes via consistent hashing.

    Key components:
    - Gateway layer: Accepts WebSocket connections, handles protocol upgrades
    - Router: Maps channels to shards using consistent hashing (Rendezvous)
    - Pub/Sub backbone: Redis Streams for inter-node message delivery
    - Presence engine: Tracks online users per channel with CRDTs

    Performance targets: 100k concurrent connections per node, p99 < 10ms for
    message delivery, horizontal scaling to 50+ nodes.

    The v0.2 release (planned Q1 2026) will add webhook delivery, channel
    encryption, and a REST API for server-side publishing.
    """

    summarize(sample_doc, related_docs=[
        "The Pusher protocol uses a JSON-based message format with event types: pusher:subscribe, pusher:unsubscribe, pusher:ping.",
        "Redis Streams were chosen over Redis Pub/Sub for durability and consumer group support.",
    ])
