#!/usr/bin/env bash
trap 'killm f' EXIT
#
# Scott Burleigh
# August 9, 2012
#

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

echo "########################################"
echo
pwd | sed "s/\/.*\///" | xargs echo "NAME: "
echo
echo "PURPOSE: demonstrate bundle transfer over the DGR convergence-layer
    protocol (an Internet-compatible, retransmitting variant of LTP over
    UDP/IP) between two neighboring nodes residing on the same computer.
    Source node 2 sends to destination node 3.  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 "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.dgr
./ionstart
cd ../3.bench.dgr
./ionstart

echo -e "Sleeping 10 seconds to allow buffer to clear\n"
sleep 10

# Delivery smoke test: send a moderate, fixed number of bundles from node 2
# to node 3 over the DGR 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.
cd ..
ROOT=$PWD
BUNDLES=10
WAIT_SECS=60
IONSENDFILE="$ROOT/2.bench.dgr/benchsend.txt"
IONRECEIVEFILE="$ROOT/3.bench.dgr/ionreceivefile.txt"
echo "This is a bench-dgr demonstration bundle." > "$IONSENDFILE"
rm -f "$IONRECEIVEFILE"

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

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

# Send from node 2.
cd "$ROOT/2.bench.dgr"
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.  DGR retransmits lost segments, so
# all bundles should arrive; 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 DGR."
    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.dgr"
    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
