//! Walk the StreamEvent iterator produced by decode_t1_streaming.
//!
//! Prints one line per event with indentation showing container depth.
//! Demonstrates that Leaf events carry `decorations: Option<DecoratorEntry>`
//! for nodes that have a sidecar entry.
//!
//! Run: `cargo run --example tier1_streaming`

// What this shows:
//   - decode_t1_streaming returns a StreamingIter that yields StreamEvent values
//   - EnterContainer / LeaveContainer delimit Table and List containers
//   - Leaf events carry the scalar value and any attached decorator sidecar entry
//   - EndOfDocument carries root-level floating decorations

use dms::tier1_stream::{decode_t1_streaming, StreamEvent, ContainerKind};
use dms::BreadcrumbSegment;

const SRC: &str = "\
+++
_dms_tier: 1
_dms_imports:
  + dialect: \"html\"
    version: \"1.0.0\"
    bind:
      \"|\": [\"tag\"]
+++
title: \"DMS streaming demo\" |note()
items:
  + \"alpha\"
  + \"beta\"
meta:
  version: 3
  active: true
";

fn path_display(path: &[BreadcrumbSegment]) -> String {
    if path.is_empty() {
        return "<root>".into();
    }
    path.iter()
        .map(|seg| match seg {
            BreadcrumbSegment::Key(k) => k.clone(),
            BreadcrumbSegment::Index(i) => format!("[{i}]"),
        })
        .collect::<Vec<_>>()
        .join(".")
}

fn main() {
    let iter = decode_t1_streaming(SRC).expect("parse failed");

    let mut depth: usize = 0;

    for event in iter {
        let indent = "  ".repeat(depth);
        match &event {
            StreamEvent::FrontMatter { meta } => {
                println!("{indent}FrontMatter  ({} key(s))", meta.len());
            }
            StreamEvent::EnterContainer { path, kind, decorations } => {
                let kind_str = match kind {
                    ContainerKind::Table => "Table",
                    ContainerKind::List  => "List",
                };
                let dec_note = if decorations.is_some() { "  [has decorations]" } else { "" };
                println!(
                    "{indent}EnterContainer  path={:?}  kind={kind_str}{dec_note}",
                    path_display(path)
                );
                depth += 1;
            }
            StreamEvent::LeaveContainer { path, kind } => {
                depth = depth.saturating_sub(1);
                let indent = "  ".repeat(depth);
                let kind_str = match kind {
                    ContainerKind::Table => "Table",
                    ContainerKind::List  => "List",
                };
                println!(
                    "{indent}LeaveContainer  path={:?}  kind={kind_str}",
                    path_display(path)
                );
            }
            StreamEvent::Leaf { path, value, decorations } => {
                let dec_note = if let Some(d) = decorations {
                    // Count total decorator calls across all sigils.
                    let n: usize = d.decorators.values().map(|v| v.len()).sum();
                    format!("  [+{n} decorator call(s)]")
                } else {
                    String::new()
                };
                println!(
                    "{indent}Leaf            path={:?}  value={value:?}{dec_note}",
                    path_display(path)
                );
            }
            StreamEvent::EndOfDocument { root_decorations } => {
                let note = if root_decorations.is_some() { "  [root decorations]" } else { "" };
                println!("{indent}EndOfDocument{note}");
            }
        }
    }
}
