use std::env;
use std::path::PathBuf;

fn main() {
    println!("cargo:rerun-if-changed=src/");
    println!("cargo:rerun-if-changed=vendor/");

    let xdiff_dir = PathBuf::from("vendor/xdiff");
    if !xdiff_dir.join("xtypes.h").exists() {
        std::fs::create_dir_all(&xdiff_dir).unwrap();
        let files = [
            "xdiffi.c", "xprepare.c", "xutils.c", "xpatience.c", "xhistogram.c", "xemit.c", "xmerge.c",
            "xdiff.h", "xdiffi.h", "xemit.h", "xinclude.h", "xmacros.h", "xprepare.h", "xutils.h", "xtypes.h"
        ];
        for f in &files {
            let url = format!("https://raw.githubusercontent.com/git/git/master/xdiff/{}", f);
            let status = std::process::Command::new("curl")
                .args(["-fsSL", &url, "-o"])
                .arg(xdiff_dir.join(f))
                .status()
                .unwrap();
            if !status.success() {
                panic!("Failed to download {}", url);
            }
        }
    }

    // Make sure to compile dtob and potc from the symlinked vendor directories.
    // This allows `cargo build` to magically output to the correct target architecture
    // Native static compilation:
    cc::Build::new()
        .include("vendor/dtob/lib")
        .include("vendor/dtob/src")
        .include("vendor/dif")
        .include("vendor/potc/src")
        .include("vendor/xanadoc")
        .include("src/xdiff_compat")
        .include("vendor")
        .include("vendor/xdiff")
        // DTOB
        .file("vendor/dtob/src/trit.c")
        .file("vendor/dtob/src/lexer.c")
        .file("vendor/dtob/src/ast.c")
        .file("vendor/dtob/src/parser.c")
        .file("vendor/dtob/src/encoder.c")
        .file("vendor/dtob/src/encode_json.c")
        .file("vendor/dtob/src/encode_xml.c")
        .file("vendor/dtob/src/html_rules.c")
        // POTC (Bromberg)
        .file("vendor/potc/src/hash_matrix.c")
        .file("vendor/potc/src/lookup_table.c")
        .file("vendor/potc/src/bromberg_sl2.c")
        // Git libxdiff
        .file("vendor/xdiff/xdiffi.c")
        .file("vendor/xdiff/xprepare.c")
        .file("vendor/xdiff/xutils.c")
        .file("vendor/xdiff/xpatience.c")
        .file("vendor/xdiff/xhistogram.c")
        .file("vendor/xdiff/xemit.c")
        // Our FFI
        .file("src/sculblog_ffi.c")
        .compile("native_deps");

    let bindings = bindgen::Builder::default()
        .header("src/sculblog_ffi.h")
        .parse_callbacks(Box::new(bindgen::CargoCallbacks::new()))
        .generate()
        .expect("Unable to generate bindings");

    let out_path = PathBuf::from(env::var("OUT_DIR").unwrap());
    bindings
        .write_to_file(out_path.join("bindings.rs"))
        .expect("Couldn't write bindings!");
}
