#!/bin/sh
# 2017, 2018, 2019, 2020, 2021 (c) Etersoft https://etersoft.ru
# Author: Vitaly Lipatov <lav@etersoft.ru>
# Public domain

# load common functions, compatible with local and installed script
. `dirname $0`/../share/eterbuild/functions/common
load_mod git

set_girar_host $1 && shift

if [ "$1" = "-h" ] || [ "$1" = "--help" ]; then
	echo "gitask — ssh gear.alt task wrapper"
	echo "Use: gitask [GIRAR] [new|run|commit|add|deps|copy|find|log|show|ls]"
	echo "$HELP_GIRAR"
	echo "     --help - help"
	docmd ssh $GEARHOST task help | sed -e "s|abort|cancel|g"
	echo
	echo "Examples:"
	echo "     ls [-a|--all] [-w [N]]          - list tasks (--all for all users) (-w [N] for update every N seconds)"
	echo "     new    [branch]             - create new task on branch (Sisyphus by default)"
	echo "     run [--test-only] [NNNN] [NNNN2] [-m <message>] - run task NNNN"
	echo "     commit [NNNN] [NNNN2] [-m <message>]       - commit task(s) NNNN, [NNNN2]"
	echo "     add [NNNN] repo  <gear repo> <gear tag> ... - add package build from repo command"
	echo "     add [NNNN] repo <gear repo>.git=<gear tag> ...  - add package build from repo command"
	echo "     add [NNNN] del package [package2...]  - add package remove command"
	echo "     add [NNNN] rebuild package [package2...]  - add package rebuild"
	echo "     add --help                  - show task add help"
	echo "     Add <args>                  - add and run the task"
	echo "     task --help                 - show task help"
	echo "     share  NNNN [enable]        - share task NNNN"
	echo "     deps   NNNN add XXXX        - add deps from XXXX to task NNNN"
	echo "     copy   NNNN to (p8|p9) [from XX]  - copy package from Sisyphus to (p8|p9) [from XX]"
	echo "     delsub NNNN (package|subtask)  - remove subtask by number or by package name"
	echo "     find   PACKAGE              - do find-package of PACKAGE"
	echo "     log    NNNN                 - show build log for task NNNN"
	echo "     show   NNNN                 - show subtask list for task NNNN"
	echo "     quota                       - show quota on the remote servers"
	echo "     cancel NNNN                 - cancel task NNNN"
	echo "     acl [branch] show package   - show acl for the package"
	echo "     acl [branch] package add|del <maintainer> - add/del acl for the package"
	echo "     rebuild --help              - rebuild package"
	exit 0
fi

# with support for #NUM
is_task_number()
{
	echo "$*" | estrlist filter_strip_spaces | grep -q "^#\?[0-9]\+$"
}

# clean from possible #
get_task_number()
{
	echo "$*" | estrlist filter_strip_spaces | sed -e "s|^#||"
}

get_last()
{
	ssh $GEARHOST task ls | head -n1 | sed -e "s|^#\([0-9]*\) .*|\1|g"
}

get_test_status()
{
	ssh $GEARHOST task ls | grep "^#$1 " | grep "\[test-only\]"
}

# get subtask number from TASKNUMBER for PROJECTNAME
get_subtask()
{
	ssh $GEARHOST task show $1 | egrep "(/$2.git|:package=$2$)" | sed -e "s|^ \([0-9]*\):.*|\1|g"
}


NEXTCOMMAND=''

$EPMCMD assure girar-show girar-utils

if [ "$1" = "get" ] ; then
	if [ "$1 $2" = "get subtask" ] ; then
		[ -n "$3" ] || fatal "get subtask TASK PROJECTNAME"
		[ -n "$4" ] || fatal "get subtask $3 PROJECTNAME"
		get_subtask "$(get_task_number $3)" "$4"
		exit
	elif [ "$1 $2 $3" = "get last " ] || [ "$1 $2 $3" = "get last task" ] ; then
		get_last
		exit
	else
		fatal "Unknown command $1 $2"
	fi
fi

