#!/bin/sh

set -e

d00=`pwd`
while ! [ -f ./all ]; do
	if [ x"`pwd`" = x"/" ]; then
		echo "Cannot find myself."
		echo "Please run this script with the working directory inside a Xonotic checkout."
		exit 1
	fi
	cd ..
done
d0=`pwd`
SELF="$d0/all"

# If we are on WINDOWS:
case "$0" in
	all|*/all)
		case "`uname`" in
			MINGW*|Win*)
				# Windows hates users. So this script has to copy itself elsewhere first...
				tname=
				cp "$SELF" ../all.xonotic.sh
				exec ../all.xonotic.sh "$@"
				;;
		esac
		;;
esac

msg()
{
	echo "$*"
}

checksum()
{
	if [ -x /usr/bin/md5sum ]; then
		/usr/bin/md5sum "$@"
	elif [ -x /bin/md5sum ]; then
		/bin/md5sum "$@"
	elif [ -x /usr/bin/cksum ]; then
		/usr/bin/cksum "$@"
	else
		echo "NOCHECKSUM"
	fi
}

self=`checksum "$SELF"`
checkself()
{
	self_new=`checksum "$SELF"`
	if [ x"$self" != x"$self_new" ]; then
		msg "./all has changed."
		if [ -z "$XONOTIC_FORBID_RERUN_ALL" ]; then
			msg "Rerunning the requested operation to make sure."
			export XONOTIC_FORBID_RERUN_ALL=1
			exec "$SELF" "$@"
		else
			msg "Please try $SELF update, and then retry your requested operation."
			exit 1
		fi
	fi
	return 0
}

verbose()
{
	msg "+ $*"
	"$@"
}

visible_repo_name()
{
	case "$1" in
		.)
			echo "the root directory"
			;;
		*)
			echo "\"$1\""
			;;
	esac
}

check_mergeconflict()
{
	if git ls-files -u | grep ' 1	'; then
		echo
		echo "MERGE CONFLICT."
		echo "change into the \"$1\" project directory, and then:"
		echo "- edit the files mentioned above with your favorite editor,"
		echo "  and fix the conflicts (marked with <<<<<<< blocks)"
		echo "- for binary files, you can select the files using"
		echo "  git checkout --ours or git checkout --theirs"
		echo "- when done with a file, 'git add' the file"
		echo "- when done, 'git commit'"
		echo
		exit 1
	fi
}

enter()
{
	verbose cd "$1"
	check_mergeconflict "$1"
}

repos_urls="
	.
	data/xonotic-data.pk3dir
	data/xonotic-maps.pk3dir
	data/xonotic-music.pk3dir
	data/xonotic-nexcompat.pk3dir
	darkplaces
	fteqcc@git://github.com/Blub/qclib.git
	div0-gittools@git://git.icculus.org/divverent/div0-gittools.git
	netradiant
"

repos=`for X in $repos_urls; do echo "${X%%@*}"; done`

if [ "$#" = 0 ]; then
	set -- help
fi
cmd=$1
shift

