use bindgen;
use regex::Regex;
use std::env;
use std::error::Error;
use std::fs::File;
use std::io::Read;
use std::path::Path;
fn main() -> Result<(), Box<Error>> {
let out_dir = env::var("OUT_DIR")?;
let out_dir = Path::new(&out_dir);
let gurobi_dir = env::var("GUROBI_HOME").expect("GUROBI_HOME environment variable not set");
let gurobi_include = Path::new(&gurobi_dir).join("include");
let mut text = String::new();
File::open(gurobi_include.join("gurobi_c.h"))
.expect("Can't open header file 'gurobi_c.h'")
.read_to_string(&mut text)?;
let major: usize = Regex::new(r#"#define\s+GRB_VERSION_MAJOR\s+(\d+)"#)?
.captures(&text)
.expect("Cannot find GRB_VERSION_MAJOR in gurobi_c.h")[1]
.parse()?;
let minor: usize = Regex::new(r#"#define\s+GRB_VERSION_MINOR\s+(\d+)"#)?
.captures(&text)
.expect("Cannot find GRB_VERSION_MINOR in gurobi_c.h")[1]
.parse()?;
println!("cargo:rustc-link-search={}/lib", gurobi_dir);
println!("cargo:rustc-link-lib=gurobi{}{}", major, minor);
let bindings = bindgen::Builder::default()
.header(gurobi_include.join("gurobi_c.h").to_str().unwrap())
.whitelist_function("GRB.*")
.whitelist_type("GRB.*")
.whitelist_var("GRB.*")
.blacklist_type("FILE")
.blacklist_type("_.*")
.opaque_type("GRBmodel")
.opaque_type("GRBenv")
.opaque_type("GRBsvec")
.generate()
.map_err(|_| format!("Can't generate bidnings"))?;
let result = bindings.to_string();
let result = Regex::new(r#"&'static \[u8;.*?\](.*");"#)?.replace_all(
&result,
"*const ::std::os::raw::c_char $1 as *const u8 as *const ::std::os::raw::c_char;",
);
let result = Regex::new(r#": [ui]32 = (.*);"#)?.replace_all(&result, ": ::std::os::raw::c_int = $1;");
let result = Regex::new(r#": [ui]8 = (.*)([ui]8)?;"#)?
.replace_all(&result, ": ::std::os::raw::c_char = $1 as ::std::os::raw::c_char;");
std::fs::write(out_dir.join("gurobi-extern.rs"), result.into_owned())?;
Ok(())
}