#![allow(missing_docs, clippy::missing_errors_doc)]

use std::{env::VarError, path::Path};

use pkg_config::Config;

type Result<T, E = Box<dyn std::error::Error>> = std::result::Result<T, E>;

fn env_var(var: &str) -> Result<String, VarError> {
    println!("cargo:rerun-if-env-changed={var}");
    std::env::var(var)
}

fn generate_bindings_file() -> Result<()> {
    let zbar = Config::new().atleast_version("0.23.0").probe("zbar")?;

    if env_var("ZBAR_STATIC").is_ok() {
        println!("cargo:rustc-link-lib=static=zbar");
    }

    let mut builder = bindgen::builder()
        .rustified_enum("zbar_color_e")
        .rustified_non_exhaustive_enum("zbar_symbol_type_e")
        .rustified_enum("zbar_orientation_e")
        .rustified_non_exhaustive_enum("zbar_error_e")
        .rustified_non_exhaustive_enum("zbar_config_e")
        .rustified_enum("zbar_modifier_e")
        .rustified_enum("video_control_type_e");

    for path in zbar.include_paths {
        builder = builder.clang_arg(format!("-I{}", path.display()));
    }

    let builder = builder.header("zbar-wrapper.h");
    let bindings = builder.generate()?;

    let out_path = Path::new(&env_var("OUT_DIR")?).join("bindings.rs");

    bindings.write_to_file(out_path)?;

    Ok(())
}

fn main() -> Result<()> {
    if let Err(e) = generate_bindings_file() {
        eprintln!("Building zbar-sys failed: {e}");
        eprintln!("Ensure zbar headers, libclang, and pkg-config are installed");
        return Err(e)
    }

    Ok(())
}