case "$cmd" in
	update|pull)
		base=`git config remote.origin.url`
		base=${base%xonotic.git}
		for dcomplete in $repos_urls; do
			case "$dcomplete" in
				*@*)
					d=${dcomplete%%@*}
					url=${dcomplete#*@}
					switch=false
					;;
				*)
					d=${dcomplete%%@*}
					url=$base${d##*/}.git
					switch=true
					;;
			esac
			if [ -d "$d0/$d" ]; then
				enter "$d0/$d"
				case "$d" in
					.)
						;;
					*)
						if $switch; then
							verbose git config remote.origin.url "$url"
						fi
						;;
				esac
				verbose git config remote.origin.fetch "refs/heads/*:refs/remotes/origin/*"

				r=`git symbolic-ref HEAD`
				r=${r#refs/heads/}
				if git config branch.$r.remote >/dev/null 2>&1; then
					if ! verbose git pull; then
						check_mergeconflict "$d"
						exit 1 # FATAL
					fi
				fi

				cd "$d00"
				checkself "$cmd" "$@"
				cd "$d0/$d"
				verbose git remote prune origin
				cd "$d0"
			else
				verbose git clone "$url" "$d0/$d"
			fi
		done
		;;
	checkout|switch)
		remote=$1
		branch=$2
		if [ -z "$branch" ]; then
			branch=$remote
			remote=origin
		fi
		exists=false
		for d in $repos; do
			enter "$d0/$d"
			if git rev-parse "refs/heads/$branch" >/dev/null 2>&1; then
				exists=true
				verbose git checkout "$branch"
			elif git rev-parse "refs/remotes/$remote/$branch" >/dev/null 2>&1; then
				exists=true
				verbose git checkout --track -b "$branch" "$remote/$branch"
			else
				verbose git checkout master
			fi
			cd "$d00"
			checkself "$cmd" "$@"
			cd "$d0"
		done
		if ! $exists; then
			echo "The requested branch was not found in any repository."
		fi
		exec "$SELF" branch
		;;
	branch)
		remote=$1
		branch=$2
		srcbranch=$3
		if [ -z "$branch" ]; then
			branch=$remote
			remote=origin
		fi
		if [ -z "$srcbranch" ]; then
			srcbranch=master
		fi
		if [ -z "$branch" ]; then
			for d in $repos; do
				enter "$d0/$d"
				r=`git symbolic-ref HEAD`
				r=${r#refs/heads/}
				echo "$d is at $r"
				cd "$d0"
			done
		else
			for d in $repos; do
				dv=`visible_repo_name "$d"`
				enter "$d0/$d"
				a=
				while [ x"$a" != x"y" -a x"$a" != x"n" ]; do
					echo "Branch in $dv?"
					read -r a
				done
				if [ x"$a" = x"y" ]; then
					verbose git push "$remote" "$srcbranch":"$branch"
					verbose git checkout --track -b "$branch" "$remote/$branch"
				fi
				cd "$d0"
			done
			"$SELF" branch
		fi
		;;
	branches)
		for d in $repos; do
			enter "$d0/$d"
			echo "In $d:"
			git branch -a | sed 's/^/  /; /->/d'
			cd "$d0"
		done
		;;
	merge)
		for d in $repos; do
			dv=`visible_repo_name "$d"`
			enter "$d0/$d"
			r=`git symbolic-ref HEAD`
			r=${r#refs/heads/}
			if git log HEAD..origin/master | grep .; then
				# we have uncommitted changes
				a=
				while [ x"$a" != x"y" -a x"$a" != x"n" ]; do
					echo "Could merge from \"master\" into \"$r\" in $dv. Do it?"
					read -r a
				done
				if [ x"$a" = x"y" ]; then
					if ! verbose git merge origin/master; then
						check_mergeconflict "$d"
						exit 1 # this should ALWAYS be fatal
					fi
				fi
			fi
			cd "$d0"
		done
		;;
	push)
		for d in $repos; do
			dv=`visible_repo_name "$d"`
			enter "$d0/$d"
			r=`git symbolic-ref HEAD`
			r=${r#refs/heads/}
			if git diff HEAD | grep .; then
				# we have uncommitted changes
				a=
				while [ x"$a" != x"y" -a x"$a" != x"n" ]; do
					echo "Uncommitted changes in \"$r\" in $dv. Commit?"
					read -r a
				done
				if [ x"$a" = x"y" ]; then
					verbose git commit -a
				fi
			fi
			if git log "origin/$r".."$r" | grep .; then
				a=
				while [ x"$a" != x"y" -a x"$a" != x"n" ]; do
					echo "Push \"$r\" in $dv?"
					read -r a
				done
				if [ x"$a" = x"y" ]; then
					verbose git push `git config "branch.$r.remote" || echo origin` HEAD
				fi
			fi
			cd "$d0"
		done
		;;
	compile)
		if [ -z "$MAKEFLAGS" ]; then
			if [ -f /proc/cpuinfo ]; then
				ncpus=$((`grep -c '^processor	:' /proc/cpuinfo`+0))
				if [ $ncpus -gt 1 ]; then
					MAKEFLAGS=-j$ncpus
				fi
			fi
		fi
		enter "$d0/fteqcc"
		verbose make $MAKEFLAGS
		enter "$d0/data/xonotic-data.pk3dir"
		verbose make FTEQCC="$d0/fteqcc/fteqcc.bin" $MAKEFLAGS
		enter "$d0/darkplaces"
		verbose make $MAKEFLAGS sv-debug
		verbose make $MAKEFLAGS cl-debug
		verbose make $MAKEFLAGS sdl-debug
		;;
	run)
		client=-sdl
		case "$1" in
			sdl|glx|agl|dedicated)
				client=-$1
				shift
				;;
			wgl)
				client=
				shift
				;;
		esac
		if ! [ -x "darkplaces/darkplaces$client" ]; then
			if [ -x "darkplaces/darkplaces$client.exe" ]; then
				client=$client.exe
			else
				echo "Client darkplaces/darkplaces$client not found, aborting"
				exit 1
			fi
		fi
		#verbose "darkplaces/darkplaces$client" -xonotic "$@"
		verbose "darkplaces/darkplaces$client" -nexuiz -customgamename Xonotic -customgamedirname1 data -customgamedirname2 "" -customgamescreenshotname xonotic -customgameuserdirname xonotic "$@"
		;;
	each|foreach)
		for d in $repos; do
			enter "$d0/$d"
			verbose "$@"
			cd "$d0"
		done
		;;
	*)
		echo "Usage:"
		echo "  $SELF pull"
		echo "  $SELF merge"
		echo "  $SELF push"
		echo "  $SELF branches"
		echo "  $SELF branch [<remote>] <branchname>"
		echo "  $SELF branch <remote> <branchname> <srcbranchname>"
		echo "  $SELF checkout [<remote>] <branchname>"
		echo "  $SELF compile"
		echo "  $SELF run <client> <options>"
		echo "  $SELF each <command>"
		;;
esac