//
// Syd: rock-solid application kernel
// lib/tests/tests.rs: libsyd tests
//
// Copyright (c) 2023, 2024, 2025 Ali Polatel <alip@chesswob.org>
//
// SPDX-License-Identifier: LGPL-3.0

use std::process::Command;

#[test]
fn test_libsyd_go() {
    let curdir = std::fs::canonicalize(std::env::current_dir().expect("current directory"))
        .expect("canonicalize");
    let curdir = curdir.display().to_string();
    eprintln!("Current directory: {curdir}");
    let libdir = std::env::var("LD_LIBRARY_PATH").unwrap_or_default();
    let libdir = libdir.split(':').next().unwrap_or("");
    eprintln!("LibSyd directory: {libdir}");

    let status = Command::new("syd")
        .current_dir("./src")
        .env("CGO_CFLAGS", format!("-I{curdir}"))
        .env("GOCACHE", curdir)
        .env("SYD_NO_SYSLOG", "1")
        .arg("-plib")
        .arg("-pP") // Allow non-PIE.
        .arg("-eLD_LIBRARY_PATH=") // pass-through
        .arg("-mtrace/allow_unsafe_libc:1") // or else AT_SECURE prevents pass-through
        .arg("-mlock:off") // Due to the way go test works, we need this.
        .arg("--")
        .args(["go", "test", "-ldflags", &format!("-extldflags '-L{libdir}'"), "-v", "-x", "-p", "1"])
        .status()
        .expect("execute go test");
    assert!(status.success(), "status:{status:?}");
}

#[test]
fn test_libsyd_pl() {
    let curdir = std::fs::canonicalize(std::env::current_dir().expect("current directory"))
        .expect("canonicalize");
    let curdir = curdir.display().to_string();
    eprintln!("Current directory: {curdir}");
    let libdir = std::env::var("LD_LIBRARY_PATH").unwrap_or_default();
    let libdir = libdir.split(':').next().unwrap_or("");
    eprintln!("LibSyd directory: {libdir}");

    let status = Command::new("syd")
        .env("SYD_NO_SYSLOG", "1")
        .arg("-plib")
        .arg("-pP") // Allow non-PIE.
        .arg("-eLD_LIBRARY_PATH=") // pass-through
        .arg("-mtrace/allow_unsafe_libc:1") // or else AT_SECURE prevents pass-through
        .arg("--")
        .arg("./src/syd.pl")
        .status()
        .expect("execute syd.pl");
    assert!(status.success(), "status:{status:?}");
}

#[test]
fn test_libsyd_py() {
    let status = Command::new("syd")
        .env("SYD_NO_SYSLOG", "1")
        .arg("-plib")
        .arg("-pP") // Allow non-PIE.
        .arg("-eLD_LIBRARY_PATH=") // pass-through
        .arg("-mtrace/allow_unsafe_libc:1") // or else AT_SECURE prevents pass-through
        .arg("--")
        .arg("./src/syd.py")
        .status()
        .expect("execute syd.py");
    assert!(status.success(), "status:{status:?}");
}

#[test]
fn test_libsyd_rb() {
    let curdir = std::fs::canonicalize(std::env::current_dir().expect("current directory"))
        .expect("canonicalize");
    let curdir = curdir.display().to_string();
    eprintln!("Current directory: {curdir}");
    let libdir = std::env::var("LD_LIBRARY_PATH").unwrap_or_default();
    let libdir = libdir.split(':').next().unwrap_or("");
    eprintln!("LibSyd directory: {libdir}");

    // WTF: Does dev-ruby/ffi map WX memory?
    // TODO: Report upstream!
    let status = Command::new("syd")
        .env("SYD_NO_SYSLOG", "1")
        .arg("-plib")
        .arg("-pMP") // Allow W^X memory and non-PIE.
        .arg("-eLD_LIBRARY_PATH=") // pass-through
        .arg("-mtrace/allow_unsafe_libc:1") // or else AT_SECURE prevents pass-through
        .arg("--")
        .arg("./src/syd.rb")
        .arg("-s0")
        .arg("-v")
        .status()
        .expect("execute syd.rb");
    assert!(status.success(), "status:{status:?}");
}
