//! decode → encode → re-decode equality check.
//!
//! Shows that `encode_t1_with_registry` produces source that re-decodes to a
//! semantically equal DocumentT1 (same body values and decorator count).
//!
//! Run: `cargo run --example tier1_roundtrip`

// What this shows:
//   - encode_t1_with_registry round-trips a DocumentT1 back to source text
//   - Re-decoding the emitted source gives equal body + equal decorator count
//   - The canonical-form encoder may rewrite positions (Leading→Inner) or
//     fold flow lists; the body values are still semantically equal

use dms::tier1::{
    decode_t1_with_registry, encode_t1_with_registry, DialectSpec, FamilySpec,
    InMemoryRegistry, ParamSignature, VersionStrategy,
};
use dms::Value;

fn build_registry() -> InMemoryRegistry {
    let dialect = DialectSpec {
        name: "html".into(),
        version: "1.0.0".into(),
        version_strategy: VersionStrategy::Caret,
        families: vec![FamilySpec {
            name: "tag".into(),
            default_sigils: vec!["|".into()],
            empty_default: Value::Table(Default::default()),
            content_slot: Some("children".into()),
            params: ParamSignature::default(),
        }],
        structs: vec![],
    };
    InMemoryRegistry::new().with(dialect)
}

const SRC: &str = "\
+++
_dms_tier: 1
_dms_imports:
  + dialect: \"html\"
    version: \"1.0.0\"
    bind:
      \"|\": [\"tag\"]
+++
|tag(class: \"header\")
title: \"Hello, DMS\"
count: 42
";

fn main() {
    let registry = build_registry();

    // Step 1: parse original source.
    let doc1 = decode_t1_with_registry(SRC, &registry).expect("initial parse");

    // Step 2: re-encode to source text.
    let reencoded = encode_t1_with_registry(&doc1, &registry).expect("encode");

    // Step 3: parse re-encoded source.
    let doc2 = decode_t1_with_registry(&reencoded, &registry).expect("re-parse after encode");

    println!("=== original source ===");
    println!("{SRC}");

    println!("=== re-encoded source ===");
    println!("{reencoded}");

    // Assert body equality.
    assert_eq!(
        doc1.t0.body, doc2.t0.body,
        "body mismatch after roundtrip"
    );
    // Assert decorator count equality.
    assert_eq!(
        doc1.decorators.len(),
        doc2.decorators.len(),
        "decorator count mismatch after roundtrip"
    );

    println!("=== roundtrip assertions passed ===");
    println!("  body entries:      both have {:?}", {
        if let Value::Table(t) = &doc1.t0.body { t.len() } else { 0 }
    });
    println!("  decorator entries: both have {}", doc1.decorators.len());
    println!("  roundtrip OK");
}
