use lace_single::prelude::*;

const TAI: &str = "0000000001:000000000";
const POLICY: &str = include_str!("../policy/items.interlang");
const UNRELATED_POLICY: &str = r#"
converge {
  Item in //first-interlace//demo/item//unrelated/{*} => include Item
}
"#;

fn main() -> std::result::Result<(), Box<dyn std::error::Error>> {
    let source = Lace::empty_memory();
    let destination = Lace::empty_memory();

    let item = spec!({
        group: "first-interlace",
        app: "demo/item",
        tai: TAI,
    });

    let first = record!(item, {
        name: "selected/one",
        data: "first selected record",
    })?;
    let second = record!(item, {
        name: "selected/two",
        data: "second selected record",
    })?;
    let unrelated = record!(item, {
        name: "unrelated/not-selected",
        data: "this record must stay at the source",
    })?;

    let stored = store(source.handle(), [first, second, unrelated])?;
    println!("source stored: {}", stored.records.len());

    let policy = PolicyAuthoringSource::interlang(POLICY.trim());
    let outcome = bounded_interlace(source.handle(), destination.handle(), policy.clone())?;
    assert_eq!(outcome.terminal, Terminal::Complete);
    println!("interlace outcome: complete");

    let selected = list(destination.handle(), policy)?;
    let mut selected_names = selected
        .records
        .iter()
        .map(|record| record.name().expect("selected records have names").to_string())
        .collect::<Vec<_>>();
    selected_names.sort();
    assert_eq!(selected_names, ["selected/one", "selected/two"]);
    println!("destination selected: {}", selected_names.join(", "));

    let unrelated = list(
        destination.handle(),
        PolicyAuthoringSource::interlang(UNRELATED_POLICY.trim()),
    )?;
    assert!(unrelated.records.is_empty());
    println!("destination unrelated: {}", unrelated.records.len());

    Ok(())
}
