//! Captures the git commit hash at build time and exposes it to the crate as
//! the `HANUKE_GIT_COMMIT` compile-time environment variable.
//!
//! Resolution order:
//! 1. An explicit `HANUKE_GIT_COMMIT` environment variable. CI passes
//!    `github.sha` here so binaries built where no `.git` directory is present
//!    (crates.io source packages, release runners) still embed the source
//!    commit.
//! 2. `git rev-parse HEAD` in the working tree.
//! 3. Unset, in which case the code falls back to "unknown".

use std::fs;
use std::path::Path;
use std::process::Command;

fn main() {
    let git_dir = Path::new(".git");
    println!("cargo:rerun-if-env-changed=HANUKE_GIT_COMMIT");
    println!("cargo:rerun-if-changed={}", git_dir.join("HEAD").display());
    if let Ok(head) = fs::read_to_string(git_dir.join("HEAD"))
        && let Some(reference) = head.strip_prefix("ref:").map(str::trim)
    {
        println!(
            "cargo:rerun-if-changed={}",
            git_dir.join(reference).display()
        );
    }

    if let Some(hash) = env_commit().or_else(git_commit) {
        println!("cargo:rustc-env=HANUKE_GIT_COMMIT={hash}");
    }
}

/// An explicit `HANUKE_GIT_COMMIT` override (used by CI), if non-empty.
fn env_commit() -> Option<String> {
    std::env::var("HANUKE_GIT_COMMIT")
        .ok()
        .map(|s| s.trim().to_string())
        .filter(|s| !s.is_empty())
}

/// The working tree's `git rev-parse HEAD`, if git is available.
fn git_commit() -> Option<String> {
    Command::new("git")
        .args(["rev-parse", "HEAD"])
        .output()
        .ok()
        .filter(|out| out.status.success())
        .map(|out| String::from_utf8_lossy(&out.stdout).trim().to_string())
        .filter(|s| !s.is_empty())
}
