#!/bin/bash
# -*- mode: shell-script; indent-tabs-mode: t; sh-basic-offset: 8; sh-indentation: 8; sh-indent-for-case-alt: + -*-

script_path="$(dirname ${0})"
script_name="$(basename ${0})"
pbench_bin="$(realpath -e ${script_path}/..)"

# source the base script
. "${pbench_bin}"/base

# The sole purpose of this script is to ensure a tool set of your choosing is
# used during the execution of a benchmark on the optional list of remote
# hostnames specified. For a list of available tool sets, use the --help
# option.

# Defaults
toolset="default"
toolset_option_used=0
remotes_arg=""
labels_arg=""
group_arg=""
install_arg=""
default_interval=$(pbench-config interval pbench/tools)
if [[ -z "${default_interval}" ]] ;then
	default_interval=3
fi

function list_tool_sets() {
	local _toolsets_list
	_toolsets_list=$(pbench-config -a pbench/tools 2> /dev/null | grep tool-set | awk '{print $1}')
	if [[ ${?} -ne 0 ]]; then
		return 1
	fi
	local toolsets_list
	local toolset_raw
	local toolset
	for toolset_raw in ${_toolsets_list}; do
		toolset="${toolset_raw%%-*}"
		if [[ ${toolset} == "default" ]]; then
			continue
		fi
		toolsets_list+=" ${toolset}"
	done
	printf -- "${toolsets_list/ /}"
	return 0
}

function usage() {
	local toolsets_raw
	local toolsets_err
	local toolset
	toolsets_raw=$(list_tool_sets)
	toolsets_err=${?}
	
	# Usage is formatted for a 80 column width screen.
	printf -- "usage:\n"
	printf -- "${script_name} [--toolset=<tool-set>] [--group=<group-name>]"
	printf -- " [--interval=<interval>] [--no-install]"
	printf -- " [--remotes=<remote-host>[,<remote-host>]]"
	printf -- " [--labels=<label>[,<label>]] [<tool-set>]\n"
	printf -- "${script_name} [--toolset=<tool-set>] [--group=<group-name>]"
	printf -- " [--interval=<interval>] [--no-install]"
	printf -- " [--remotes=@<remotes-file>] [<tool-set>]\n\n"
	#             1         2         3         4         5         6         7         8
	# (tab)    1 901234567890123456789012345678901234567890123456789012345678901234567890
	printf -- "\tWhere the list of labels must match the list of remotes.\n\n"
	printf -- "\tOne can specify as the argument to the \"--remotes\" option a single\n"
	printf -- "\tremote host, a list of remote hosts (comma-separated, no spaces) or an\n"
	printf -- "\t\"at\" sign (\"@\") followed by a filename.  In this last case, the file\n"
	printf -- "\tshould contain a list of hosts and their (optional) labels.  Each line\n"
	printf -- "\tof the file should contain a host name, optionally followed by a label\n"
	printf -- "\tseparated by a comma (\",\"); empty lines are ignored, and comments are\n"
	printf -- "\tdenoted by a leading hash, or pound (\"#\"), character.\n"
	printf -- "\nAvailable tool sets from ${_PBENCH_AGENT_CONFIG}:\n"
	if [[ ${toolsets_err} -eq 0 ]]; then
		for toolset in ${toolsets_raw}; do
			printf -- "\t${toolset}\n"
		done
	else
		printf -- "\tERROR - list of tool sets not available\n"
	fi
}

# Process options and arguments
opts=$(getopt -q -o ht:g:i:r:l: --longoptions "help,toolset:,group:,interval:,no-install,remote:,remotes:,label:,labels:" -n "getopt.sh" -- "${@}")
if [[ ${?} -ne 0 ]]; then
	printf -- "\n${*}\n" >&2
	printf -- "${script_name}: you specified an invalid option\n\n" >&2
	usage >&2
	exit 1
fi

eval set -- "${opts}"
while true; do
	opt=${1}
	shift
	case "${opt}" in
	-t|--toolset)
		toolset_option_used=1
		if [[ -n "${1}" ]]; then
			toolset="${1}"
			shift
		fi
		;;
	-r|--remote|--remotes)
		if [[ -n "${1}" ]]; then
			remotes_arg=" --remotes=${1}"
			shift
		fi
		;;
	-l|--label|--labels)
		if [[ -n "${1}" ]]; then
			labels_arg=" --labels=${1}"
			shift
		fi
		;;
	-g|--group)
		if [[ -n "${1}" ]]; then
			group_arg=" --group=${1}"
			shift
		fi
		;;
	-i|--interval)
		if [[ -n "${1}" ]]; then
			default_interval="${1}"
			shift
		fi
		;;
	--no-install)
		install_arg=" --no-install"
		;;
	-h|--help)
		usage
		exit 0
		;;
	--)
		break
		;;
	esac
done

if [[ -n "${1}" ]]; then
	toolset=${1}
fi

# Guard against `toolset` being empty when used to fetch the configuration
# value.
if [[ -z "${toolset}" ]]; then
	printf -- "ERROR: Missing <tool-set> argument\n" >&2
	usage >&2
	exit 1
fi

the_tool_set=$(pbench-config -l ${toolset}-tool-set pbench/tools 2>/dev/null)
if [[ ${?} -ne 0 ]]; then
	printf -- "ERROR: failed to fetch tool set, ${toolset}-tool-set, from the pbench-agent configuration file\n" >&2
	exit 1
fi
if [[ -z ${the_tool_set} ]]; then
	printf -- "ERROR: empty tool set, ${toolset}-tool-set, fetched from the pbench-agent configuration file\n" >&2
	exit 1
fi

pbench-register-tool --test-args ${remotes_arg}${labels_arg}
if [[ ${?} -ne 0 ]]; then
	usage >&2
	exit 1
fi

common_notice="is deprecated and will be removed in the Pbench Agent v1.0 future release"

if [[ "${toolset}" == "default" ]]; then
	toolset_list=$(list_tool_sets)
	warn_log "${script_name}: the 'default' tool set ${common_notice}, please use a named tool set argument from one of: ${toolset_list// /, }"
fi

if [[ ${toolset_option_used} -eq 1 ]]; then
	warn_log "${script_name}: the '--toolset' option ${common_notice}, please use an argument value to specify the tool set name."
fi

typeset -i nerrs=0
reg_perf=0
for tool_name in ${the_tool_set}; do
	if [[ ${tool_name} == "perf" ]]; then
		# Ignore, we'll register it after all the others
		reg_perf=1
		continue
	fi
	interval=$(pbench-config interval tools/${tool_name})
	if [[ -z "${interval}" ]]; then
		interval=${default_interval}
	fi
	pbench-register-tool --name=${tool_name}${group_arg}${install_arg}${remotes_arg}${labels_arg} -- --interval="${interval}"
	rc=${?}
	if [[ ${rc} != 0 ]]; then
		(( nerrs++ ))
	fi
done
# low overhead perf
if [[ ${reg_perf} -ne 0 ]]; then
	pbench-register-tool --name=perf${group_arg}${install_arg}${remotes_arg}${labels_arg} -- --record-opts="'-a --freq=100'"
	rc=${?}
	if [[ ${rc} != 0 ]] ;then
		(( nerrs++ ))
	fi
fi

exit ${nerrs}
