#!/bin/sh
# Resolve the wickra-synth C ABI (header + shared library) for the Unix build.
#
# Self-contained by default: download the prebuilt
# wickra-synth-c-<triple>.tar.gz release asset that matches this package's
# version and stage the shared library into src/, so the compiled wickrasynth.so
# links against it and bundles it (via install.libs.R), found post-install
# through an rpath ($ORIGIN on Linux, @loader_path on macOS).
#
# Set WKSYNTH_INC + WKSYNTH_LIB to build against a locally built C ABI instead
# (the dev override our own CI uses; e.g. `cargo build -p wickra-synth-c
# --release`). Download and extract go through base R, which is always present
# at build time, so there is no curl/wget system dependency.
set -e

inc=""
lib=""

# A freshly cut GitHub release can briefly return 404 while its assets propagate
# across the CDN, and a transient network blip should not fail the build either.
# Retry base R's download.file with a backoff (~2 min total) instead of giving up
# on the first miss.
wksynth_download() {
  _url="$1"
  _dest="$2"
  _attempt=1
  while [ "${_attempt}" -le 6 ]; do
    if "${R_HOME}/bin/Rscript" -e "download.file('${_url}', '${_dest}', mode = 'wb', quiet = TRUE)"; then
      return 0
    fi
    echo "wickra-synth: download attempt ${_attempt}/6 failed (${_url}); the release asset may still be propagating - retrying in 20s..."
    sleep 20
    _attempt=$((_attempt + 1))
  done
  echo "wickra-synth: failed to download ${_url} after 6 attempts"
  return 1
}

# WebAssembly (r-universe / webR): there is no prebuilt wasm C ABI to download,
# but the build image ships cargo (/usr/local/cargo/bin) and emscripten
# (EMSDK on PATH), so build the C ABI staticlib from source for
# wasm32-unknown-emscripten right here, from the release tag this package's
# version names. Building it in the same image with the same emscripten
# avoids any ABI/version mismatch a prebuilt lib would risk. Default features
# are off (threads, where a crate has them): the computation is serial there
# and functionally identical.
if [ "$(uname -s)" = "Emscripten" ]; then
  version=$(sed -n 's/^Version:[[:space:]]*//p' DESCRIPTION)
  echo "wickra-synth: building C ABI from source for wasm32-unknown-emscripten (v${version})"
  build=$(mktemp -d)
  url="https://github.com/wickra-lib/wickra-synth/archive/refs/tags/v${version}.tar.gz"
  wksynth_download "${url}" "${build}/src.tar.gz" || exit 1
  "${R_HOME}/bin/Rscript" -e "untar('${build}/src.tar.gz', exdir = '${build}')"
  root="${build}/wickra-synth-${version}"
  rustup target add wasm32-unknown-emscripten 2>/dev/null || true
  ( cd "${root}" && cargo build -p wickra-synth-c --release \
      --target wasm32-unknown-emscripten --no-default-features ) \
    || { echo "wickra-synth: cargo wasm build failed"; exit 1; }
  cp "${root}/bindings/c/include/wickra_synth.h" src/wickra_synth.h
  cp "${root}/target/wasm32-unknown-emscripten/release/libwickra_synth.a" src/libwickra_synth.a
  rm -rf "${build}"
  # The static archive is linked into the package object; no shared lib to
  # bundle and no rpath needed.
  sed "s|@WKSYNTH_RPATH@||" src/Makevars.in > src/Makevars
  exit 0
fi

if [ -n "${WKSYNTH_INC}" ] && [ -n "${WKSYNTH_LIB}" ]; then
  echo "wickra-synth: using C ABI from WKSYNTH_INC / WKSYNTH_LIB (dev override)"
  inc="${WKSYNTH_INC}"
  lib="${WKSYNTH_LIB}"
else
  version=$(sed -n 's/^Version:[[:space:]]*//p' DESCRIPTION)
  os=$(uname -s)
  arch=$(uname -m)
  case "${os}" in
    Linux)
      case "${arch}" in
        x86_64) triple="x86_64-unknown-linux-gnu" ;;
        aarch64 | arm64) triple="aarch64-unknown-linux-gnu" ;;
        *) echo "wickra-synth: unsupported Linux arch '${arch}' - set WKSYNTH_INC/WKSYNTH_LIB"; exit 1 ;;
      esac
      ;;
    Darwin)
      case "${arch}" in
        x86_64) triple="x86_64-apple-darwin" ;;
        arm64 | aarch64) triple="aarch64-apple-darwin" ;;
        *) echo "wickra-synth: unsupported macOS arch '${arch}' - set WKSYNTH_INC/WKSYNTH_LIB"; exit 1 ;;
      esac
      ;;
    *)
      echo "wickra-synth: unsupported OS '${os}' - set WKSYNTH_INC/WKSYNTH_LIB"
      exit 1
      ;;
  esac
  url="https://github.com/wickra-lib/wickra-synth/releases/download/v${version}/wickra-synth-c-${triple}.tar.gz"
  echo "wickra-synth: downloading C ABI ${triple} for v${version}"
  wksynth_download "${url}" "src/wickra-synth-c.tar.gz" || exit 1
  "${R_HOME}/bin/Rscript" -e "untar('src/wickra-synth-c.tar.gz', exdir = 'src/wickra-synth-c')"
  inc="src/wickra-synth-c/wickra-synth-c-${triple}/include"
  lib="src/wickra-synth-c/wickra-synth-c-${triple}/lib"
fi

# Stage the header and the platform shared library into src/ so the package
# object links with -L. -lwickra_synth and install.libs.R bundles the library.
cp "${inc}/wickra_synth.h" src/wickra_synth.h
staged=""
for f in libwickra_synth.so libwickra_synth.dylib; do
  if [ -f "${lib}/${f}" ]; then
    cp "${lib}/${f}" "src/${f}"
    staged="${f}"
  fi
done
if [ -z "${staged}" ]; then
  echo "wickra-synth: no libwickra_synth.so/.dylib found under ${lib}"
  exit 1
fi

# rpath so the bundled library is found next to wickrasynth.so after install.
case "$(uname -s)" in
  Darwin)
    rpath="-Wl,-rpath,@loader_path"
    # Normalise the dylib id to @rpath so @loader_path resolution applies.
    install_name_tool -id "@rpath/${staged}" "src/${staged}" 2>/dev/null || true
    ;;
  *)
    rpath="-Wl,-rpath,'\$\$ORIGIN'"
    ;;
esac

sed "s|@WKSYNTH_RPATH@|${rpath}|" src/Makevars.in > src/Makevars
echo "wickra-synth: configured (bundled ${staged})"
exit 0
