//! Smoke-test that smpark.ko loads on boot.
//!
//! Bakes a fresh `rust:1-slim` image with smpark.ko staged at
//! `/supermachine-smpark.ko`. init-oci `finit_module`s it before
//! starting the user workload. After acquire, we read
//! `/proc/modules` from inside the guest to verify the module is
//! loaded.
//!
//! Smoke level only — proves the load path works on a 1-vCPU
//! guest (where the module no-ops). Doesn't drive park/unpark or
//! validate multi-vCPU snapshots — those are the next steps.

use std::time::Duration;
use supermachine::Image;

fn main() -> Result<(), Box<dyn std::error::Error>> {
    let smpark_ko = std::path::PathBuf::from("docs/design/extras/smpark/smpark.ko");
    if !smpark_ko.is_file() {
        eprintln!("smpark.ko not found at {}", smpark_ko.display());
        std::process::exit(1);
    }

    eprintln!("[smpark-smoke] baking with smpark.ko staged...");
    let image = Image::builder("rust:1-slim")
        .with_name("rust_1_slim_smpark")
        .with_memory_mib(512)
        .with_extra_file(&smpark_ko, "/supermachine-smpark.ko")
        .build()?;

    eprintln!("[smpark-smoke] acquiring + checking /proc/modules...");
    let pool = image.pool().min(1).max(1).build()?;
    let vm = pool.acquire()?;
    let out = vm
        .exec_builder()
        .argv(["sh", "-c", "cat /proc/modules || true"])
        .timeout(Duration::from_secs(5))
        .output()?;
    let stdout = String::from_utf8_lossy(&out.stdout);
    eprintln!("[smpark-smoke] /proc/modules output:\n{stdout}");

    if stdout.contains("smpark") {
        eprintln!("[smpark-smoke] SUCCESS: smpark loaded");
    } else {
        eprintln!("[smpark-smoke] FAIL: smpark not in /proc/modules");
        std::process::exit(2);
    }
    Ok(())
}