eval lastarg=\${$#}

if [ "$1" = "find" ] ; then
	shift
	#showcmd "$GEARHOST>" find-packages "$@"
	docmd ssh $GITHOST find-package "$@"
	exit
fi

set_if_matched()
{
    local i
    local m="$1"
    shift
    for i in $* ; do
        echo "$m" | grep "^$i$" && return
    done
    echo "Sisyphus"
    return 1
}

# acl [p9] show mc | add mc lav
if [ "$1" = "acl" ] ; then
	if [ "$lastarg" = "--help" ] ; then
		docmd ssh $GEARHOST "$@"
		exit
	fi
	shift
	BINARYREPO=$(set_if_matched $1 "Sisyphus [ptc][6-9] [ptc][6-9]\.[0-9]") && shift
	COMMAND="$1"
	PROJECTNAME="$2"
	[ -z "$PROJECTNAME" ] && PROJECTNAME="$COMMAND" && COMMAND="show"
	OPERAND="$3"
	showcmd ssh $GEARHOST acl $BINARYREPO $PROJECTNAME $COMMAND $OPERAND
	echo "$GEARHOST:$BINARYREPO ACL for $PROJECTNAME:"
	if [ "$COMMAND" = "show" ] ; then
		ssh $GEARHOST acl $BINARYREPO $PROJECTNAME $COMMAND | sed -e "s|^$PROJECTNAME||"
	else
		ssh $GEARHOST acl $BINARYREPO $PROJECTNAME $COMMAND $OPERAND
	fi
	exit
fi

if [ "$1" = "rebuild" ] ; then
	shift
	showcmd "$GEARHOST>" build rebuild "$@"
	docmd ssh $GEARHOST build rebuild "$@"
	exit
fi

if [ "$1" = "log" ] ; then
	shift
	TASK="$(get_task_number $1)"
	[ -n "$TASK" ] || TASK="$(get_last)" || fatal
	showcmd "$GEARHOST>" girar-show "$TASK"
	GIT_ALT=$GEARHOST girar-show "$TASK"
	exit
fi

if [ "$1" = "quota" ] ; then
	docmd ssh $GIRARHOST quota "$@"
	docmd ssh $GEARHOST quota "$@"
	exit
fi

if [ "$1 $2" = "cancel --help" ] ; then
	echo "cancel a task"
	echo "Usage: $ gita cancel <task id>"
	exit
fi

if [ "$lastarg" = "--help" ] ; then
	docmd ssh $GEARHOST task "$@"
	exit
fi

# task command below

if [ "$1" = "ls" ] ; then
	shift
	if [ "$1" = "--all" ] || [ "$1" = "-a" ] ; then
		docmd ssh $GEARHOST task ls --user=ALL --state=ALL
		exit
	fi
	if [ "$1" = "-w" ] ; then
		WN="$2"
		[ -n "$WN" ] && WN=10
		watch -c -n $WN $0 ls
		exit
	fi
	# TODO: with arg(s) — subtask
	# TODO: add support ls -a (with subtasks)
	if [ -n "$1" ] || ! isatty ; then
		showcmd "$GEARHOST>" girar-show "$@"
		GIT_ALT=$GEARHOST girar-show "$@"
	else
		showcmd "$GEARHOST>" 'girar-show | head -n20'
		GIT_ALT=$GEARHOST girar-show | head -n20
		echo "(end of head -n20 output)"
	fi
	exit
fi

if [ "$1" = "delsub" ] ; then
	shift 
	TASK="$(get_task_number $1)"
	[ -n "$TASK" ] || TASK="$(get_last)" || fatal
	shift
	while [ -n "$1" ] ; do
		SUBTASK="$1"
		shift
		if isnumber $SUBTASK ; then
			NUMTASK="$SUBTASK"
		else
			NUMTASK="$(get_subtask $TASK $SUBTASK)"
			info "$SUBTASK -> $NUMTASK"
		fi
		[ -z "$NUMTASK" ] && warning "can't find subtask for $SUBTASK, skipped" && continue
		docmd ssh $GEARHOST task delsub "$TASK" "$NUMTASK"
	done
	exit
fi

if [ "$1" = "copy" ] ; then
	shift
	PACKAGELIST=''
	while [ -n "$1" ] ; do
		[ "$1" = "to" ] && break
		PACKAGELIST="$PACKAGELIST $1"
		shift
	done

	[ "$1" = "to" ] || fatal "missed 'to' in your command"
	shift # to
	TARGET="$1"
	shift

	FROMSTR=''
	[ "$1" = "from" ] && FROMSTR="$2"

	[ -n "$PACKAGELIST" ] || fatal "no packages"
	showcmd ssh $GEARHOST task new $TARGET
	TASK="$(ssh $GEARHOST task new $TARGET | head -n1)" || fatal
	for PACKAGE in $PACKAGELIST ; do
		docmd ssh $GEARHOST task add $TASK copy $PACKAGE $FROMSTR
	done
	docmd ssh $GEARHOST task run $TASK
	exit
fi

if [ "$1" = "add" ] || [ "$1" = "Add" ] ; then
	[ "$1" = "Add" ] && NEXTCOMMAND="run"
	SUBTASK=''
	ADDCMD=''
	ADDCMDLIST="del copy repo rebuild"
	# add TASKNUMBER package
	if is_task_number "$2" && estrlist has "$3" $ADDCMDLIST ; then
		TASK="$(get_task_number $2)"
		ADDCMD="$3"
		shift 3
	elif is_task_number "$2" && isnumber "$3" && estrlist has "$4" $ADDCMDLIST ; then
		TASK="$(get_task_number $2)"
		SUBTASK="$3"
		ADDCMD="$4"
		shift 4
	elif estrlist has "$2" $ADDCMDLIST ; then
		TASK="$(get_last)"
		ADDCMD="$2"
		shift 2
	else
		fatal "don't support $1 $2 command"
	fi

	[ -n "$1" ] || fatal "no packages"

	OADDCMD=$ADDCMD
	while [ -n "$1" ] ; do
		PACKAGE="$1"
		if [ "$OADDCMD" = "repo" ] ; then
			#<gear repo>.git=<gear tag>
			if rhas "$1" "\.git=" ; then
				ADDCMD=''
			else
				PACKAGE="$1 $2" && shift
			fi
		fi
		shift
		ST="$(get_subtask $TASK $PACKAGE)"
		if [ -n "$ST" ] ; then
			info "$PACKAGE already present in the task $TASK as subtask $ST, replacing ..."
			docmd ssh $GEARHOST task delsub $TASK $ST
			[ -n "$SUBTASK" ] || SUBTASK="$ST"
			# too much re add to the same place
			[ "$SUBTASK" = "1" ] && SUBTASK=""
		fi
		docmd ssh $GEARHOST task add $TASK $SUBTASK $ADDCMD $PACKAGE
	done
	[ -n "$NEXTCOMMAND" ] && sleep 2 && $0 $NEXTCOMMAND
	exit
fi

if [ "$1" = "show" ] ; then
	shift
	COMMIT=''
	TASK="$(get_task_number $1)"
	if [ -z "$TASK" ] ; then
		TASK="$(get_last)" || fatal "Can't get last task"
	fi
	docmd ssh $GEARHOST task show "$TASK"
	exit
fi

if [ "$1" = "run" ] || [ "$1" = "commit" ] ; then
	COMMIT=''
        [ "$1" = "commit" ] && COMMIT="--commit"
	shift
	TESTONLY=''
	[ "$1" = "--test-only" ] && TESTONLY="$1" && shift

	TASKLIST=''
	MESSAGE=''
	MESSAGETEXT=''

	while [ -n "$1" ] ; do
		# TODO: check for number?
		if echo "$1" | grep -qv "^-" ; then
			TASK="$(get_task_number $1)"
			TASKLIST="$TASKLIST $TASK"
		elif [ "$1" = "-m" ] ; then
			#MESSAGE="$1 ${2// /_}"
			MESSAGE="-m -"
			MESSAGETEXT="$2"
			shift
		else
			fatal "Unknown param $1"
		fi
		shift
	done

	[ -n "$TASKLIST" ] || TASKLIST="$(get_last)" || fatal "Can't get last task"

	for TASK in $TASKLIST ; do
		echo "$MESSAGETEXT" | docmd ssh $GEARHOST task run $TESTONLY $MESSAGE $COMMIT "$TASK"
	done
	exit
fi

if [ "$1" = "cancel" ] ; then
	shift
	TASK="$(get_task_number $1)"
	if [ "$GEARHOST" = "git.eter" ]  || [ "$GEARHOST" = "git.office" ] ; then
		docmd ssh $GEARHOST task cancel "$TASK"
	else
		docmd ssh $GEARHOST task abort "$TASK"
	fi
	exit
fi

if [ "$1" = "share" ] && [ -n "$2" ] ; then
	shift
	TASK="$(get_task_number $1)"
	docmd ssh $GEARHOST task share "$TASK" enable
	exit
fi


if [ "$1" = "task" ] ; then
	# by default
	shift
fi

docmd ssh $GEARHOST task "$@"

