#!/bin/sh

if test $# -ne 4; then
	echo "Usage: $0 <experiment-config> <peers-directory> <node-count> <experiment-length-in-min>"
	exit 1
fi

# expand experiment config filename to full path
cfg_name=$(basename $1)
cfg_path=$(dirname $1)
cd $cfg_path
cfg_path=$(pwd)
BRANCH=$(pwd)
EXPERIMENT_CONFIG=$cfg_path/$cfg_name
source $EXPERIMENT_CONFIG

cd $2
PEERS_DIRECTORY=$(pwd)
NODE_COUNT=$3
EXPERIMENT_LENGTH=$4

current_hour=$(date +%H)
day_of_week=$(date +%u)
if test $current_hour -lt 20 && test $current_hour -gt 8 && test $day_of_week -lt 6 && test $EXPERIMENT_LENGTH -ge 15 ; then
    # according to: http://www.cs.vu.nl/das4/usage.shtml
    # working hours: Mon-Fri, 8:00 - 20:00
    echo "* Adjusting experiment length from $EXPERIMENT_LENGTH min to 14 min (it's working hours!)"
    # EXPERIMENT_LENGTH=14
fi

rm -rf $PEERS_DIRECTORY/control
rm -f $PEERS_DIRECTORY/peers

cd $PEERS_DIRECTORY
rm -rf `find . -type d -name 'output'`
mkdir -p $PEERS_DIRECTORY/output

# save SVN version of ${BRANCH}
cd ${BRANCH}
svnversion | sed 's/.*:\([0-9]*\)*[A-Z]*$/\1/g' > $PEERS_DIRECTORY/output/svn_version.txt

cd ${BRANCH}
echo "* Cleaning up *.pyc files..."
find . -iregex '.*\(dispersy\|Community\).*\.py[co]' -delete
echo "* Recompiling python classes..."
(/usr/bin/env python | grep -v Listing ) <<END
from compileall import compile_dir
import re
compile_dir('.', rx=re.compile('/[.]svn'), force=False)
END

(/usr/bin/env python -O | grep -v Listing ) <<END
from compileall import compile_dir
import re
compile_dir('.', rx=re.compile('/[.]svn'), force=False)
END

cd $PEERS_DIRECTORY
PEER_COUNT=$(cat peer.count)

cd ${BRANCH}
echo "* Starting the DAS4 config sync server in the background..."
./das4-config-sync-server.py $PEER_COUNT $INITIAL_DELAY & # it automatically stops after all peers received their config
CONFIG_SERVER_PID=$!
#disown  # remove job from the job table of the current bash process

cd $PEERS_DIRECTORY

echo "* Starting experiment on $NODE_COUNT nodes ("$[$PEER_COUNT / $NODE_COUNT]" peers per node)..."

#echo "* Reserving $NODE_COUNT nodes... "
reservation_length=$[$EXPERIMENT_LENGTH * 60 + 60]
echo "* Job reservation length is: $EXPERIMENT_LENGTH min (experiment length) + 1 min = $reservation_length seconds"
#RESERVATION_ID=$(preserve -# $NODE_COUNT $reservation_length | head -n1 | sed 's/Reservation number \(.*\):/\1/g')
#echo "* Done. Reservation ID: $RESERVATION_ID (you can see reservation status with 'preserve -llist')"
echo "* Sending job to DAS4..."

JOB_STATUS_FILE=/tmp/das4_job_$USER
#prun SGE_TASK_LAST=${NODE_COUNT} -v -reserve $RESERVATION_ID -np ${NODE_COUNT} ${BRANCH}/das4-node $EXPERIMENT_CONFIG ${BRANCH} $PEERS_DIRECTORY $PEER_COUNT $EXPERIMENT_LENGTH &
(prun SGE_TASK_LAST=${NODE_COUNT} -t $reservation_length -v -np ${NODE_COUNT} ${BRANCH}/das4-node $EXPERIMENT_CONFIG ${BRANCH} $PEERS_DIRECTORY $PEER_COUNT $EXPERIMENT_LENGTH 2>&1 | tee $JOB_STATUS_FILE ) &
PRUN_PID=$! # well, not really prun's PID, but we'll be using this one to send prun and tee signals
sleep 2
RESERVATION_ID=$(head -n1 $JOB_STATUS_FILE | sed 's/Reservation number \([0-9]*\):.*/\1/g')
rm $JOB_STATUS_FILE
echo
preserve -llist
echo
echo "*** If the job gets queued, you can cancel waiting using Ctrl+C"
echo "*** (check DAS4 status with 'preserve -llist')"
echo
echo "* Waiting for peers to start and receive their configuration..."

function stop_everything {
    echo "* Stopping config server..."
    kill -9 $CONFIG_SERVER_PID &>/dev/null
    echo "* Stopping DAS4 job..."
    kill -1 $PRUN_PID &>/dev/null # according to http://www.cs.vu.nl/das4/prun.shtml, must send SIGINT
    #echo "* Canceling reservation..."
    #preserve -c $RESERVATION_ID
    echo "* Cleanup complete."
    exit
}

trap stop_everything SIGHUP SIGTERM SIGINT
# disown $CONFIG_SERVER_PID # doesn't work
wait $CONFIG_SERVER_PID
start_time=$(date +%s)
start_time_s=$(awk 'BEGIN {print strftime("%Y-%m-%d %H:%M:%S",'$start_time')}')
let stop_time=$start_time+$[$EXPERIMENT_LENGTH * 60]
stop_time_s=$(awk 'BEGIN {print strftime("%Y-%m-%d %H:%M:%S",'$stop_time')}')
echo "* Peers received their configuration."
echo "* Experiment started ($start_time_s)"
echo "* You can cancel the experiment using 'preserve -c $RESERVATION_ID'"
echo "* You can check DAS4 jobs status with 'preserve -llist'"
echo
echo "* Waiting for the experiment to end (expected finish time: $stop_time_s)..."
wait $PRUN_PID
echo "* Experiment completed."
