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

# identify the test for later analysis
echo "Date: `date`"
echo "Benchmark: `pwd`"
echo "Hostname: `hostname`"
echo "UnameOS: `uname -s`"
echo "UnameProcessor: `uname -p`"
echo "UnameMachine: `uname -m`"
echo "UnameRelease: `uname -r`"
echo "UnameAll: `uname -a`"

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

echo "########################################"
echo
pwd | sed "s/\/.*\///" | xargs echo "NAME: "
echo
echo "PURPOSE: demonstrate bundle exchange over the DTNRG-standard TCP
    convergence-layer protocol between two neighboring nodes residing on
    the same computer, connected over loopback TCP/IP.  This is a
    configuration demonstration and a delivery smoke test -- a moderate,
    fixed number of bundles is sent from node 2 to node 3 and delivery is
    confirmed -- not a throughput measurement (loopback throughput is not
    representative of any real deployment)."

if [ -n "$DEBUG" ]; then
    echo
    echo "CONFIG: 2 node custom:"
    echo
    for N in $CONFIGFILES
    do
        echo "$N:"
        cat "$N"
        echo "# EOF"
        echo
    done
fi

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

echo "#########################################################################"
echo "##  Starting ION Nodes"
echo "#########################################################################"
echo

# Start nodes.
(cd 2.bench.tcp; ./ionstart)
(cd 2.bench.tcp; ../../../system_up -i "p 30" -b "p 30")
if [ $? -ne 2 ]; then
    echo "Node 2 not started: Aborting Test"
    exit 1
fi

(cd 3.bench.tcp; ./ionstart)
(cd 3.bench.tcp; ../../../system_up -i "p 30" -b "p 30")
if [ $? -ne 2 ]; then
    echo "Node 3 not started: Aborting Test"
    exit 1
fi

sleep 3

# Delivery smoke test: send a moderate, fixed number of bundles from node 2
# to node 3 over the loopback TCP convergence layer and confirm they arrive.
# This is a configuration demonstration, not a throughput measurement, so the
# volume is small and delivery is bounded in time.
ROOT=$PWD
BUNDLES=10
WAIT_SECS=60
IONSENDFILE="$ROOT/2.bench.tcp/benchsend.txt"
IONRECEIVEFILE="$ROOT/3.bench.tcp/ionreceivefile.txt"
echo "This is a bench-tcp demonstration bundle." > "$IONSENDFILE"
rm -f "$IONRECEIVEFILE"

echo ""
echo "Sending $BUNDLES bundles from node 2 to node 3 over TCP."

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

# Send from node 2 over the loopback TCP convergence layer.
cd "$ROOT/2.bench.tcp"
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.  Reliable TCP loopback delivers
# quickly; 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 TCP."
    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
do
    cd "$ROOT/$N.bench.tcp"
    bpstats
done
cd "$ROOT"

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

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