#!/bin/bash

set -x

NUMA_IDX=0

WKSP=test_ipc
WKSP_CNT=1
WKSP_PAGE=gigantic

TX_MAX=1
RX_MAX=16

TX_DEPTH=32768
TX_MTU=1542

APP_SZ=4032

CONF=tmp/test_ipc.conf

########################################################################

if [ $# -ne 1 ]; then
  echo ""
  echo "        build directory not specified"
  echo ""
  echo "        Usage: $0 [BUILD_DIRECTORY]"
  echo ""
  echo "        This is meant to be run from the firedancer base directory.  It"
  echo "        assumes that there is a firedancer shared memory sandbox setup"
  echo "        on the host in the default location, the user has permissions to"
  echo "        use this sandbox and the host has $WKSP_CNT $WKSP_PAGE unused page(s) on"
  echo "        numa node $NUMA_IDX (and ideally a large number unused huge pages there"
  echo "        too for tile stack usage).  This will recreate from scratch any"
  echo "        pre-existing wksp named $WKSP in the sandbox.  The details"
  echo "        about the shared memory objects used for interprocess"
  echo "        communications will be stored to:"
  echo "                $CONF"
  echo ""
  echo "        A suitable shared memory sandbox can usually be setup by running:"
  echo "                sudo [BUILD_DIRECTORY]/bin/fd_shmem_cfg init 0700 $USER \"\""
  echo "        once."
  echo ""
  exit 1
fi

BIN=$1/bin
UNIT_TEST=$1/unit-test

# Disable permanent log for all the controls we are going to run in here

FD_LOG_PATH=""
export FD_LOG_PATH

# Diagnose the numa topology
# FIXME: DIAGNOSE IF BLOCKED OR STRIPED CORE ASSIGNMENT

NUMA_CNT="$("$BIN"/fd_shmem_ctl numa-cnt "" 2> /dev/null)"

# Do basic box config (if not done already)

"$BIN"/fd_wksp_ctl delete "$WKSP" # Okay if this fails

#sudo "$BIN"/fd_shmem_cfg init 0700 "$USER" ""
#sudo "$BIN"/fd_shmem_cfg alloc 2 gigantic 0 512 huge 0

# Create the wksp

"$BIN"/fd_wksp_ctl new "$WKSP" "$WKSP_CNT" "$WKSP_PAGE" "$NUMA_IDX" 0600 || exit $?

# Setup txs
# FIXME: CONSIDER PUTTING APP_SZ AT END OF NEW-MCACHE CALL?
# FIXME: CONSIDER HAVING USER APP_SZ IN FSEQ CALL?

for((tx_idx=0;tx_idx<TX_MAX;tx_idx++)); do
  TX_CNC[tx_idx]=$("$BIN"/fd_tango_ctl new-cnc "$WKSP" 0 - "$APP_SZ") || exit $?
  TX_MCACHE[tx_idx]=$("$BIN"/fd_tango_ctl new-mcache "$WKSP" "$TX_DEPTH" "$APP_SZ" 0) || exit $?
  TX_DCACHE[tx_idx]=$("$BIN"/fd_tango_ctl new-dcache "$WKSP" "$TX_MTU" "$TX_DEPTH" 1 1 "$APP_SZ") || exit $?
done

# Setup rxs

for((rx_idx=0;rx_idx<RX_MAX;rx_idx++)); do
  RX_CNC[rx_idx]=$("$BIN"/fd_tango_ctl new-cnc "$WKSP" 2 - "$APP_SZ") || exit $?
  RX_FSEQ[rx_idx]=$("$BIN"/fd_tango_ctl new-fseq "$WKSP" 0) || exit $?
done

# Write out the details

mkdir -pv "$(dirname "$CONF")" || exit $?
echo "#!/bin/bash"                     >  "$CONF"
{
  echo "# AUTOGENERATED"
  echo BIN="$BIN"
  echo UNIT_TEST="$UNIT_TEST"
  echo NUMA_IDX="$NUMA_IDX"
  echo NUMA_CNT="$NUMA_CNT"
  echo WKSP="$WKSP"
  echo TX_MAX="$TX_MAX"
  echo TX_CNC=\( "${TX_CNC[*]}" \)
  echo TX_MCACHE=\( "${TX_MCACHE[*]}" \)
  echo TX_DCACHE=\( "${TX_DCACHE[*]}" \)
  echo RX_MAX="$RX_MAX"
  echo RX_CNC=\( "${RX_CNC[*]}" \)
  echo RX_FSEQ=\( "${RX_FSEQ[*]}" \)
} >> "$CONF"

echo Autogenerated unit test configuration at "$CONF"
echo pass
exit 0

