use std::{fs, path::Path, process::Command};

#[test]
fn add_fixture_emits_expected_llvm_shape() {
    let compiler = env!("CARGO_BIN_EXE_glagol");
    let fixture = Path::new("../examples/add.slo");
    let expected = fs::read_to_string("../tests/add.expected.ll").expect("read add.expected.ll");

    let output = Command::new(compiler)
        .arg(fixture)
        .output()
        .expect("run glagol on add fixture");

    assert!(
        output.status.success(),
        "compiler failed\nstdout:\n{}\nstderr:\n{}",
        String::from_utf8_lossy(&output.stdout),
        String::from_utf8_lossy(&output.stderr),
    );

    let actual = String::from_utf8(output.stdout).expect("LLVM output is UTF-8");

    for required in required_shapes(&expected) {
        assert!(
            actual.contains(required),
            "LLVM output did not contain expected shape `{}`\nactual:\n{}",
            required,
            actual,
        );
    }
}

fn required_shapes(expected: &str) -> Vec<&str> {
    expected
        .lines()
        .map(str::trim)
        .filter(|line| !line.is_empty())
        .filter(|line| !line.starts_with(';'))
        .collect()
}
