#!/bin/sh

set -e

PRG=`basename $0`

TEMP=`getopt -s sh -o ah:fk -l all,host:,force,kill -n "$PRG" -- "$@"`
if [ $? != 0 ] ; then echo "Terminating..." >&2 ; exit 1 ; fi
eval set -- "$TEMP"

all="no"
host="localhost"
force="no"
kill="no"
while true ; do
	case "$1" in
		-a|--all) all="yes" ; shift ;;
		-h|--host) host="$2" ; shift 2 ;;
		-f|--force) force="yes" ; shift ;;
		-k|--kill) kill="yes" ; shift ;;
		--) shift ; break ;;
		*) echo "Internal error!" ; exit 1 ;;
	esac
done

USER="`whoami`"

if [ "$all" = yes ]; then
#	users=$(find /home -mindepth 2 -maxdepth 2 -type f -name .offlineimaprc -printf '%h\n' | sed 's,.*/,,')
	users=$(members mailmirrors)
else
	users="${@:-$USER}"
fi

#for user in $(find /home -mindepth 2 -maxdepth 2 -type f -name .offlineimaprc -printf '%h\n' | sed 's,.*/,,'); do
for user in $users; do
#	x-terminal-emulator -e sh -c "echo \"while true; do pkill -u $user offlineimap || offlineimap -u Curses.Blinkenlights; done\" | ssh $user@localhost sh -s" &
	if [ "$host" = localhost ] && [ "$user" = "$USER" ]; then
		ssh=""
	else
		ssh="ssh $user@$host"
	fi
	if [ "$kill" = yes ]; then
		$ssh killall -wq -u $user offlineimap
		exit $?
	fi
	if $ssh pgrep -u $user offlineimap; then
		if [ "$force" = yes ]; then
			$ssh killall -wq -u $user offlineimap || true
		else
			x-terminal-emulator -e sh -c "echo \"Error: offlineimap process(es) already running. Use --force to kill before use.\"; echo \"Press enter to quit this terminal\"; read" &
		fi
	fi
	if [ -n "$ssh" ]; then
		# SSH expands shell command twice: protect semicolons by double-quoting
		x-terminal-emulator -e $ssh -t sh -c "\"while true; do offlineimap -u Curses.Blinkenlights; done; read\"" &
	else
		x-terminal-emulator -e sh -c "while true; do offlineimap -u Curses.Blinkenlights; done; read" &
	fi
done

exit 0

unbreakshell() {
	echo "$@" | perl -pe 's/(\S*[\\\|";'\'']\S*)/'\''$1'\''/g'
#	echo "$@" | perl -pe 's/(\S+)/'\''$1'\''/g'
#	echo "$@" | perl -pe 's/'\''/'\'\\\''/g; s/(\S+)/'\''$1'\''/g'
}

execute() {
	TEMP=`getopt -s sh -o xtf --long fork,loop -n "$PRG" -- "$@"`
	eval set -- "$TEMP"

	fork=""
	loop=""
	x11=""
	term=""
	force=""
	while true ; do
		case "$1" in
			--fork) fork="1" ; shift ;;
			--loop) loop="1" ; shift ;;
			-x) x11="-x" ; shift ;;
			-t) term="-t" ; shift ;;
			-f) force="-f" ; shift ;;
			--) shift ; break ;;
			*) echo >&2 "Internal error in execute subroutine!" ; exit 1 ;;
		esac
	done

	user=$1; shift
	host=$1; shift
	shellbreaks=0

	if [ -n "$loop" ]; then
#		TEMP="sh -c \"while true; do $(unbreakshell "$@"); done\""
#		eval set -- "$TEMP"
		eval set -- "sh -c \"while true; do" "$@" "; done\""
	fi

#	if [ -n "$fork" ]; then
#		command="sh -c \"eval $@ \& \""
#		eval set -- `unbreakshell $command`
#	fi

	ssh=""
	if [ "$host" != localhost ] || [ "$user" != "$USER" ]; then
		ssh="1"
	fi

	sshopts="-e none"
	xterm=""
	if [ "$host" != localhost ]; then
		sshopts="$sshopts -C"
	fi
	if [ -n "$x11" ]; then
		if [ -n "$term" ]; then
			xterm="1"
			sshopts="$sshopts -T"
		else
			sshopts="$sshopts -X"
		fi
	fi

#	while [ "$shellbreaks" -gt 0 ]; do
#		eval set -- "`unbreakshell "$@"`"
#		shellbreaks=`expr $shellbreaks - 1`
#	done

	if [ -n "$ssh" ]; then
		TEMP="ssh $sshopts \"$user@$host\" -- $(unbreakshell "$@")"
		eval set -- "$TEMP"
	fi

	if [ -n "$x11" ] && [ -n "$term" ]; then
		TEMP="x-terminal-emulator -e sh -c \"$(unbreakshell "$@")\""
		eval set -- "$TEMP"
	fi

	if [ -n "$fork" ]; then
		$@ &
	else
		$@
	fi

}

findusers() {
	user=$1; shift
	host=$1; shift

	execute $force "$user" "$host" -- find /home -mindepth 2 -maxdepth 2 -type f -name .offlineimaprc -printf '%h\n' | sed 's,.*/,,'
}

dosync() {
	TEMP=`getopt -s sh -o xtf -n "$PRG" -- "$@"`
	eval set -- "$TEMP"

	x11=""
	term=""
	force=""
	while true ; do
		case "$1" in
			-x) x11="-x" ; shift ;;
			-t) term="-t" ; shift ;;
			-f) force="-f" ; shift ;;
			--) shift ; break ;;
			*) echo >&2 "Internal error in dosync subroutine!" ; exit 1 ;;
		esac
	done

	user=$1; shift
	host=$1; shift

	killfork=""
	if [ "$1" = KILL ]; then
		killfork="--fork"
	fi

	execute $x11 $term $force $killfork "$user" "$host" -- killall -u $user -wq -v -r "sh offlineimap" || [ $? -lt 2 ]

	if [ "$1" != KILL ]; then
		execute $x11 $term $force --loop --fork "$user" "$host" -- offlineimap "$@"
#		execute $x11 $term $force --loop "$user" "$host" -- offlineimap "$@"
	fi
#	execute "$user" "$host" pkill -u $user offlineimap || [ $? -lt 2 ]
#	execute "$user" "$host" pkill -u $user offlineimap || echo $?
#	execute "$user" "$host" sh -c \"pkill -u $user offlineimap \|\| echo \$?\"
#	execute "$user" "$host" sh -c \"pkill -u $user offlineimap\" || [ $? -lt 2 ]
#	while true; do execute "$user" "$host" offlineimap "$@"; done
#	while true; do execute "$user" "$host" sh -c \"pkill -u $user offlineimap \|\|offlineimap "$@"\"; done &
}

case "$user" in
    ALL)
	if [ -z "$x11" ]; then
		echo >&2 "Error: checking multiple accounts requires the --x11 option."
		exit 1
	fi
	realusers="`findusers "$USER" "$host"`"
	for realuser in $realusers; do
		dosync $x11 $term $force "$realuser" "$host" -- "$@"
	done
	;;
    *)
	dosync $x11 $term $force "$user" "$host" -- "$@"
	;;
esac

exit 0