//! Minimal tier-1 decode. Shows the decoration sidecar without a
//! dialect registry — `decode_t1` skips hoisting and validation but
//! still parses and attaches decorations to value-tree paths.
//!
//! Run: `cargo run --example tier1_basic`

// What this shows:
//   - decode_t1 accepts tier-1 front matter with _dms_imports
//   - body is a plain tier-0 Value tree accessible via doc.t0.body
//   - decorator calls land in doc.decorators, keyed by path + sigil
//   - DecorationPosition (Leading / Inner / Trailing / Floating) is recorded per call

use dms::tier1::{decode_t1, DecorationPosition};
use dms::Value;

const SRC: &str = "\
+++
_dms_tier: 1
_dms_imports:
  + dialect: \"html\"
    version: \"1.0.0\"
    bind:
      \"|\": [\"tag\"]
+++
|tag(class: \"lede\")
title: \"Hello, DMS\"
port: 5432 |validates_range(1024, 65535)
";

fn main() {
    let doc = decode_t1(SRC).expect("parse failed");

    // Body is a plain tier-0 Value tree — access it through doc.t0.
    let body = match &doc.t0.body {
        Value::Table(t) => t,
        other => panic!("expected table body, got {:?}", other),
    };
    println!("=== body values ===");
    println!("  title = {:?}", body["title"]);
    println!("  port  = {:?}", body["port"]);

    // Decorations live in a separate sidecar, grouped by path.
    // Each DecoratorEntry holds the path + a sigil-keyed map of calls.
    println!("\n=== decorator sidecar ({} entries) ===", doc.decorators.len());
    for entry in &doc.decorators {
        // Format path as a human-readable breadcrumb.
        let path_str: Vec<String> = entry.path.iter().map(|seg| format!("{seg:?}")).collect();
        let path_display = if path_str.is_empty() {
            "<root>".to_string()
        } else {
            path_str.join(".")
        };
        println!("  path: {path_display}");

        for (sigil, calls) in &entry.decorators {
            for call in calls {
                let pos = match call.position {
                    DecorationPosition::Leading  => "leading",
                    DecorationPosition::Inner    => "inner",
                    DecorationPosition::Trailing => "trailing",
                    DecorationPosition::Floating => "floating",
                };
                // Without a registry the family field is empty (not resolved).
                println!(
                    "    sigil={sigil:?}  fn={:?}  position={pos}  params={} group(s)",
                    call.fn_name,
                    call.params.len()
                );
            }
        }
    }

    // Imports were parsed from _dms_imports and validated.
    println!("\n=== imports ({} entry) ===", doc.imports.imports.len());
    for imp in &doc.imports.imports {
        println!("  dialect={:?}  version={:?}", imp.dialect, imp.version);
        for (sigil, families) in &imp.bind {
            println!("    bind {sigil:?} -> {families:?}");
        }
    }
}
