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

ROOT_DIR="$(cd "$(dirname "$0")/.." && pwd)"
VENDOR_DIR="$ROOT_DIR/vendor/linuxcnc"
WRAP_DIR="$ROOT_DIR/runtime/core/linuxcnc_wrap"
SHIM_DIR="$ROOT_DIR/runtime/core/shims"
INCLUDE_DIR="$ROOT_DIR/runtime/core/include"
OUT_DIR="$ROOT_DIR/build/wasm/tp"
OBJ_DIR="$OUT_DIR/obj"

source "$ROOT_DIR/tools/wasm_incremental_build_lib.sh"

mkdir -p "$OUT_DIR" "$OBJ_DIR"

TARGET="linuxcnc_tp_wasm"
: > "$OUT_DIR/$TARGET.stdout.log"
: > "$OUT_DIR/$TARGET.stderr.log"

COMMON_FLAGS=(
  -O2
  -D_GNU_SOURCE
  -DM_PI=3.14159265358979323846
  -I"$WRAP_DIR"
  -I"$SHIM_DIR"
  -I"$INCLUDE_DIR"
  -I"$VENDOR_DIR/src"
  -I"$VENDOR_DIR/src/rtapi"
  -I"$VENDOR_DIR/src/emc"
  -I"$VENDOR_DIR/src/emc/nml_intf"
  -I"$VENDOR_DIR/src/emc/motion"
  -I"$VENDOR_DIR/src/emc/tp"
  -I"$VENDOR_DIR/src/emc/kinematics"
  -I"$VENDOR_DIR/src/libnml/posemath"
)

C_FLAGS=(
  -std=gnu11
  "${COMMON_FLAGS[@]}"
)

CXX_FLAGS=(
  -std=c++20
  -fpermissive
  "${COMMON_FLAGS[@]}"
)

SOURCES=(
  "$VENDOR_DIR/src/emc/tp/tp.c"
  "$VENDOR_DIR/src/emc/tp/tc.c"
  "$VENDOR_DIR/src/emc/tp/tcq.c"
  "$VENDOR_DIR/src/emc/tp/spherical_arc.c"
  "$VENDOR_DIR/src/emc/tp/blendmath.c"
  "$VENDOR_DIR/src/emc/tp/sp_scurve.c"
  "$VENDOR_DIR/src/emc/tp/ruckig_wrapper.c"
  "$VENDOR_DIR/src/emc/tp/cruckig/block.c"
  "$VENDOR_DIR/src/emc/tp/cruckig/brake.c"
  "$VENDOR_DIR/src/emc/tp/cruckig/calculator.c"
  "$VENDOR_DIR/src/emc/tp/cruckig/cruckig.c"
  "$VENDOR_DIR/src/emc/tp/cruckig/input_parameter.c"
  "$VENDOR_DIR/src/emc/tp/cruckig/output_parameter.c"
  "$VENDOR_DIR/src/emc/tp/cruckig/profile.c"
  "$VENDOR_DIR/src/emc/tp/cruckig/roots.c"
  "$VENDOR_DIR/src/emc/tp/cruckig/trajectory.c"
  "$VENDOR_DIR/src/emc/tp/cruckig/position_first_step1.c"
  "$VENDOR_DIR/src/emc/tp/cruckig/position_first_step2.c"
  "$VENDOR_DIR/src/emc/tp/cruckig/position_second_step1.c"
  "$VENDOR_DIR/src/emc/tp/cruckig/position_second_step2.c"
  "$VENDOR_DIR/src/emc/tp/cruckig/position_third_step1.c"
  "$VENDOR_DIR/src/emc/tp/cruckig/position_third_step2.c"
  "$VENDOR_DIR/src/emc/tp/cruckig/velocity_second_step1.c"
  "$VENDOR_DIR/src/emc/tp/cruckig/velocity_second_step2.c"
  "$VENDOR_DIR/src/emc/tp/cruckig/velocity_third_step1.c"
  "$VENDOR_DIR/src/emc/tp/cruckig/velocity_third_step2.c"
  "$VENDOR_DIR/src/emc/nml_intf/emcpose.c"
  "$VENDOR_DIR/src/libnml/posemath/posemath.cc"
  "$VENDOR_DIR/src/libnml/posemath/_posemath.c"
  "$VENDOR_DIR/src/libnml/posemath/sincos.c"
  "$WRAP_DIR/linuxcnc_tp_wasm.c"
)

OBJECTS=()
for source in "${SOURCES[@]}"; do
  obj="$(source_object_path "$source" "$ROOT_DIR" "$OBJ_DIR")"
  OBJECTS+=("$obj")
  case "$source" in
    *.cc|*.cpp|*.cxx)
      compile_wasm_object "$TARGET" "$source" "$obj" "$OUT_DIR" "${CXX_FLAGS[@]}"
      ;;
    *)
      compile_wasm_object "$TARGET" "$source" "$obj" "$OUT_DIR" "${C_FLAGS[@]}"
      ;;
  esac
done

link_wasm_module \
  "$TARGET" \
  "$OUT_DIR/linuxcnc_tp.js" \
  "$OUT_DIR" \
  -O2 \
  "${OBJECTS[@]}" \
  -s MODULARIZE=1 \
  -s EXPORT_ES6=1 \
  -s ENVIRONMENT=web,node \
  -s ALLOW_MEMORY_GROWTH=1 \
  -s NO_EXIT_RUNTIME=1 \
  -s EXPORTED_FUNCTIONS='["_malloc","_free","_lctp_run_probe","_lctp_free_string"]' \
  -s EXPORTED_RUNTIME_METHODS='["UTF8ToString"]'
