//! Emoji-decorator showcase. Decodes a small deploy config that uses
//! 🚀 / ♻️ / ⚡ / 🔒 as decorator sigils, prints the body and the
//! decorator sidecar.
//!
//! Run: `cargo run --example tier1_emoji_sigils`

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

const SRC: &str = "+++
_dms_tier: 1
_dms_imports:
  + dialect: \"deploy\"
    version: \"1.0.0\"
    bind:
      \"🚀\": [\"target\"]
      \"⚡\": [\"perf\"]
      \"🔒\": [\"auth\"]
      \"📊\": [\"metrics\"]
+++

🚀target(env: \"prod\", region: \"us-east-1\")
⚡perf(p99_target_ms: 200)
🔒auth(role: \"user\")
📊metrics(name: \"api_latency\")
api_service: \"registry.example.com/api:v3.2.1\"

🚀target(env: \"staging\")
🔒auth(role: \"developer\")
staging_service: \"registry.example.com/api:experimental\"
";

fn position_label(p: DecorationPosition) -> &'static str {
    match p {
        DecorationPosition::Leading => "leading",
        DecorationPosition::Inner => "inner",
        DecorationPosition::Trailing => "trailing",
        DecorationPosition::Floating => "floating",
    }
}

fn print_value(v: &Value, indent: usize) {
    let pad = "  ".repeat(indent);
    match v {
        Value::String(s) => println!("{pad}\"{s}\""),
        Value::Integer(n) => println!("{pad}{n}"),
        Value::Bool(b) => println!("{pad}{b}"),
        Value::Float(f) => println!("{pad}{f}"),
        Value::Table(t) => {
            for (k, v) in t {
                println!("{pad}{k}:");
                print_value(v, indent + 1);
            }
        }
        Value::List(l) => {
            for (i, v) in l.iter().enumerate() {
                println!("{pad}[{i}]");
                print_value(v, indent + 1);
            }
        }
        other => println!("{pad}{other:?}"),
    }
}

fn main() {
    let doc = decode_t1(SRC).expect("emoji-decorated source must parse");

    println!("=== body (post-parse, pre-hoist) ===");
    print_value(&doc.t0.body, 0);

    println!("\n=== imports ({} entry/entries) ===", 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:?}");
        }
    }

    println!("\n=== decorator sidecar ({} node(s) decorated) ===", doc.decorators.len());
    for entry in &doc.decorators {
        println!("  path: {:?}", entry.path);
        for (sigil, calls) in &entry.decorators {
            for call in calls {
                println!(
                    "    {sigil}{}  pos={}  family={:?}",
                    call.fn_name,
                    position_label(call.position),
                    call.family,
                );
                for (i, group) in call.params.iter().enumerate() {
                    match group {
                        dms::tier1::ParamGroup::Named(m) if !m.is_empty() => {
                            println!("      params[{i}] (named): {m:?}");
                        }
                        dms::tier1::ParamGroup::Positional(v) if !v.is_empty() => {
                            println!("      params[{i}] (positional): {v:?}");
                        }
                        _ => {}
                    }
                }
            }
        }
    }
}
