use std::path::{Path, PathBuf};
use std::{env, fs};

use base64::{engine::general_purpose, Engine as _};

/// Work out where the workspace dir is
fn workspace_dir() -> Option<PathBuf> {
    let output = std::process::Command::new(env!("CARGO"))
        .arg("locate-project")
        .arg("--workspace")
        .arg("--message-format=plain")
        .output()
        .ok()?
        .stdout;
    let cargo_path = Path::new(std::str::from_utf8(&output).ok()?.trim());
    cargo_path.parent().map(|p| p.to_path_buf())
}

// We do this here so it's only actually run and checked once at build time.
fn determine_git_rev() -> Option<String> {
    let Some(workspace_dir) = workspace_dir() else {
        eprintln!("cargo:warning=Failed to determine workspace dir for git rev, incremental rebuilds could fail!");
        return None;
    };

    let Ok(repo) = gix::open(workspace_dir) else {
        return None;
    };

    let mut head = repo.head().ok()?;
    let commit = head.peel_to_commit().ok()?;
    let mut commit_id = commit.id().to_string();
    // Now we actually want to trim this to only 10 chars?
    commit_id.truncate(10);
    Some(commit_id)
}

fn main() {
    /*
     * https://doc.rust-lang.org/cargo/reference/build-scripts.html#change-detection
     * If the build script inherently does not need to re-run under any circumstance, then emitting
     * cargo:rerun-if-changed=build.rs is a simple way to prevent it from being re-run (otherwise,
     * the default if no rerun-if instructions are emitted is to scan the entire package directory
     * for changes).
     */
    println!("cargo:rerun-if-changed=build.rs");
    println!("cargo:rerun-if-env-changed=KANIDM_BUILD_PROFILE");

    let profile = env::var("KANIDM_BUILD_PROFILE").unwrap_or_else(|_| "developer".to_string());

    let profile_path: PathBuf = ["./", format!("{profile}.toml").as_str()].iter().collect();

    let data =
        fs::read(&profile_path).unwrap_or_else(|_| panic!("Failed to read {profile_path:?}"));

    let contents = general_purpose::STANDARD.encode(data);

    if let Some(commit_rev) = determine_git_rev() {
        println!("cargo:rustc-env=KANIDM_PKG_COMMIT_REV={commit_rev}");
    }

    println!("cargo:rerun-if-changed={}", profile_path.to_string_lossy());

    println!("cargo:rustc-env=KANIDM_BUILD_PROFILE={profile}");
    println!("cargo:rustc-env=KANIDM_BUILD_PROFILE_TOML={contents}");
}
