//! E2E pin for the `str_concat` heap-Str primitive shipped in iter
//! `str-concat`. Asserts that `ail check` + `ail build` + run on
//! `examples/show_user_adt_with_label.ail` produce stdout
//! `Item 42\n` — i.e. that the Show body's
//! `(app str_concat "Item " (app int_to_str n))` evaluates correctly
//! and `print` emits the concatenated heap-Str.
//!
//! Without `str_concat` registered as a builtin (pre-iter state), the
//! fixture fails `ail check` with `[unbound-var]: str_concat`. After
//! the iter ships, both check and build succeed and the binary
//! produces the expected stdout.

use std::path::Path;
use std::process::Command;

fn ail_bin() -> &'static str {
    env!("CARGO_BIN_EXE_ail")
}

#[test]
fn str_concat_e2e_show_user_adt_with_label() {
    let manifest_dir = env!("CARGO_MANIFEST_DIR");
    let workspace = Path::new(manifest_dir).parent().unwrap().parent().unwrap();
    let src = workspace
        .join("examples")
        .join("show_user_adt_with_label.ail");
    assert!(src.exists(), "fixture missing: {}", src.display());

    let check = Command::new(ail_bin())
        .args(["check", src.to_str().unwrap()])
        .output()
        .expect("ail check failed to spawn");
    assert_eq!(
        check.status.code(),
        Some(0),
        "ail check must succeed; got stdout={} stderr={}",
        String::from_utf8_lossy(&check.stdout),
        String::from_utf8_lossy(&check.stderr)
    );

    let tmp = tempfile::tempdir().expect("tempdir");
    let bin_path = tmp.path().join("a.out");
    let build = Command::new(ail_bin())
        .args([
            "build",
            src.to_str().unwrap(),
            "-o",
            bin_path.to_str().unwrap(),
        ])
        .output()
        .expect("ail build failed to spawn");
    assert_eq!(
        build.status.code(),
        Some(0),
        "ail build must succeed; got stdout={} stderr={}",
        String::from_utf8_lossy(&build.stdout),
        String::from_utf8_lossy(&build.stderr)
    );

    let run = Command::new(&bin_path)
        .output()
        .expect("produced binary failed to spawn");
    assert_eq!(run.status.code(), Some(0), "binary must exit 0");
    let stdout = String::from_utf8_lossy(&run.stdout);
    assert_eq!(
        stdout, "Item 42\n",
        "expected `Item 42\\n` from str_concat + int_to_str + print; got {stdout:?}"
    );
}
