//! End-to-end test of a **real `wasm32` guest** against the `WasmTransform`
//! host (`src/wasm.rs`). The guest is the crate in `wasm-guest/`, which reads
//! the input Arrow-IPC stream, **keeps only rows where `_gar_id` is even**, and
//! writes the result back as Arrow IPC — proving arrow-on-wasm works.
//!
//! `#[ignore]` because it depends on the wasm artifact being **pre-built**:
//!
//! ```sh
//! cargo build -p knut-bifrost-wasm-guest \
//!     --target wasm32-unknown-unknown --release \
//!     --manifest-path crates/knut-bifrost/wasm-guest/Cargo.toml
//! ```
//!
//! Then run it (feature `wasm`, not ignored):
//!
//! ```sh
//! cargo test -p knut-bifrost --features wasm --test wasm_guest -- --ignored
//! ```
#![cfg(feature = "wasm")]

use std::path::PathBuf;
use std::sync::Arc;

use arrow_array::{Int64Array, RecordBatch, StringArray};
use arrow_schema::{DataType, Field, Schema};

use knut_bifrost::transform::{TableContext, Transform};
use knut_bifrost::wasm::WasmTransform;

/// Path to the pre-built guest artifact, relative to this crate's manifest dir.
fn guest_wasm_path() -> PathBuf {
    PathBuf::from(env!("CARGO_MANIFEST_DIR"))
        .join("wasm-guest/target/wasm32-unknown-unknown/release/knut_bifrost_wasm_guest.wasm")
}

fn sample() -> RecordBatch {
    RecordBatch::try_new(
        Arc::new(Schema::new(vec![
            Field::new("_gar_id", DataType::Int64, false),
            Field::new("name", DataType::Utf8, false),
        ])),
        vec![
            Arc::new(Int64Array::from(vec![1, 2, 3, 4, 5, 6])),
            Arc::new(StringArray::from(vec!["a", "b", "c", "d", "e", "f"])),
        ],
    )
    .unwrap()
}

#[test]
#[ignore = "needs the wasm32 guest artifact pre-built; see module docs"]
fn real_wasm_guest_keeps_only_even_gar_ids() {
    let path = guest_wasm_path();
    assert!(
        path.exists(),
        "guest wasm not built at {path:?}\n  build it with:\n  cargo build -p knut-bifrost-wasm-guest \
         --target wasm32-unknown-unknown --release \
         --manifest-path crates/knut-bifrost/wasm-guest/Cargo.toml"
    );

    let t = WasmTransform::from_file(&path, "Person", "_gar_id").expect("load guest wasm");
    let mutation = t
        .apply(
            &TableContext {
                table: "people".into(),
            },
            &[sample()],
        )
        .expect("guest transform runs");

    assert_eq!(
        mutation.vertices.len(),
        1,
        "one output batch → one vertex set"
    );
    let vs = &mutation.vertices[0];
    assert_eq!(vs.label, "Person");
    assert_eq!(vs.id_column, "_gar_id");

    // Only even _gar_id rows survive: 2, 4, 6 (names b, d, f).
    let ids = vs
        .batch
        .column_by_name("_gar_id")
        .unwrap()
        .as_any()
        .downcast_ref::<Int64Array>()
        .unwrap();
    let got: Vec<i64> = ids.iter().map(|v| v.unwrap()).collect();
    assert_eq!(got, vec![2, 4, 6], "guest kept only even _gar_id rows");

    let names = vs
        .batch
        .column_by_name("name")
        .unwrap()
        .as_any()
        .downcast_ref::<StringArray>()
        .unwrap();
    let got_names: Vec<&str> = names.iter().map(|v| v.unwrap()).collect();
    assert_eq!(
        got_names,
        vec!["b", "d", "f"],
        "rows stayed aligned through the filter"
    );
}
