#![doc = "Build script that generates the BQ25887 register API from the YAML manifest."]

use std::path::PathBuf;
use std::str::FromStr;
use std::{env, fs, io};

fn main() -> Result<(), Box<dyn std::error::Error>> {
    println!("cargo:rerun-if-changed=build.rs");
    println!("cargo:rerun-if-changed=link.x");
    println!("cargo:rerun-if-changed=src/bq25887.yaml");

    let target = env::var("TARGET").unwrap_or_default();
    if target == "thumbv8m.main-none-eabihf" {
        println!("cargo:rustc-link-arg=-Tlink.x");
        println!("cargo:rustc-link-arg=-Tdefmt.x");
        println!("cargo:rustc-link-arg=--nmagic");
    }

    let manifest_dir = PathBuf::from(env::var("CARGO_MANIFEST_DIR").expect("CARGO_MANIFEST_DIR must be set"));
    let manifest_path = manifest_dir.join("src/bq25887.yaml");
    let manifest = fs::read_to_string(&manifest_path)?;

    let generated = device_driver_generation::transform_yaml(&manifest, "Bq25887");

    let tokens = proc_macro2::TokenStream::from_str(&generated)
        .map_err(|err| io::Error::other(format!("Failed to parse generated device tokens: {err}")))?;

    let syntax_tree = syn::parse2::<syn::File>(tokens)
        .map_err(|err| io::Error::other(format!("Failed to build syntax tree for generated device: {err}")))?;

    let formatted = prettyplease::unparse(&syntax_tree);

    let mut output = String::new();
    output.push_str("// @generated by build.rs\n");
    output.push_str("// Do not edit this file manually.\n");
    output.push_str("// Source manifest: ");
    output.push_str(&manifest_path.display().to_string());
    output.push_str("\n\n");
    output.push_str(formatted.trim_start_matches('\u{feff}'));
    if !output.ends_with('\n') {
        output.push('\n');
    }

    let out_dir = PathBuf::from(env::var_os("OUT_DIR").expect("OUT_DIR must be set by Cargo"));
    let dest = out_dir.join("bq25887_device.rs");
    fs::write(dest, output)?;

    Ok(())
}
