#![cfg(target_os = "linux")]

use std::path::PathBuf;
use std::process::Command;
use std::time::{SystemTime, UNIX_EPOCH};

#[test]
fn module_d_cli_small_file_fallback() {
    let binary = env!("CARGO_BIN_EXE_tracer-bullet");
    let target_path = unique_path("module-d-cli-target");

    let output = Command::new(binary)
        .args([
            "module-d-append",
            "--target-path",
            target_path.to_str().expect("path should be utf-8"),
            "--total-bytes",
            "8388608",
            "--group-bytes",
            "4194304",
            "--request-bytes",
            "262144",
            "--producers",
            "2",
            "--seed",
            "7",
            "--allow-file-fallback",
            "--json",
        ])
        .output()
        .expect("failed to invoke module-d command");

    assert!(
        output.status.success(),
        "module-d command failed: status={:?} stderr={} stdout={}",
        output.status,
        String::from_utf8_lossy(&output.stderr),
        String::from_utf8_lossy(&output.stdout)
    );

    let stdout = String::from_utf8_lossy(&output.stdout);
    assert!(stdout.contains("\"module\":\"D\""));
    assert!(stdout.contains("\"alignment_violations\":0"));
    assert!(stdout.contains("\"write_errors\":0"));

    let fallback = target_path.with_extension("direct.bin");
    let _ = std::fs::remove_file(fallback);
}

#[test]
#[ignore = "heavy 50GiB module-d write"]
fn module_d_cli_full_scale() {
    let binary = env!("CARGO_BIN_EXE_tracer-bullet");
    let target_path = unique_path("module-d-cli-full");

    let status = Command::new(binary)
        .args([
            "module-d-append",
            "--target-path",
            target_path.to_str().expect("path should be utf-8"),
            "--total-bytes",
            "53687091200",
            "--group-bytes",
            "16777216",
            "--request-bytes",
            "262144",
            "--producers",
            "4",
            "--allow-file-fallback",
            "--json",
        ])
        .status()
        .expect("failed to invoke module-d full-scale command");

    assert!(status.success(), "module-d full-scale run failed");

    let fallback = target_path.with_extension("direct.bin");
    let _ = std::fs::remove_file(fallback);
}

fn unique_path(prefix: &str) -> PathBuf {
    let nanos = SystemTime::now()
        .duration_since(UNIX_EPOCH)
        .expect("system time should be valid")
        .as_nanos();
    std::env::temp_dir().join(format!("{}-{}-{}", prefix, std::process::id(), nanos))
}
