#!/bin/bash -e

set ${VOLATILE_DIR:=/volatile}
set ${VOLATILE_PEER:=eta}
set ${VOLATILE_RSYNC:=rsync --progress --exclude=turnkey-files/xmlsitemap --exclude=turnkey-files/backup_migrate --exclude=.*.swp --exclude=turnkey-files/js --exclude=turnkey-files/css --exclude=.git -avP --delete}

get_branch()
{
	basename $(git-symbolic-ref HEAD)
}

progname=$(basename $0)

if [ $progname != "volatile-init" ]; then
	_fatal=false
	cd $VOLATILE_DIR
	_branch=$(get_branch)
	cd - >& /dev/null
	trap 'exit_handler' EXIT INT TERM
fi

cleanup()
{
	git-reset --hard HEAD >& /dev/null
	if [ "$_branch" != $(get_branch) ]; then
		git-checkout $_branch >& /dev/null
	fi
}

exit_handler()
{
	exitcode=$?
	set +x
	if [ "$exitcode" != 0 ] && [ "$_fatal" != "true" ]; then
		echo "volatile: last command exited with nonzero exit code" >& 2
		cleanup
	fi
	
}

is_clean()
{
	git-status | grep -q "nothing to commit";
}

fatal()
{
	set +x
	_fatal=true
	echo "volatile: $*" >& 2
	exit 1
}

pull_local()
{
	echo "# pulling local"
	pull_remote
	git-checkout local
	if ! git-merge remote; then
		git-ls-files -u
		echo "# MANUALLY RESOLVE MERGE CONFLICT IN THE ABOVE FILES:"
		/bin/bash
		is_clean || git-commit
	fi
}

pull_remote()
{
	[ $(get_branch) = "remote" ] || git-checkout remote
	echo "# pulling remote"
	$VOLATILE_RSYNC $VOLATILE_PEER:$VOLATILE_DIR/ .
	autocommit "pull-remote autocommit"
}

autocommit()
{
	msg=$1
	pwd
	git-add .
	git-commit -a -v -m "$msg" || true
}

volatile_pull()
{
	cd $VOLATILE_DIR
	is_clean || fatal "$VOLATILE_DIR is dirty"

	branch=$(get_branch)
	set -x
	if [ $branch = "local" ]; then
		pull_local
	elif [ $branch = "remote" ]; then
		pull_remote
	else
		fatal "unknown branch ($(get_branch)) - expecting remote or local"
	fi
}

volatile_sync()
{
	cd $VOLATILE_DIR
	if [ $(get_branch) != "local" ]; then
		fatal "can't sync from non-local branch"
	fi
	set -x

	volatile_pull
	$VOLATILE_RSYNC ./ $VOLATILE_PEER:$VOLATILE_DIR

	git-checkout remote
	git-merge local
	git-checkout local
}

volatile_init()
{
	[ -e $VOLATILE_DIR ] && fatal "can't init - $VOLATILE_DIR already exists"
	set -x
	mkdir -p $VOLATILE_DIR
	cd $VOLATILE_DIR
	$VOLATILE_RSYNC $VOLATILE_PEER:$VOLATILE_DIR/ .
	git-init
	git-add .
	git-commit -a -v -m "Initial commit"
	git-checkout -b remote master
	git-checkout -b local remote
	git-branch -D master
}

volatile_help()
{
	echo "Usage: $0 volatile-<command>"
	echo "Commands:"
	echo "    pull     pull changes from peer into volatile directory"
	echo
        echo "             If local branch is checked out, we try to merge local with remote"
        echo "             If remote branch is checked out, we only update the remote branch"
	echo
	echo "    sync     pull changes into local branch, and push changes to peer after merge"
	echo "    init     initialize local volatile repository from peer"
	echo
	echo "Environment variables":
	echo "    VOLATILE_PEER     address of remote peer (default: $VOLATILE_PEER)"
	echo "    VOLATILE_DIR      path to volatile directory (default: $VOLATILE_DIR)"
	echo
	echo "    VOLATILE_RSYNC    rsync command (default: $VOLATILE_RSYNC)"

	_fatal=true
	exit 1
}

if [ $progname = "volatile-pull" ]; then
	volatile_pull
elif [ $progname = "volatile-sync" ]; then
	volatile_sync
elif [ $progname = "volatile-init" ]; then
	volatile_init
elif [ $progname = "volatile" ]; then
	volatile_help
fi
