#!/bin/sh

# Usage: af_mkuser
# Create the "build" user and group with the correct IDs.
af_mkuser() {
	groupadd -g "$AF_BUILD_GID" build
	useradd -g build -u "$AF_BUILD_UID" -d /af -s /bin/sh build
}

# Usage: af_userconf
# Set up the $ABUILD_USERCONF file. Generate a $PACKAGER_PRIVKEY if
# necessary, and install its corresponding public key to /etc/apk/keys.
af_userconf() (
	set -e

	if ! [ -e "$ABUILD_USERCONF" ]; then
		touch "$ABUILD_USERCONF"
		chown build:build "$ABUILD_USERCONF"
	fi

	. "$ABUILD_USERCONF"
	if [ -z "$PACKAGER_PRIVKEY" ]; then
		cd "$APORTSDIR"
		USER=build abuild-keygen -anq
		cd "$OLDPWD"
		. "$ABUILD_USERCONF"
		chown build:build "$PACKAGER_PRIVKEY" "$PACKAGER_PRIVKEY.pub"
	fi
	cp "$PACKAGER_PRIVKEY.pub" /etc/apk/keys

	# We only want to make a copy of the container's key if re-signing
	# will not occur (otherwise it is useless).
	if [ -n "$AF_PUBKEY_COPY" ]; then
		cp "$PACKAGER_PRIVKEY.pub" "$REPODEST"
	fi

	if [ -z "$PACKAGER" ]; then
		cat >> "$ABUILD_USERCONF" <<-EOF
		PACKAGER="APK Foundry"
		EOF
	fi
)

# Usage: af_loginit [-at]
# Redirect standard output and standard error to a log file named
# $REPODEST/$repo/$CARCH/logs/$pkgname-$pkgver-r$pkgrel.log depending on
# the APKBUILD in the current working directory. A symlink named
# /af/build/log will also point to this log file.
#
# -a        append to .log file instead of overwriting. Do not enable
#           this if the project has persistent_repodest is enabled!
# -t        tee to original standard output
af_loginit() {
	local append opt tee
	OPTIND=1
	while getopts at opt; do
	case "$opt" in
	a) append=-a;;
	t) tee=1;;
	esac
	done
	shift "$((OPTIND - 1))"

	(
		set -e
		repo="${PWD%/*}"
		repo="${repo##*/}"
		logdir="$REPODEST/$repo/$CARCH/logs"
		mkdir -p "$logdir"
		rm -f /af/build/log
		. ./APKBUILD
		ln -sr "$logdir/$pkgname-$pkgver-r$pkgrel.log" /af/build/log
	)

	if [ -n "$tee" ]; then
		pipe="$(mktemp)"
		rm -f "$pipe"
		mkfifo -m 600 "$pipe"
		(
			tee $append /af/build/log < "$pipe" || :
			rm -f "$pipe"
		) &
		exec >"$pipe" 2>&1
	elif [ -n "$append" ]; then
		exec >>/af/build/log 2>&1
	else
		exec >/af/build/log 2>&1
	fi
}

# Usage: af_abuild_env STARTDIR
# Sets up the environment for abuild to perform out-of-tree builds. This
# is useful when trying to resume a failed build or otherwise run a
# build interactively.
af_abuild_env() {
	export HOME=/af/build/"$1"/tmp
	mkdir -p "$HOME"
	export TEMP="$HOME" TMP="$HOME" TEMPDIR="$HOME" TMPDIR="$HOME"
	export ABUILD_TMP=/af/build
}

# Usage: af_abuild_unpriv [abuild options...] [abuild phases...]
# A wrapper that completely drops APK Foundry privileges before
# executing abuild.
af_abuild_unpriv() (
	set -e
	eval "exec $AF_SUDO_FD>&-"
	export ABUILD_FETCH=
	export ADDGROUP=
	export ADDUSER=
	export SUDO_APK=
	export APK_FETCH=
	export AF_SUDO_FD=
	exec abuild "$@"
)

# Usage: af_abuild [-cDfkKmPqsv]
# A wrapper for abuild that performs privileged actions first, then
# executes the rest of the build using af_abuild_unpriv. It is
# equivalent to "abuild -r".
#
# No phases may be given.
#
# Only a subset of abuild options are supported.
af_abuild() {
	local force opt
	OPTIND=1
	while getopts cD:fkKmP:qs:v opt; do
	case "$opt" in
	# up2date doesn't respect -f so we need to check for it ourselves
	f) force=1;;
	esac
	done
	if [ "$OPTIND" -le "$#" ]; then
		die "invalid usage"
	fi

	if [ -z "$force" ] && abuild "$@" up2date >/dev/null 2>&1; then
		msg "Package is up2date or disabled on $CARCH or $CLIBC"
		return 0
	fi

	# builddeps is normally run before fetch, but fetch errors are more
	# common and especially annoying if you get one after waiting for
	# hundreds of dependencies to be installed first
	abuild "$@" -r sanitycheck fetch builddeps mkusers
	# -d allows us to skip running builddeps twice
	af_abuild_unpriv "$@" -d build_abuildrepo
}
