#!/bin/bash

pushd $(dirname "$0") > /dev/null
D=$(pwd -P)
popd > /dev/null

BASED="$D/.build"
HOMED="$D/.home"

SOURCED="$HOMED/source"
INSTALLD="$HOMED/.local"

GTK_OSX_BASE_URL="https://git.gnome.org/browse/gtk-osx/plain/"
JHBUILD_SOURCED="$SOURCED/jhbuild"

ME="$0"

if [ -z "$GEDIT_SDK" ]; then
	export GEDIT_SDK=10.7
fi

export PATH="$INSTALLD/bin:$PATH"

function do_exit() {
	printf "$@"
	echo ""
	exit 1
}

if [ ! which git &>/dev/null ]; then
	do_exit "You need to have git installed to build gedit for OS X"
fi

if [ ! xcodebuild -version &>/dev/null ]; then
	do_exit "You need to have Xcode installed to build gedit for OS X"
fi

xcodebase=$(xcode-select -p)
sdkdir="$xcodebase/Platforms/MacOSX.platform/Developer/SDKs/MacOSX$GEDIT_SDK.sdk"

if [ ! -d "$sdkdir" ]; then
	do_exit "SDK base directory for $GEDIT_SDK not found. Please make sure to install the SDK at $sdkdir"
fi

function checkout_jhbuild() {
	#JHBUILD_REVISION=$(curl -ks "$GTK_OSX_BASE_URL/jhbuild-revision")

	#if test x"$JHBUILD_REVISION" = x; then
	#	do_exit "Could not find jhbuild revision to use."
	#fi

	mkdir -p $(dirname "$JHBUILD_SOURCED")

	git clone git://git.gnome.org/jhbuild "$JHBUILD_SOURCED" || do_exit "Failed to clone jhbuild."
	#git --work-tree "$JHBUILD_SOURCED" checkout -b stable $JHBUILD_REVISION || do_exit "Failed to checkout stable jhbuild revision."
}

function build_jhbuild() {
	echo "Building jhbuild..."
	(cd "$JHBUILD_SOURCED" && ./autogen.sh --prefix="$INSTALLD" && make -f Makefile.plain DISABLE_GETTEXT=1 install) >/dev/null || do_exit "Jhbuild installation failed";

	rm -f "$INSTALLD/bin/python2"

	cat << PYTHON2 > "$INSTALLD/bin/python2"
#!/bin/bash

exec /usr/bin/python "\$@"
PYTHON2
	chmod +x "$INSTALLD/bin/python2"
}

function setup_jhbuildrc() {
	echo "Installing jhbuild configuration..."

	mkdir -p "$HOMED"
    curl -ks "$GTK_OSX_BASE_URL/jhbuildrc-gtk-osx" | \
    	sed -e 's/^.*PYTHONPATH.*$//g' -e 's/^.*PYTHON_SITE_PACKAGES.*$//g' > "$HOMED/.jhbuildrc" || do_exit "Failed to get jhbuildrc."

    rm -f "$HOMED/.jhbuildrc-gedit"
    ln -s "$D/config/jhbuildrc-gedit" "$HOMED/.jhbuildrc-gedit" || exit 1
}

function init_help_short() {
	echo "Initialize the in-tree build environment (installs jhbuild)"
}

function cmd_init() {
	mkdir -p "$SOURCED"

	if [ ! -d "$JHBUILD_SOURCED" ]; then
		checkout_jhbuild
	fi

	build_jhbuild
	setup_jhbuildrc

	rm -f "$BASED/$GEDIT_SDK/source/gedit"
	mkdir -p "$BASED/$GEDIT_SDK/source"
	ln -s $(cd "$D/../../" && pwd) "$BASED/$GEDIT_SDK/source/gedit"
}

function bootstrap_help_short() {
	echo "Run jhbuild bootstrap"
}

function cmd_bootstrap() {
	# Built python once
	cmd_jh bootstrap -q python || exit 1

	# Built python twice! There is a bug where python somehow manages to link
	# its main binary to the system framework library, which then doesn't work...
	# Building python again seems to resolve the issue...
	cmd_jh bootstrap -q -f -t python python || exit 1

	# Bootstrap all the rest
	cmd_jh bootstrap -q || exit 1
}

function jh_help_usage() {
	echo "jhbuild-command ..."
}

function jh_help_short() {
	echo "Run jhbuild commands"
}

