//! Build script generating the header for the `servicepoint` C library.
//!
//! When the environment variable `SERVICEPOINT_HEADER_OUT` is set, the header is copied there from
//! the out directory. This can be used to use the build script as a command line tool from other
//! build tools.

use std::{env, fs};

fn main() {
    let crate_dir = env::var("CARGO_MANIFEST_DIR").unwrap();
    println!("cargo::rerun-if-changed={crate_dir}/src");
    println!("cargo::rerun-if-changed={crate_dir}/build.rs");
    println!("cargo::rerun-if-changed={crate_dir}/Cargo.toml");
    println!("cargo::rerun-if-changed={crate_dir}/Cargo.lock");
    println!("cargo::rerun-if-changed={crate_dir}/cbindgen.toml");
    println!("cargo::rerun-if-env-changed=SERVICEPOINT_HEADER_OUT");

    let config =
        cbindgen::Config::from_file(crate_dir.clone() + "/cbindgen.toml")
            .unwrap();
    let output_dir = env::var("OUT_DIR").unwrap();
    let header_file = output_dir.clone() + "/servicepoint.h";

    let bindings = match cbindgen::generate_with_config(crate_dir, config) {
        Ok(bindings) => bindings,
        Err(e) => {
            eprintln!("cargo:warning=Servicepoint header could not be generated: {e:?}");
            return;
        }
    };

    bindings.write_to_file(&header_file);
    println!("cargo:include={output_dir}");

    if let Ok(header_out) = env::var("SERVICEPOINT_HEADER_OUT") {
        let header_copy = header_out + "/servicepoint.h";
        
        if fs::exists(&header_copy).unwrap_or(false) {
            // check if content changed to prevent rebuild of dependents if not

            let mut bindings_text = Vec::new();
            bindings.write(&mut bindings_text);
            
            match fs::read(&header_copy) {
                Ok(old_content) if old_content == bindings_text => {
                    println!("cargo:warning=Header did not change, not updating timestamp");
                    return;
                }
                _  => {}
            };
        }
        
        // file does not exist or is different
        println!("cargo:warning=Copying header to {header_copy}");
        fs::copy(header_file, &header_copy).unwrap();
        println!("cargo::rerun-if-changed={header_copy}");
    }
}