#! /usr/bin/env bash

repository="$1"
workdir="$2"
fossilCIDir="$3"
if [ -z "${repository}" -o -z "${workdir}" ]; then
	echo "Usage: autobuild <repository> <workdir> [<fossil-ci-dir>]" >&2

	exit 1
fi

if [ -z "${fossilCIDir}" ]; then
	fossilCIDir='.fossil-ci'
fi

# 1. Register cleanup
tmpdir=''
function cleanup() {
	if [ -n "${tmpdir}" ]; then
		rm -rf "${tmpdir}"
	fi
}
trap cleanup EXIT

# 2. Setup a sane environment
## 2.a. Abort on errors
set -e

## 2.b. Universal timezone
export TZ=UTC

## 2.c. Basic locale
unset $(locale | cut -f 1 -d =)

## 2.d. Sane umask
umask 022

# 3. Update the Fossil repository
fossil pull -R "${repository}" || :

# 4. Get a list of branches
branches=( $(fossil branch -R "${repository}" list) )

# 5. Get Fossil CI configuration from the trunk branch
## 5.a. Set default config
excludedBranches=''
buildCommands=('./autogen.sh || :' ./configure make)
builderID=''
projectName="$(fossil info -R "${repository}" | awk '/^project-name:/{ sub(/^project-name: */, ""); gsub(/ /, ""); print; }')"

## 5.b. Read config
config="$(fossil cat -R "${repository}" -r trunk "${fossilCIDir}/config")" || :

## 5.c Load config
if [ -f  ~/.fossil-ci/config ]; then
	. ~/.fossil-ci/config
fi

eval "${config}"

if [ -f ~/.fossil-ci/"${projectName}"/config ]; then
	. ~/.fossil-ci/"${projectName}"/config
fi

# 6. For each branch, attempt to build
for branch in "${branches[@]}"; do
	## 6.a. Ignore excluded branches
	case "${branch}" in
		${excludedBranches})
			continue
			;;
	esac

	## 6.b. Find the branch working directory
	branchdir="$(echo "${branch}" | sed 's@[^A-Za-z0-9-]@_@g')"
	builddir="${workdir}/build-output/branch-${branchdir}"
	branchdir="${workdir}/working-copies/branch-${branchdir}"
	mkdir -p "${branchdir}"

	## 6.c. Determine current checkout ID
	checkout="$(fossil info -R "${repository}" "${branch}" | awk '/^uuid:/{ print $3 "T" $4 "-" $2 }')"
	builddir="${builddir}/checkout-${checkout}"

	## 6.d. Determine if build even needs to occur
	if [ -d "${builddir}" ]; then
		continue
	fi
	mkdir -p "${builddir}"

	## 6.e. Check-out or update the branch
	(
		cd "${branchdir}" || exit 1

		if [ ! -f '.fslckout' ]; then
			fossil open "${repository}" "${branch}" --nested
		else
			fossil update "${branch}"
		fi
	) > "${builddir}/update.log" 2>&1 || continue

	## 6.f. Build and log the results, if there are any
	build_pass='1'
	(
		cd "${branchdir}" || exit 1

		for cmd in "${buildCommands[@]}"; do
			eval "set -x; ${cmd}" || exit 1
		done
	) > "${builddir}/build.log" 2>&1 || build_pass='0'

	### 6.g. Test the branch
	tests_pass='-1'
	if [ "${build_pass}" = '1' ]; then
		tests_pass='1'
		(
			cd "${branchdir}" || exit 1

			for cmd in "${testCommands[@]}"; do
				eval "set -x; ${cmd}" || exit 1
			done
		) > "${builddir}/test.log" 2>&1 || tests_pass='0'
	fi

	### 6.h. Tag the branch
	### 6.i. Upload the logs somewhere if requested
	### 6.j. Upload build artifacts somewhere if requested
done

# 7. Clean up any branches that no longer exist