function cmd_jh() {
	# Setup our jhbuild environment
	export GEDIT_OSX_SOURCE_BASE="$D"
	export GEDIT_OSX_BUILD_BASE="$BASED"
	export __GEDIT_OSX_OLD_HOME="$HOME"
	export HOME="$HOMED"
	export JHB=gedit

	# We set this because without it, GNU gettext intltool or whatever the cause
	# may be, will set DATADIRNAME=lib during configure because gettext is not part
	# of libc on OS X. The result is that translations would be installed in lib/
	# instead of share/ and would not get picked up.
	export DATADIRNAME=share

	"$INSTALLD/bin/jhbuild" -f "$HOMED/.jhbuildrc" "$@"
}

function dbg_help_usage() {
	echo "build command ..."
}

function dbg_help_short() {
	echo "Run remaining build commands in a debug environment"
}

function cmd_dbg() {
	export GEDIT_OSX_DEBUG=1
	_process "$@"
}

function shell_help_short() {
	echo "Start the jhbuild shell (shorthand for jh shell)"
}

function cmd_shell() {
	cmd_jh shell
}

function make_help_usage() {
	echo "module-source-directory"
}

function make_help_short() {
	echo "Run jhbuild make at the provided source directory"
}

function cmd_make() {
	cd "$BASED/$GEDIT_SDK/source/$1" && cmd_jh make
}

function run_help_usage() {
	echo "program ..."
}

function run_help_short() {
	echo "Run the provided program in the jhbuild environment (shorthand for jh run)"
}

function cmd_run() {
	cmd_jh run "$@"
}

function env_help_short() {
	echo "Obtain certain environment paths"
}

function cmd_env() {
	vars=(source inst bin home local-bin)

	case "$1" in
	source)
		echo "$BASED/$GEDIT_SDK/source"
		;;
	inst)
		echo "$BASED/$GEDIT_SDK/inst"
		;;
	bin)
		echo "$BASED/$GEDIT_SDK/inst/bin"
		;;
	home)
		echo "$HOMED"
		;;
	local-bin)
		echo "$HOMED/.local/bin"
		;;
	"")
		for v in "${vars[@]}"; do
			u=$(echo -n "$v" | tr '-' '_')
			echo -n "$u="
			cmd_env "$v"
		done
		;;
	*)
		varnames=$(printf ", \033[1m%s\033[0m" "${vars[@]}")
		varnames=${varnames:2}

		do_exit "Unknown environment variable \033[1m$1\033[0m, available variables are: $varnames"
		;;
	esac
}

function all_help_short() {
	echo "Runs the init, bootstrap and build commands"
}

function cmd_all() {
	if [ ! -d "$JHBUILD_SOURCED" ]; then
		cmd_init || exit 1
	fi

	if [ ! -f "$BASED/$GEDIT_SDK/inst/bin/python" ]; then
		cmd_bootstrap || exit 1
	fi

	cmd_jh build -q
}

function help_help_short() {
	echo "Shows this help message"
}

function cmd_help() {
	if [ -z "$1" ]; then
		echo "Usage: $ME [command]"
		echo ""
		echo "Available commands:"
		echo ""

		for cmd in "${commands[@]}"; do
			printf "  \033[1m$cmd\x1B[0m "

			l=${#cmd}
			let d="$commandsmaxlen - $l + 1"

			printf "%${d}s" ""
			echo -n "- "

			if [[ $(type -t "${cmd}_help_short") = "function" ]]; then
				"${cmd}_help_short"
			else
				echo ""
			fi
		done

		echo ""
	else
		cmd="cmd_$1"

		if [[ $(type -t "$cmd") != "function" ]]; then
			do_exit "Invalid command \033[1m$1\033[0m, available commands are: $cmds"
		fi

		printf "Usage: $ME \033[1m$1\033[0m "

		if [[ $(type -t "$1_help_usage") = "function" ]]; then
			"$1_help_usage"
		else
			echo ""
		fi

		echo ""

		if [[ $(type -t "$1_help_long") != "function" ]]; then
			"$1_help_short"
		else
			"$1_help_long"
		fi
	fi
}

commands=()
commandsmaxlen=0

while read line
do
	cmd=${line#declare -f }

	if [[ "$cmd" = cmd_* ]]; then
		cname=${cmd#cmd_}

		commands+=($cname)

		l=${#cname}

		if [[ $l > $commandsmaxlen ]]; then
			commandsmaxlen=$l
		fi
	fi
done < <(declare -F)

cmds=$(printf ", \033[1m%s\033[0m" "${commands[@]}")
cmds=${cmds:2}

function _process() {
	if [ -z "$1" ]; then
		cmd_help
		exit 0
	fi

	cmd="cmd_$1"

	if [[ $(type -t "$cmd") != "function" ]]; then
		do_exit "Invalid command $1, available commands are: $cmds"
	fi

	shift 1
	"$cmd" "$@"
}

_process "$@"
