#!/bin/bash

# Default parameters:
dir="$JR_HOME/vsuite"
exec=1
jrv_i=" "
jrv_s=" "
killem=0
lim=3
mpc=""		# Unknown at this point.
nodes=20
nth=4
robust=1
usecache=0	# 1 = yes, 0 = auto, -1 = no
verbosity=0	# 1 = verbose, 0 = normal, -1 = quiet
declare -i usecache verbosity

# Other variables:
fail=-1
me=`whoami`
rm="/bin/rm -f"
mkdir="/bin/mkdir -p"

cachedir=".RJRVCACHE"
scache="$cachedir/search"

rjrv="$JR_HOME/rjrv/rjrv"
wait="$JR_HOME/rjrv/timeout"
master="$JR_HOME/rjrv/master"
merger="$JR_HOME/rjrv/mergeout/mo"
opts="-q -x -o BatchMode=yes -o StrictHostKeyChecking=no"

declare -i max
mstr="^pc2[1-9]$|^pc3[0-5]$"
pstr="^pc[1-2]?[0-9]$|^pc3[0-5]$"
up=`ruptime -lr | grep " up" | cut -d' ' -f1 | egrep "$pstr"`
gpc=`echo "$up" | egrep "$mstr" | head -1`
pcs=(`echo "$up"`)
max=${#pcs[*]}-1

usage="Usage: rjrv [-cfghikqrsvz] [-d dir] [-l limit] [-m master] [-n nodes] [-t threads]
Run jrv much faster than normal by distributing the workload across many CSIF machines.

	-c	Force the use of the rjrv cache.
	-d	Specify the starting directory.
	-f	Fast: Skip connection verifications.
	-g	Google: I'm feeling lucky! (-cfqs -m $gpc -n $max).
	-h	Print this help message and exit.
	-i	Pass the -i option on to jrv.
	-k	Kill: Terminate all your processes on the CSIF machines.
	-l	Set the timeout limit for the worker connections.
	-m	Specify the machine to use as the master.
	-n	Specify the number of CSIF pc* machines to use ($max max).
	-q	Quiet: Print only the progress bar and any errors that occur.
	-r	Rebuild: Search for Script files and do not use the rjrv cache.
	-s	Return $fail if errors are found in the JR implemenation.
	-t	Specify the number of threads to execute per machine.
	-v	Verbose: Print out information about each thread as it is initialized.
	-z	Debug: Go through the motions without actually executing jrv.

Defaults are: dir = $dir, limit = $lim, master is dynamic, nodes = $nodes, threads = $nth."

# Set up variables according to the command-line arguments:
while [ -n "$1" ]; do
	case "$1" in
		-c)
			usecache+=1
			shift
		;;
		-d)
			cd $2 &> /dev/null
			if [ $? -ne 0 ]; then
				echo "$0: Error: Invalid directory" 1>&2
				exit 1
			fi

			dir=`pwd`
			shift; shift
		;;
		-f)
			if [ -z "$mpc" ]; then
				mpc=$gpc
			fi

			robust=0
			shift
		;;
		-g)
			jrv_s="-s"
			mpc=$gpc
			nodes=$max
			robust=0
			usecache=1
			verbosity=-1
			shift
		;;
		-h)
			echo "$usage"
			exit
		;;
		-i)
			jrv_i="-i"
			shift
		;;
		-k)
			killem=1
			shift
		;;
		-l)
			lim=$2
			shift; shift
		;;
		-m)
			mpc=$2
			shift; shift
		;;
		-n)
			nodes=$2
			shift; shift
		;;
		-q)
			verbosity+=-1
			shift
		;;
		-r)
			usecache+=-1
			shift
		;;
		-s)
			jrv_s="-s"
			shift
		;;
		-t)
			nth=$2
			shift; shift
		;;
		-v)
			verbosity+=1
			shift
		;;
		-z)
			exec=0
			shift
		;;
		--)
			break
		;;
		*)
			echo -e "$0: Error: Unrecognized option $1\n" 1>&2
			echo "$usage"
			exit 2
		;;
	esac
done

if [ $killem -eq 1 -a $me = "shepard" ]; then
	for pc in ${pcs[*]}; do
		echo -n "."
		$wait $lim ssh $opts $pc pkill -9 -u $me
	done

	exit
fi



log="$dir/.log"
timer="$log/timer"
merged="$log/merged"

declare -i pos=0

while [ -z "$mpc" ]; do
	pc=${pcs[pos]}; pos+=1

	if [ -z "$pc" ]; then
		echo "Error: could not create master!"
		exit 3
	fi

	if [ -n "`echo $pc | egrep $mstr`" ]; then
		$wait $lim ssh $opts $pc date &> /dev/null

		if [ $? -eq 0 ]; then
			mpc=$pc
		fi
	fi
done

pcs=(`echo "$up" | grep -v $mpc`)
if [ $verbosity -ge 0 ]; then endl="\n"; fi
if [ $exec -eq 1 ]; then $mkdir $log; $rm $log/* &> /dev/null; fi
cmd="$master $cachedir $dir $exec \"$jrv_i\" \"$jrv_s\" $lim $log $master \"$mkdir\" $nodes"
cmd="$cmd $nth \"$opts\" \"${pcs[*]}\" $rjrv \"$rm\" $robust $scache $usecache $verbosity $wait"





# Start the tests:
echo `date` >> $timer
echo "Starting master on $mpc..."
ssh $opts $mpc $cmd; status=$?
echo `date` >> $timer
if [ $exec -eq 0 -o $status -ne 0 ]; then exit $status; fi





# Merge the log files:
$merger $log

# Search for and report any errors:
echo
# 2009-03-10
# added check for differs
# (jrv code is written so it can also generate "missing",
# but that's not executed; instead cmp complains with exit status 255)
# also now define search string as variable.
# added space to search string to avoid potential conflicts
# with vsuite filenames, which are presumed not to have spaces.

searchfor='expected |differs '
tested=`egrep -v "$searchfor" $merged | wc -l`
ndirs=`grep "^ndirs: " $scache | cut -d' ' -f2`
errors=`egrep -H "$searchfor" $log/pc* | cut -d'.' -f2-`

## echo tested is $tested ndirs is $ndirs errors is $errors

if [ $tested -ne $ndirs ]; then
	echo "Error: Some of the 'Script' files may not have been executed!  Please try again."
	exit -2
elif [ -n "$errors" ]; then
	echo "The following errors were found:"
	echo "$errors"

	if [ "$jrv_s" = "-s" ]; then
		exit $fail
	fi
else
	echo "No errors detected."
fi
