use gobuild::BuildMode;
use std::path::PathBuf;
use std::{env, fs};

fn main() {
    // Build the go sources into a C shared library (.so file), and generate an .h file too.
    //
    // Unfortunately, we can't build it into a static library (.a file), because that is unsupported
    // by the Go toolchain [1]. This means our output is going to depend on the generated .so file,
    // which we need to make available to `./build-ndk.sh` so it can be copied into the right place
    // for Android.
    //
    // We do this by setting env var `ONIONMASQ_PT_LIB_LOCATION` in the build script and copying
    // the generated .so file there if it exists.
    //
    // [1]: https://github.com/golang/go/issues/33806

    gobuild::Build::new()
        .file("./src-go/lyrebird_util.go")
        .file("./src-go/logging.go")
        .file("./src-go/main.go")
        .buildmode(BuildMode::CShared)
        .compile("onionmasq-pt-bindings");

    let out_dir = env::var("OUT_DIR").unwrap();
    let out_path = PathBuf::from(out_dir);

    println!("cargo:rerun-if-env-changed=ONIONMASQ_PT_LIB_LOCATION");

    // Copy the generated .so file from Go so we can find it later.
    if let Ok(so_out_path) = env::var("ONIONMASQ_PT_LIB_LOCATION") {
        let so_from = out_path.join("libonionmasq-pt-bindings.so");

        if let Err(e) = fs::copy(&so_from, &so_out_path) {
            panic!(
                "Failed to copy {} to {}: {}",
                so_from.to_string_lossy(),
                so_out_path,
                e
            );
        }
    }

    // Invoke bindgen on the generated .h file.
    let bindings = bindgen::builder()
        .header(
            out_path
                .join("libonionmasq-pt-bindings.h")
                .to_str()
                .expect("non-UTF-8 path"),
        )
        .generate()
        .expect("running bindgen failed");

    bindings
        .write_to_file(out_path.join("bindings.rs"))
        .expect("writing bindgen bindings failed");
}
