#!/usr/local/bin/cbsd
#v11.1.0
MYARG="mode"
MYOPTARG="logfile notify autoflush nodetask owner after client_id jname jconf exclusive cast_args"
MYDESC="Task queue management"
CBSDMODULE="taskd"
ADDHELP="mode=new <cmd>, mode=cancel <jobid>, mode=cancelall, mode=flushall\n\
notify=0 for prevent notification of result to email\n\
autoflush=0,1,2 (0 - all jobs stored in base, 1 - autoflush completed cmd, 2 - autoflush for all cm)\n\
after=X - shedule a new task to run only after job with id X will be successfully completed\n\
exclusive= prevent multiple task running by cmd,jname,owner params. When 1 - is exclusive job\n"
EXTHELP="wf_taskd"

. ${subrdir}/nc.subr

# todo: rewrite to substr
# for init: disable double args initialization
#double_args=0

. ${cbsdinit}

. ${system}
[ -z "${exclusive}" ] && exclusive=0

try_remote()
{
	local _ip node="${nodetask}"

	. ${nodes}

	_ip=$( cbsdsqlro nodes SELECT ip FROM nodelist WHERE nodename=\"${node}\" 2>/dev/null )
	[ -z "${_ip}" ] && err 1 "${N1_COLOR}No such ip for node: ${N2_COLOR}${node}${N0_COLOR}"

	if ! check_locktime ${ftmpdir}/shmux_${_ip}.lock > /dev/null 2>&1; then
		err 1 "${N1_COLOR}Node is offline: ${N2_COLOR}${node}${N0_COLOR}"
	fi

	rexe node=${node} /usr/local/bin/cbsd task autoflush=2 mode=new owner=${nodename} $@
	echo "NODE: ${node}"
	echo "TASK STR: $@"
	owner="${nodename}"
	echo "OWNER: ${owner}"

	exit 0
}

## MAIN
[ -n "${logfile}" ] && shift
[ -n "${notify}" ] && shift
[ -n "${autoflush}" ] && shift
[ -n "${node}" ] && shift
[ -n "${owner}" ] && shift
[ -n "${after}" ] && shift
[ -n "${client_id}" ] && shift
[ -n "${cast_args}" ] && shift

# cast param=" ss val" into param=' ss val' by default
[ -z "${cast_args}" ] && cast_args=1

[ -n "${jconf}" -a -r "${jconf}" ] && . ${jconf}

shift ## mode=xxx

if [ ${cast_args} -eq 1 ]; then
	# Pass '"' as ' in cmd
	INIT_IFS="${IFS}"
	IFS="~"
	cmd="$@"
	IFS="${INIT_IFS}"
	cmd=$( while [ -n "${1}" ]; do
		IFS="~"
		strpos --str="${1}" --search="="
		_pos=$?
		if [ ${_pos} -eq 0 ]; then
			# not params=value form
			#printf "${1} "		# (printf handles -args (with dashes)
			echo -n "${1} "
			shift
			continue
		fi

		_arg_len=$( strlen ${1} )
		_pref=$(( _arg_len - _pos ))
		ARG=$( substr --pos=0 --len=${_pos} --str="${1}" )
		VAL=$( substr --pos=$(( ${_pos} +2 )) --len=${_pref} --str="${1}" )

		printf "${ARG}='${VAL}' "
		shift
	done )
else
	cmd="$@"
fi

## place for default of all variables for remote node?
[ -z "${notify}" ] && notify=1
[ -z "${after}" ] && after=0
[ -z "${client_id}" ] && client_id=0
[ -z "${owner}" ] && owner=$( ${WHOAMI_CMD} )
[ -n "${nodetask}" ] && try_remote "${cmd}"

case "${mode}" in
	"new")
		[ -z "$1" ] && err 1 "${N1_COLOR}Command required${N0_COLOR}"

		# test for exclusive
		if [ ${exclusive} -eq 1 ]; then
			_excl_test=$( cbsdsqlro cbsdtaskd "SELECT id FROM taskd WHERE cmd=\"${cmd}\" AND status != 2 AND owner=\"${owner}\" AND jname=\"${jname}\" ORDER BY id DESC LIMIT 1" )
			[ -n "${_excl_test}" ] && err 1 "${N1_COLOR}This job is exclusive, waiting to complete: ${N2_COLOR}${_excl_test}${N0_COLOR}"
		fi

		if [ -n "${logfile}" ]; then
			_err=$( cbsdsqlrw cbsdtaskd "INSERT INTO taskd ( cmd,status,logfile,logtype,notify,autoflush,owner,after,client_id,jname ) VALUES ( \"${cmd}\", 0, \"$logfile\", 0, \"$notify\", \"$autoflush\", \"$owner\", \"$after\", \"$client_id\", \"${jname}\" )" )
		else
			_err=$( cbsdsqlrw cbsdtaskd "INSERT INTO taskd ( cmd,status,notify,autoflush,owner,after,client_id,jname ) VALUES ( \"${cmd}\", 0, \"$notify\", \"$autoflush\", \"$owner\", \"$after\", \"$client_id\", \"${jname}\" )" )
		fi

		[ $? -ne 0 ] && err 1 "${N1_COLOR}task mode=new error: ${_err}${N0_COLOR}"
		tid=$( cbsdsqlro cbsdtaskd "SELECT id FROM taskd WHERE cmd=\"${cmd}\" AND status=0 ORDER BY id DESC LIMIT 1" )
		${TOUCH_CMD} ${workdir}/var/db/cbsdtaskd.sqlite
		[ -z "${tid}" ] && err 1 "${N1_COLOR}task mode=new tid error: ${_err}${N0_COLOR}"
		echo "${tid}"
		;;
	"cancel")
		;;
	"cancelall")
		cbsdsqlrw cbsdtaskd UPDATE taskd SET status='2'
		;;
	"flushall")
		for i in $( cbsdsqlro cbsdtaskd SELECT logfile FROM taskd WHERE status='2' ); do
			[ -f "${i}" ] && ${RM_CMD} -f "${i}"
		done
		cbsdsqlrw cbsdtaskd DELETE FROM taskd WHERE status='2'
		x=$( cbsdsqlro cbsdtaskd "SELECT COUNT(id) FROM taskd" )
		# reset SQLITE_SEQUENCE
		[ "${x}" = "0" ] && cbsdsqlrw cbsdtaskd "UPDATE sqlite_sequence SET seq=0 WHERE name=\"taskd\""
		;;
esac
