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

fn resolve_kvproto_root(manifest_dir: &Path) -> PathBuf {
    let default_root = manifest_dir.join("../../../../kvproto");
    let resolved = match std::env::var_os("KVPROTO_ROOT").map(PathBuf::from) {
        None => default_root,
        Some(raw_path) if raw_path.is_absolute() => raw_path,
        Some(raw_path) => {
            // Keep KVPROTO_ROOT relative paths stable by resolving them from workspace root.
            let workspace_root = manifest_dir
                .ancestors()
                .nth(3)
                .map(PathBuf::from)
                .unwrap_or_else(|| manifest_dir.to_path_buf());
            workspace_root.join(raw_path)
        }
    };

    std::fs::canonicalize(&resolved).unwrap_or(resolved)
}

fn main() {
    let root = PathBuf::from(std::env::var("CARGO_MANIFEST_DIR").expect("manifest dir"));
    let kvproto_root = resolve_kvproto_root(&root);
    let proto_dir = kvproto_root.join("proto");
    let include_dir = kvproto_root.join("include");
    let admin_proto = root.join("proto/admin_v1.proto");

    println!("cargo:rerun-if-env-changed=KVPROTO_ROOT");
    println!("cargo:rerun-if-changed={}", admin_proto.display());
    println!(
        "cargo:rerun-if-changed={}",
        proto_dir.join("tsopb.proto").display()
    );
    println!(
        "cargo:rerun-if-changed={}",
        proto_dir.join("pdpb.proto").display()
    );

    tonic_build::configure()
        .build_client(true)
        .build_server(true)
        .compile_protos(
            &[
                proto_dir.join("tsopb.proto"),
                proto_dir.join("pdpb.proto"),
                admin_proto,
            ],
            &[proto_dir, include_dir, root.join("proto")],
        )
        .expect("compile protobuf files");
}
