#! /bin/sh

set -e

PATH=/bin:/usr/bin:/usr/sbin:/usr/local/package/bin:/usr/local/bin
umask 022

die() {
	echo "$@"
	exit 1
}

die_usage() {
	die "usage: $0 example-1.2.3-0 [--purge] [--bind directory]"
}

ere_quote() {
	sed 's/[]\.|$(){}?+*^]/\\&/g' <<< "$*"
}

log_cmd() {
	echo "$@"
	"$@"
}

eval set -- $(getopt --options "" --longoptions purge,bind: -- "$@")
while true; do
	case "$1" in
		--bind)  opt_bind=1;bind_dir=$2;shift 2;;
		--purge) opt_purge=1;shift;;
		--) shift;break;;
		*) die "internal error: unknown option $!"
	esac
done

test $# -eq 1 || die_usage

PKG="$1"
PKG="${PKG%.build.sh}"

grep -q -E "^$(ere_quote "$PKG")\b" /etc/mxpkg || die "$PKG not found in mxpkg"
test -e "$PKG.build.sh" || die "$PKG.build.sh: file does not exist"
test $UID -eq 0 || die "$0: please run with sudo"

if [ ! -d "/package/pkg/$PKG" ]; then
	log_cmd mkdir -p "/package/pkg/$PKG"
	log_cmd chown build:build "/pkg/$PKG"
fi

if [ "$(stat -c %U "/pkg/$PKG")" != "build" ] && [ -z "$opt_purge" ] ; then
	echo "/pkg/$PKG is no longer owned by build user"
	echo "rerun with --purge if you want to build from scratch"
	exit 1
fi

if [ -n "$opt_purge" ]; then
	# make double sure PKG is not empty even if bugs are introduced in code above
	test -z "$PKG" && die "internal error: PKG is empty"
	log_cmd find "/pkg/$PKG" -mindepth 1 -delete
	test "$(stat -c %U "/pkg/$PKG")" = "build" || log_cmd chown build:build "/pkg/$PKG"
	if [ -n "$opt_bind" -a -d "$bind_dir/pkg_bindmnt" ]; then
		log_cmd find "$bind_dir/pkg_bindmnt" -mindepth 1 -delete
	fi
fi

chmod a+rx "$PKG.build.sh"

if [ -n "$opt_bind" ]; then
	mkdir -p "$bind_dir/pkg_bindmnt"
	chown build:build "$bind_dir/pkg_bindmnt"
	# check that '/pkg/$PKG' differs from intended location (i.e. isn't mounted already)
	if [ $(stat --format=%D:%i "$bind_dir/pkg_bindmnt") != $(stat --format=%D:%i /pkg/$PKG) ]; then
		log_cmd mount --bind "$bind_dir/pkg_bindmnt" /pkg/$PKG
		# prevent automount from unmounting
		exec 3</pkg/$PKG/.
		test $(stat --format=%D:%i "$bind_dir/pkg_bindmnt") = $(stat --format=%D:%i /pkg/$PKG) || die "unable to mount and lock '$bind_dir/pkg_bindmnt' on /pkg/$PKG"
	else
		die "'$bind_dir/pkg_bindmnt' is already mounted on /pkg/$PKG (try 'umount /pkg/$PKG')"
	fi
fi

echo "sudo -u build script -q -e -c \"./$PKG.build.sh\" /package/pkg/$PKG/$PKG.build.log"
(
	sudo -u build script -q -e -c "./$PKG.build.sh" /package/pkg/$PKG/$PKG.build.log
	sudo -u build cp "$PKG.build.sh" "/package/pkg/$PKG/$PKG.build.sh"
)

# make double sure PKG is not empty even if bugs are introduced in code above
test -z "$PKG" && die "internal error: PKG is empty"
log_cmd chown -R bin:bin "/pkg/$PKG"

if [ -n "$opt_bind" ]; then
	test -z "$PKG" && die "internal error: PKG variable is empty"
	test $(ls "/pkg/$PKG" | wc -l) = 0 && die "/pkg/$PKG contains no files"
	# withdraw our 'foot in the door'
	exec 3<&-
	log_cmd umount /pkg/$PKG
	# enforce single filesystem as source, and ignore .*
	log_cmd cp -ax $bind_dir/pkg_bindmnt/* /package/pkg/$PKG
	log_cmd chown bin:bin "/package/pkg/$PKG"
fi