#!/usr/bin/env bash
trap 'killm f' EXIT
#
# Scott Burleigh
# February 6, 2019
#

# documentation boilerplate
CONFIGFILES=" \
./2.bench.bibe/bench.bprc \
./2.bench.bibe/bench.biberc \
./2.bench.bibe/bench.ionconfig \
./2.bench.bibe/bench.ionrc \
./2.bench.bibe/bench.ionsecrc \
./2.bench.bibe/bench.ipnrc \
./3.bench.bibe/bench.bprc \
./3.bench.bibe/bench.biberc \
./3.bench.bibe/bench.ionconfig \
./3.bench.bibe/bench.ionrc \
./3.bench.bibe/bench.ionsecrc \
./3.bench.bibe/bench.ipnrc \
./4.bench.bibe/bench.ionconfig \
./4.bench.bibe/bench.ionrc \
./4.bench.bibe/bench.ionsecrc \
./4.bench.bibe/bench.ipnrc \
"

echo "########################################"
echo
pwd | sed "s/\/.*\///" | xargs echo "NAME: "
echo
echo "PURPOSE: demonstrate a configuration that uses the BIBE
    convergence-layer protocol (over UDP/IP) between neighboring DTN nodes,
    relying on BIBE custodial retransmission for reliability; bundles
    received via BIBE are forwarded to the final destination by STCP.
    Source node 2 sends to destination node 4 via relay node 3 -- node 2
    to node 3 over BIBE/UDP with custodial retransmission, node 3 to node 4
    over STCP.  This is a configuration demonstration and a delivery smoke
    test -- a moderate, fixed number of bundles is sent and custodial
    delivery is confirmed -- not a throughput measurement."

echo
echo "CONFIG: 3 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 "########################################"
echo
echo "***PLEASE NOTE: this benchmark test requires Bundle Protocol version 7."

./cleanup
sleep 1

#echo "Checking for additional memory needed for this demo..."
./check_memory
if [ $? != 0 ]; then
    echo "Can't run, need additional system resources"
    exit 1
fi

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

# Start nodes.
cd 2.bench.bibe
./ionstart >& bench.stdout
cd ../4.bench.bibe
./ionstart >& bench.stdout
cd ../3.bench.bibe
./ionstart >& bench.stdout

sleep 3

# Delivery smoke test: send a moderate, fixed number of bundles from node 2
# to node 4 and confirm they arrive.  Node 2 forwards to node 3 over BIBE
# (with custodial retransmission over lossy UDP), and node 3 forwards to
# node 4 over STCP.  This is a configuration demonstration, not a throughput
# measurement, so the volume is small and delivery is bounded in time; the
# generous wait allows for BIBE custodial retransmission.  A shortfall fails
# fast rather than hanging until the harness timeout.
cd ..
ROOT=$PWD
BUNDLES=10
WAIT_SECS=90
IONSENDFILE="$ROOT/2.bench.bibe/benchsend.txt"
IONRECEIVEFILE="$ROOT/4.bench.bibe/ionreceivefile.txt"
echo "This is a bench-bibect demonstration bundle." > "$IONSENDFILE"
rm -f "$IONRECEIVEFILE"

echo ""
echo "Sending $BUNDLES bundles from node 2 to node 4 via BIBE custody."

# Receiver on node 4.
cd "$ROOT/4.bench.bibe"
bpsink ipn:4.1 > "$IONRECEIVEFILE" &
BPSINKPID=$!
sleep 1

# Send from node 2; each bundle is carried to node 3 over BIBE/UDP under
# custodial retransmission, then on to node 4 over STCP.  A brief throttle
# between sends keeps BIBE from saturating the contact rate.
cd "$ROOT/2.bench.bibe"
i=1
while [ "$i" -le "$BUNDLES" ]
do
    bpsource ipn:4.1 < "$IONSENDFILE" 1>/dev/null 2>/dev/null
    sleep 0.1
    i=$((i + 1))
done
cd "$ROOT"

# Wait (bounded) for delivery at node 4.
echo "Waiting up to ${WAIT_SECS}s for delivery at node 4..."
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 4 via BIBE custody."
    RETVAL=0
else
    echo "FAILURE: only $got of $BUNDLES bundles delivered after ${WAIT_SECS}s."
    RETVAL=1
fi

# Per-node stats, for the demonstration.
for N in 2 3 4
do
    cd "$ROOT/$N.bench.bibe"
    bpstats
done
cd "$ROOT"

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

echo -e "...benchmarking terminated.\n"
exit $RETVAL
