#!/bin/sh

script_name=$0
submit_dir=${USER}-workers
use_master_name=0
pwfile=""
arguments=""

host=
port=
count=1

cores=
memory=
disk=

specified_resources=0

show_help()
{
	# stub for user defined help options
	echo "" > /dev/null
}

show_help_common()
{
	echo "Use: $script_name [worker options] [batch specific options] <servername> <port> <num-workers>"
	echo "         or"
	echo "     $script_name [worker options] --master-name <name> [batch specific options] <num-workers>"

	echo "worker options:"

	echo "  -M,--master-name <name>   Name of the preferred master for worker."
	echo "  -N,--name <name>          Same as -M (backwards compatibility)."
	echo "  -C,--catalog <catalog>    Set catalog server to <catalog>. <catalog> format: HOSTNAME:PORT."
	echo "  -t,--timeout <time>       Abort after this amount of idle time. (default=900s)."
	echo "  -d,--debug <subsystem>    Enable debugging on worker for this subsystem (try -d all to start)."
	echo "  -w,--tcp-window-size <siz e>  Set TCP window size."
	echo "  -i,--min-backoff <time>   Set initial value for backoff interval when worker fails to connect to a master. (default=1s)"
	echo "  -b,--max-backoff <time>   Set maxmimum value for backoff interval when worker fails to connect to a master. (default=60s)"
	echo "  -z,--disk-threshold <size >   Set available disk space threshold (in MB). When exceeded worker will clean up and reconnect. (default=100MB)"
	echo "  -A,--arch <arch>          Set architecture string for the worker to report to master instead of the value in uname."
	echo "  -O,--os <os>              Set operating system string for the worker to report to master instead of the value in uname."
	echo "  -s,--workdir <path>       Set the location for creating the working directory of the worker."
	echo "  -P,--password <pwfile>    Password file to authenticate workers to master."
	echo "  --cores <num>             Set the number of cores each worker should use (0=auto). (default=1)"
	echo "  --memory <size>           Manually set the amonut of memory (in MB) reported by this worker."
	echo "  --disk <size>             Manually set the amount of disk (in MB) reported by this worker."
	echo "  -E,--worker-options <str> Extra options passed to work_queue_worker"
	echo "  -h,--help                 Show this help message."
	echo ""
	echo "batch specific options:"
	show_help
	exit 0
}

parse_arguments()
{
	echo "" > /dev/null
}

parse_arguments_common()
{
	# Used options (as in the getopts format):  M:N:C:t:d:w:i:b:z:A:O:s:r:P:h
	while [ $# -gt 0 ]
	do
		case $1 in
			-a | --advertise)
			# Leave here for backwards compatibility
			arguments="$arguments -a"
			use_master_name=1
			;;
			-M | --master-name)
			shift
			arguments="$arguments -M $1"
			use_master_name=1
			;;
			-N | --name)
			shift
			arguments="$arguments -M $1"
			use_master_name=1
			;;
			-C | --catalog)
			shift
			arguments="$arguments -C $1"
			;;
			-t | --timeout)
			shift
			arguments="$arguments -t $1"
			;;
			-d | --debug)
			shift
			arguments="$arguments -d $1"
			;;
			-w | --tcp-window-size)
			shift
			arguments="$arguments -w $1"
			;;
			-i | --min-backoff)
			shift
			arguments="$arguments -i $1"
			;;
			-b | --max-backoff)
			shift
			arguments="$arguments -b $1"
			;;
			-z | --disk-threshold)
			shift
			arguments="$arguments -z $1"
			;;
			-A | --arch)
			shift
			arguments="$arguments -A $1"
			;;
			-O | --os)
			shift
			arguments="$arguments -O $1"
			;;
			-s | --workdir)
			shift
			arguments="$arguments -s $1"
			;;
			-P | --password)
			shift
			pwfile=$1
			arguments="$arguments -P $pwfile"
			;;
			--cores)
			shift
			arguments="$arguments --cores $1"
			cores="$1"
			specified_resources=1
			;;
			--memory)
			shift
			arguments="$arguments --memory $1"
			memory="$1"
			specified_resources=1
			;;
			--disk)
			shift
			arguments="$arguments --disk $1"
			disk="$1"
			specified_resources=1
			;;
			-r)
			shift
			requirements="$requirements $1"
			;;
			-E | --worker-options)
			shift
			arguments="$arguments $1"
			;;
			-h | --help)
			show_help_common
			;;
			*)
			break
			;;
		esac
		shift
	done

	parse_arguments "$@"

	while [ $# -gt 0 ]
	do
		case $1 in
			-*)
			;;
			*)
			break
			;;
		esac
		shift
	done

	set_up_master_address $1 $2 $3 $4

	if [ $specified_resources = 1 -a -n "$SGE_WARNING" ]
	then
		echo "Worker resources were manually specified. Remember to also describe your resources according to your local qsub system (e.g., -p '-pe smp 4'. See also the --sge-parameter option in the configure script when manually compiling CCTools.)" 1>&2
	fi
}


set_up_master_address()
{
	if [ $use_master_name = 0 ]; then
		if [ $# -ne 3 ] ; then
			echo "3 arguments (<servername> <port> <num-workers>) are expected while $# are present: \"$@\"." 1>&2
			echo "To view the help message, type: $script_name -h" 1>&2
			exit 1
		fi
		host=$1
		port=$2
		count=$3
	else
		if [ $# -ne 1 ]
		then
			echo "1 argument (<num-workers>) is expected while $# is present: \"$@\"." 1>&2
			echo "To view the help message, type: $script_name -h" 1>&2
			exit 1
		fi
		host=
		port=
		count=$1
	fi
}

set_up_working_directory()
{
	# Set up a local temporary directory to manage the log files.
	# home directories on shared filesystems are often not accessible

	echo "Creating worker submit scripts in ${submit_dir}..."
	mkdir -p ${submit_dir}

	# Copy the worker executable into the temporary directory,
	# for similar reasons.

	worker=`which work_queue_worker 2>/dev/null`
	if [ $? != 0 ]
	then
		echo "$0: please add 'work_queue_worker' to your PATH." 1>&2
		exit 1
	fi

	gpu_detection=`which cctools_gpu_autodetect 2>/dev/null`
	if [ $? != 0 ]
	then
		echo "$0: could not find cctools_gpu_autodetect in PATH. gpus will not be automatically detected." 1>&2
	else
		cp $gpu_detection ${submit_dir}
	fi

	cd ${submit_dir}
	cp $worker .
}

set_up_password_file()
{
	# stub for password file code specific to batch system
	echo "" > /dev/null
}

set_up_password_file_common()
{
	# If a password file has been selected, check for existence,
	# copy it into the submission directory, then add it to
	# the transfer input files list.

	if [ X${pwfile} != X ]
	then
		if [ ! -f $pwfile ]
		then
			echo "$script_name password file $pwfile not found" 1>&2
			exit 1
		fi

		cp $pwfile ${submit_dir}

		set_up_password_file
	fi
}

submit_workers_command()
{
	echo "Please define a submit_workers_command function in your script" 1>&2
}

submit_workers()
{
	parse_arguments_common "$@"
	set_up_working_directory
	set_up_password_file_common
	submit_workers_command

	exit $?
}

if [ "${script_name##*/}" = work_queue_submit_common ]
then
	echo "This script provides support functions for the work queue"
	echo "workers submission scripts, and cannot be executed by itself."
fi
