#!/usr/bin/env bash
trap 'killm f' EXIT
#
# Scott Burleigh
# August 9, 2012
#
# Shawn Ostermann
# Made it more flexible for testing
# October 11, 2023
#

# documentation boilerplate
CONFIGFILES=" \
./global.ionrc \
./2.bench.ltp/bench.ltprc \
./2.bench.ltp/bench.bprc \
./2.bench.ltp/bench.ionconfig \
./2.bench.ltp/bench.ionrc \
./2.bench.ltp/bench.ionsecrc \
./2.bench.ltp/bench.ipnrc \
./3.bench.ltp/bench.ltprc \
./3.bench.ltp/bench.bprc \
./3.bench.ltp/bench.ionconfig \
./3.bench.ltp/bench.ionrc \
./3.bench.ltp/bench.ionsecrc \
./3.bench.ltp/bench.ipnrc \
"

echo "########################################"
echo
pwd | sed "s/\/.*\///" | xargs echo "NAME: "
echo
echo "PURPOSE: demonstrate reliable (RED) Licklider Transmission
    Protocol as a BP convergence layer and confirm end-to-end bundle
    delivery.  Two neighboring nodes reside on the same computer and
    communicate over loopback UDP (udplso/udplsi).  A moderate, fixed
    number of bundles is sent from node 2 to node 3 and delivery is
    confirmed.  Because LTP RED is reliable, every bundle is expected
    to arrive.  This is a configuration demonstration and a delivery
    smoke test, not a throughput measurement (loopback throughput is
    not representative of any real deployment)."
echo
echo "CONFIG: 2 node custom:"
echo
for N in $CONFIGFILES
do
    echo "$N:"
    cat "$N"
    echo "# EOF"
    echo
done
echo "OUTPUT: Terminal messages will relay results."
echo
echo "########################################"

./cleanup
sleep 1

echo "Starting ION..."
export ION_NODE_LIST_DIR=$PWD
rm -f ./ion_nodes
RETVAL=0

# Start nodes.
(cd 2.bench.ltp; ./ionstart)
(cd 3.bench.ltp; ./ionstart)
sleep 3

ROOT=$PWD
BUNDLES=10
WAIT_SECS=60
IONSENDFILE="$ROOT/2.bench.ltp/benchsend.txt"
IONRECEIVEFILE="$ROOT/3.bench.ltp/ionreceivefile.txt"
echo "This is a bench-ltp demonstration bundle." > "$IONSENDFILE"
rm -f "$IONRECEIVEFILE"

echo ""
echo "Sending $BUNDLES bundles from node 2 to node 3 over LTP (RED)."

# Receiver on node 3.
cd "$ROOT/3.bench.ltp"
bpsink ipn:3.1 > "$IONRECEIVEFILE" &
BPSINKPID=$!
sleep 1

# Send from node 2; each invocation transmits one bundle over LTP.
cd "$ROOT/2.bench.ltp"
i=1
while [ "$i" -le "$BUNDLES" ]
do
    bpsource ipn:3.1 < "$IONSENDFILE" 1>/dev/null 2>/dev/null
    i=$((i + 1))
done
cd "$ROOT"

# Wait (bounded) for delivery at node 3.  LTP RED is reliable, so all
# bundles are expected; a shortfall fails fast here rather than hanging
# until the harness timeout.
echo "Waiting up to ${WAIT_SECS}s for delivery at node 3..."
elapsed=0
got=0
while [ "$elapsed" -lt "$WAIT_SECS" ]
do
    got=$(grep -c "^ION event: Payload delivered\." "$IONRECEIVEFILE" 2>/dev/null)
    [ -z "$got" ] && got=0
    if [ "$got" -ge "$BUNDLES" ]
    then
        break
    fi
    sleep 2
    elapsed=$((elapsed + 2))
done

if [ "$got" -ge "$BUNDLES" ]
then
    echo "SUCCESS: $got of $BUNDLES bundles delivered to node 3 over LTP."
    RETVAL=0
else
    echo "FAILURE: only $got of $BUNDLES bundles delivered after ${WAIT_SECS}s."
    RETVAL=1
fi

# Stop the receiver.
kill -2 "$BPSINKPID" >/dev/null 2>&1
sleep 1
kill -9 "$BPSINKPID" >/dev/null 2>&1

echo ""
echo "Stopping ION..."
killm f
echo "...demonstration terminated."
exit $RETVAL
