use std::{env, path::PathBuf};

// Supported versions of FSV
static SUPPORTED_FSV_VERSIONS: [&str; 2] = ["1.40.14", "1.40.13"];

fn build_bindings(version: &str, target_code: &str) -> PathBuf {
    let target = env::var("TARGET").expect("TARGET not set");
    let wrapper_path = format!("bindgen-wrappers/{}/wrapper.{}.h", version, target_code);
    let bindings = bindgen::Builder::default()
        // The input header we would like to generate
        // bindings for.
        .header(wrapper_path)
        // To generate the bindings for specific target
        .clang_arg(format!("--target={}", target))
        // Limit the bindings generation to the SSV_ prefix
        .allowlist_item("SSV_.*")
        // Tell cargo to invalidate the built crate whenever any of the
        // included header files changed.
        .parse_callbacks(Box::new(bindgen::CargoCallbacks::new()))
        // Finish the builder and generate the bindings.
        .generate()
        // Unwrap the Result and panic on failure.
        .expect("Unable to generate bindings");

    // Write the bindings to the $OUT_DIR/bindings.rs file.
    let out_dir = PathBuf::from(env::var("OUT_DIR").unwrap());
    let out_file = format!("bindings_{}.rs", version);
    let out_path = out_dir.join(out_file);
    bindings
        .write_to_file(&out_path)
        .expect("Couldn't write bindings! ");
    out_path
}

fn get_target_code() -> String {
    // Use CARGO configuration env Variable, because !cfg(target_os) is not available in build.rs
    // Source: https://kazlauskas.me/entries/writing-proper-buildrs-scripts
    let target_os = env::var("CARGO_CFG_TARGET_OS");

    match target_os.as_ref().map(|x| &**x) {
        Ok("linux") => "linux",  // lib_name = "ssvlux64";
        Ok("windows") => "win",  // lib_name = "Ssvw64";
        Ok("macos") => "macosx", // lib_name = "ssvosx";
        tos => panic!("Unsupported target_os {:?}", tos),
    }
    .to_string()
}

fn main() {
    let target_code = get_target_code();
    // Build the bindings for each supported version of FSV
    let bindings_paths: Vec<PathBuf> = SUPPORTED_FSV_VERSIONS
        .iter()
        .map(|version| build_bindings(version, &target_code))
        .collect();
    println!("FSV bindings generated: {:#?}", bindings_paths);
}