#!/usr/bin/env bash
trap 'killm f' EXIT
#
# Scott Burleigh
# March 8, 2017
#

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

echo "########################################"
echo
pwd | sed "s/\/.*\///" | xargs echo "NAME: "
echo
echo "PURPOSE: demonstrate the simplified TCP (STCP) convergence-layer
    protocol between two neighboring nodes residing on the same computer
    and confirm reliable end-to-end bundle delivery.  Source node 2 sends
    to destination node 3 over loopback STCP/IP.  This is a configuration
    demonstration and a delivery smoke test -- a moderate, fixed number of
    bundles is sent and delivery is confirmed -- 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.stcp
./ionstart
../../../system_up -i "p 30" -b "p 30"
if [ $? -eq 2 ]; then
    echo ""
else
    echo "Node 2 not started: Aborting Test"
    exit 1
fi

cd ../3.bench.stcp
./ionstart
../../../system_up -i "p 30" -b "p 30"
if [ $? -eq 2 ]; then
    echo ""
else
    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 STCP 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; a shortfall fails fast
# rather than hanging until the harness timeout.
cd ..
ROOT=$PWD
BUNDLES=10
WAIT_SECS=60
IONSENDFILE="$ROOT/2.bench.stcp/benchsend.txt"
IONRECEIVEFILE="$ROOT/3.bench.stcp/ionreceivefile.txt"
echo "This is a bench-stcp demonstration bundle." > "$IONSENDFILE"
rm -f "$IONRECEIVEFILE"

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

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

# Send from node 2 over the STCP convergence layer.
cd "$ROOT/2.bench.stcp"
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.
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 STCP."
    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.stcp"
    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
