#!/usr/bin/env bash
set -euo pipefail

# TODO this is a complete vibe-coded hack, but the header patching at least is crucial

# Prepare Rust artifacts and C header for hs-bindgen.
#
# Pipeline:
#   1. cargo build       - build the Rust static library
#   2. cbindgen           - generate a C header from the Rust source
#   3. awk                - patch the header for hs-bindgen compatibility
#
# System include paths (needed by libclang on NixOS) are detected
# automatically at TH compile time by GarnetRs.Raw — no env vars needed.
#
# Prerequisites: run inside the Nix dev shell (provides gcc, cbindgen).

SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
RUST_DIR="$SCRIPT_DIR/rust"
HEADER_NAME="garnet_rs.h"
HEADER="$RUST_DIR/target/debug/$HEADER_NAME"

# --- Step 1: Build Rust static library ---
echo "=== Building Rust library ==="
cargo build --manifest-path "$RUST_DIR/Cargo.toml"

# --- Step 2: Generate C header with cbindgen ---
echo "=== Running cbindgen ==="
cbindgen \
  --lang c \
  --crate garnet-rs \
  --output "$HEADER" \
  --style tag \
  "$RUST_DIR"

echo "  Raw header written to $HEADER"

# --- Step 3: Patch the header for hs-bindgen compatibility ---
#
# cbindgen emits:    union { ... };       (anonymous)
# hs-bindgen needs:  union { ... } body;  (named)
# See: https://github.com/well-typed/hs-bindgen/issues/1649
echo "=== Patching header ==="
awk '
# Name anonymous unions: }; at end of union block inside struct -> } body;
/^  \};$/ && saw_union {
    print "  } body;"
    saw_union = 0
    next
}
/^  union \{$/ {
    saw_union = 1
}

{ print }
' "$HEADER" > "${HEADER}.tmp" && mv "${HEADER}.tmp" "$HEADER"

echo "  Patched header at $HEADER"

echo "=== Done ==="
echo "Run 'cabal run' to test."
