use std::env;
use std::path::PathBuf;

fn main() -> Result<(), Box<dyn std::error::Error>> {
    let manifest_dir = PathBuf::from(env::var("CARGO_MANIFEST_DIR")?);
    // Source of truth is the repo-root `proto/` dir (shared with buf + the TS
    // codegen). It is one level above this crate, so it is NOT in the
    // crates.io package tarball — fall back to the vendored copy under the
    // crate (`proto/makechain.proto`, kept byte-identical by the proto-sync
    // test) when building a published crate outside the workspace.
    let root_proto_dir = manifest_dir.join("../../proto");
    let proto_dir = if root_proto_dir.join("makechain.proto").exists() {
        root_proto_dir
    } else {
        manifest_dir.join("proto")
    };
    let proto_file = proto_dir.join("makechain.proto");

    println!("cargo:rerun-if-changed={}", proto_file.display());
    println!("cargo:rerun-if-changed=build.rs");

    // connectrpc-build runs buffa's codegen for messages and emits its own
    // companion files for the ConnectRPC service trait + typed client. Both
    // get stitched into a single module that we pull back in via
    // `connectrpc::include_generated!()` in src/lib.rs.
    //
    // Reflection is enabled (vtable mode) so the generated `makechain`
    // package exposes a runtime `DescriptorPool`, which backs the
    // `connectrpc-reflection` gRPC Server Reflection service (see
    // `src/reflection.rs`). This replaces the pre-0.7 workaround of
    // re-running `protoc --descriptor_set_out` for a raw descriptor blob.
    let mut buffa = buffa_codegen::CodeGenConfig::default();
    buffa_codegen::ReflectMode::VTable.apply(&mut buffa);
    // `arbitrary::Arbitrary` derives, always generated: buffa-codegen emits
    // them behind `cfg_attr(feature = "arbitrary", ...)` itself, so the
    // crate's `arbitrary` feature (used by its own property tests) is the
    // single gate — dependents that leave it off compile identical code, and
    // the generated source is the same for every feature set.
    buffa.generate_arbitrary = true;

    connectrpc_build::Config::new()
        .files(std::slice::from_ref(&proto_file))
        .includes(std::slice::from_ref(&proto_dir))
        .buffa_config(buffa)
        // `buffa_config` replaces the buffa options wholesale, dropping
        // connectrpc-build's JSON-on default — re-enable it explicitly: the
        // API serves Connect-JSON from the same handler as gRPC.
        .generate_json(true)
        .include_file("_connectrpc.rs")
        .compile()?;

    Ok(())
}
