use std::io::Result;
use std::process::Command;

fn main() -> Result<()> {
    // Compile protobuf definitions
    prost_build::compile_protos(&["../proto/guruconnect.proto"], &["../proto/"])?;

    // Rerun if proto changes
    println!("cargo:rerun-if-changed=../proto/guruconnect.proto");

    // Rerun if git HEAD changes (new commits)
    println!("cargo:rerun-if-changed=../.git/HEAD");
    println!("cargo:rerun-if-changed=../.git/index");

    // Build timestamp (UTC)
    let build_timestamp = chrono::Utc::now()
        .format("%Y-%m-%d %H:%M:%S UTC")
        .to_string();
    println!("cargo:rustc-env=BUILD_TIMESTAMP={}", build_timestamp);

    // Git commit hash (short)
    let git_hash = Command::new("git")
        .args(["rev-parse", "--short=8", "HEAD"])
        .output()
        .ok()
        .and_then(|o| String::from_utf8(o.stdout).ok())
        .map(|s| s.trim().to_string())
        .unwrap_or_else(|| "unknown".to_string());
    println!("cargo:rustc-env=GIT_HASH={}", git_hash);

    // Git commit hash (full)
    let git_hash_full = Command::new("git")
        .args(["rev-parse", "HEAD"])
        .output()
        .ok()
        .and_then(|o| String::from_utf8(o.stdout).ok())
        .map(|s| s.trim().to_string())
        .unwrap_or_else(|| "unknown".to_string());
    println!("cargo:rustc-env=GIT_HASH_FULL={}", git_hash_full);

    // Git branch name
    let git_branch = Command::new("git")
        .args(["rev-parse", "--abbrev-ref", "HEAD"])
        .output()
        .ok()
        .and_then(|o| String::from_utf8(o.stdout).ok())
        .map(|s| s.trim().to_string())
        .unwrap_or_else(|| "unknown".to_string());
    println!("cargo:rustc-env=GIT_BRANCH={}", git_branch);

    // Git dirty state (uncommitted changes)
    let git_dirty = Command::new("git")
        .args(["status", "--porcelain"])
        .output()
        .ok()
        .map(|o| !o.stdout.is_empty())
        .unwrap_or(false);
    println!(
        "cargo:rustc-env=GIT_DIRTY={}",
        if git_dirty { "dirty" } else { "clean" }
    );

    // Git commit date
    let git_commit_date = Command::new("git")
        .args(["log", "-1", "--format=%ci"])
        .output()
        .ok()
        .and_then(|o| String::from_utf8(o.stdout).ok())
        .map(|s| s.trim().to_string())
        .unwrap_or_else(|| "unknown".to_string());
    println!("cargo:rustc-env=GIT_COMMIT_DATE={}", git_commit_date);

    // Build profile (debug/release)
    let profile = std::env::var("PROFILE").unwrap_or_else(|_| "unknown".to_string());
    println!("cargo:rustc-env=BUILD_PROFILE={}", profile);

    // Target triple
    let target = std::env::var("TARGET").unwrap_or_else(|_| "unknown".to_string());
    println!("cargo:rustc-env=BUILD_TARGET={}", target);

    // On Windows, embed the manifest for UAC elevation
    #[cfg(target_os = "windows")]
    {
        println!("cargo:rerun-if-changed=guruconnect.manifest");

        let mut res = winres::WindowsResource::new();
        res.set_manifest_file("guruconnect.manifest");
        res.set("ProductName", "GuruConnect Agent");
        res.set("FileDescription", "GuruConnect Remote Desktop Agent");
        res.set("LegalCopyright", "Copyright (c) AZ Computer Guru");
        res.set_icon("guruconnect.ico"); // Optional: add icon if available

        // Only compile if the manifest exists
        if std::path::Path::new("guruconnect.manifest").exists() {
            if let Err(e) = res.compile() {
                // Don't fail the build if resource compilation fails
                eprintln!("Warning: Failed to compile Windows resources: {}", e);
            }
        }
    }

    Ok(())
}
