#!/bin/bash -e

. $(dirname $0)/mbd-common.sh
. "${MBD_REPCONFIGFILE}"

mbd_opt_init "Mini-buildd: Preinstall script for mini-dinstall."
mbd_opt_addPos "CHANGESFILE" "Full path to changes file."
mbd_opt_parse "$@"
mbdCheckUser mini-buildd

MBD_TMP_CF="$(mbd_opt_getPos 0)"
MBD_PREINSTALL_HOOK="${MBD_LOCALCONFIG}/preinstall"

mbdCheckFile "${MBD_TMP_CF}"

mbdParseCF "${MBD_TMP_CF}"

mbdABSpoolRun()
{
	local c
	for c in $(find "${MBD_INCOMING_BPO}/" -maxdepth 2 -mindepth 2 -name "*_source.changes"); do
		mbdParseCF "${c}"
		local inst=true
		local f
		for f in ${mbdParseCF_files}; do
			${MBD_LOG} -s "I: Auto-backports $(basename $c): Checking ${f}."
			if [ -e "${MBD_INCOMING}/${f}" ]; then
				${MBD_LOG} -s "W: Auto-backports $c: Can't upload yet (${f})."
				inst=false
				continue
			fi
		done
		if ${inst}; then
			${MBD_LOG} -s "I: Auto-backports Uploading ${c}."
			(
				cd "$(dirname "${c}")"
				mv -v ${mbdParseCF_files} ${MBD_INCOMING}/ 2>&1 | ${MBD_LOG} -s
			)
		fi
	done
}

mbdShowQAChecks()
{
	local id="${1}"
	local url="http://${mbd_rephost}:${mbd_httpport}/~mini-buildd/log/${id}"

	echo "QA-Checks: ${url}"
	echo "----------------------------------------------------------------------"
	for s in ${MBD_HOME}/log/${id}/*.status; do
		local name=$(basename "${s}" .status)
		local status=$(cat "${s}")
		echo "${status} (${name}): ${url}/${name}.log"
	done
	echo "----------------------------------------------------------------------"
	echo "Preinstall log: ${url}.log"
}


mbdQAPreliminary()
{
	${MBD_LIB}/mbd-qa-check -c "${MBD_TMP_CF}" -Q "Version New Orig UploadDSP" -I "${MBD_TMP_BUILDID}" -P "10_Preliminary"
}

mbdQAPrebuild()
{
	${MBD_LIB}/mbd-qa-check -a "${mbd_archall}" -r -c "${MBD_TMP_SRC_CF_ONANYBLD}" -Q "Lintian" -I "${MBD_TMP_BUILDID}" -P "20_Prebuild"
}

mbdArchBuild()
{
	local cf="${MBD_HOME}/bld/builds/$(mbdBId2BDir "${mbdParseArch_arch}" "${MBD_TMP_BUILDID}")/${mbdParseCF_package}_source.changes"
	${MBD_LIB}/mbd-qa-check -a "${mbdParseArch_arch}" -r -c "${cf}" -Q "Build" -I "${MBD_TMP_BUILDID}" -P "30_Build_${mbdParseArch_arch}"
}

mbdArchQAPostbuild()
{
	local cf="${MBD_HOME}/bld/builds/$(mbdBId2BDir "${mbdParseArch_arch}" "${MBD_TMP_BUILDID}")/${mbdParseCF_package}_${mbdParseArch_arch}.changes"
	# Only run this if we have a changes file on bld host
	if ssh -o StrictHostKeyChecking=no -p ${mbd_sshport} ${mbdParseArch_host} "test -f ${cf}"; then
		${MBD_LIB}/mbd-qa-check -a "${mbdParseArch_arch}" -r -c "${cf}" -Q "Lintian DownloadDBP Backports" -I "${MBD_TMP_BUILDID}" -P "40_Postbuild_${mbdParseArch_arch}"
	else
		${MBD_LOG} -s "${MBD_TMP_LOGPRE}: ${mbdParseArch_arch}: No changes file (skipping postbuild checks)."
	fi
}

mbdArchClean()
{
	local buildDir="bld/builds/$(mbdBId2BDir "${mbdParseArch_arch}" "${MBD_TMP_BUILDID}")"
	local info="${MBD_TMP_LOGPRE}: ${mbdParseArch_host}: ${buildDir}"
	${MBD_LOG} -s "${info}: Cleaning..."
	ssh -o StrictHostKeyChecking=no -p ${mbd_sshport} ${mbdParseArch_host} "rm -rf ${buildDir}"
	${MBD_LOG} -s "${info}: Cleaned."
}

# Run function on all build hosts in parallel.
mbdArchRun()
{
	local f="${1}"
	local pids=""
	local retval=0

	for arch in $(mbdD2SList "${mbd_archs}"); do
		mbdParseArch "${arch}"
		${f} &
		pids="${pids} $!"
	done

	local p
	for p in ${pids}; do
		if ! wait ${p}; then
			retval=1
		fi
	done
	return ${retval}
}

mbdMoveFiles()
{
	local dir="${1}"
	echo "I: Uploaded files moved to ${dir}."
	mkdir "${dir}"

	local f
	for f in ${mbdParseCF_files}; do
		mv "$(dirname "${MBD_TMP_CF}")/${f}" "${dir}" || true
	done
}

MBD_TMP_LOGPRE="I: ${mbdParseCF_package}(${mbdParseCF_dist})"
# We propagate source-only uploads to builders, binary uploads are skipped
if [ "${mbdParseCF_arch}" = "source" ]; then
	MBD_TMP_BUILDID="${mbdParseCF_source}/${mbdParseCF_version}/$(date --utc +%Y%m%d:%H%M%S:%N)"
	MBD_TMP_LOGDIR="${MBD_HOME}/log/${MBD_TMP_BUILDID}"
	mkdir -p "${MBD_TMP_LOGDIR}" || exit 10
	MBD_TMP_SRC_CF_ONANYBLD="${MBD_HOME}/bld/builds/$(mbdBId2BDir "${mbd_archall}" "${MBD_TMP_BUILDID}")/$(basename "${MBD_TMP_CF}")"

	${MBD_LOG} -s "${MBD_TMP_LOGPRE}: DSP upload. Build-ID is ${MBD_TMP_BUILDID}."

	# Bash4 will exit-on-error if subshell fails, so we need to diable error exit
	set +e
	(
		mbdQAPreliminary
		[ $? -eq 0 ] || exit 2  # REJECT

		mbdQAPrebuild
		[ $? -eq 0 ] || exit 2  # REJECT

		mbdArchRun mbdArchBuild
		[ $? -eq 0 ] || exit 1  # FTBFS

		mbdArchRun mbdArchQAPostbuild
		[ $? -eq 0 ] || exit 2  # REJECT

	) >"${MBD_TMP_LOGDIR}.log" 2>&1
	MBD_PREINSTALL_RETVAL=$?
	set -e

	MBD_PREINSTALL_STATUS=$(mbdRetval2Status PREINSTALL ${MBD_PREINSTALL_RETVAL})
	echo "${MBD_PREINSTALL_STATUS}" >"${MBD_TMP_LOGDIR}.status"

	# Cleanup Build area on all build hosts. Always ignore retval; cosmetic only.
	mbdArchRun mbdArchClean >>"${MBD_TMP_LOGDIR}.log" 2>&1 || true

	(
		case ${MBD_PREINSTALL_STATUS} in
			BUILT)
				echo "I: Built and uploaded for all archs (${mbdParseCF_dist})."
				echo "----------------------------------------------------------------------"
				cat "${MBD_TMP_CF}"

				if [ -x "${MBD_PREINSTALL_HOOK}" ]; then
					echo "----------------------------------------------------------------------"
					${MBD_LOG} -s "${MBD_TMP_LOGPRE}: Running local hook for ${mbdParseCF_arch}:"
					${MBD_PREINSTALL_HOOK} "${MBD_TMP_CF}" 2>&1 | ${MBD_LOG} -s || true
				fi
				;;
			FTBFS)
				echo "E: Fails to build from source; please re-upload if you need a retry."
				mbdMoveFiles "${MBD_TMP_LOGDIR}/FTBFS"
				;;
			REJECT)
				echo "E: Mandatory QA-Check failed. Please check failing qa check."
				mbdMoveFiles "${MBD_TMP_LOGDIR}/REJECT"
				;;
			*)
				echo "E: Internal error detected. Please check preinstall log."
				;;
		esac
		echo "----------------------------------------------------------------------"
		mbdShowQAChecks "${MBD_TMP_BUILDID}"
	) 2>&1 | mail -s "${MBD_PREINSTALL_STATUS}(${mbdParseCF_dist}): ${mbdParseCF_package}" "${mbd_mail}"
	${MBD_LOG} -s "${MBD_TMP_LOGPRE}: ${MBD_PREINSTALL_STATUS}."
	exit ${MBD_PREINSTALL_RETVAL}
else
	( mbdABSpoolRun ) || true

	if [ "${mbdParseCF_maintainer}" = "${MBD_AUTOBUILD_MAINTAINER}" ]; then
		${MBD_LOG} -s "${MBD_TMP_LOGPRE}: DBP upload ${mbdParseCF_arch}."

		if [ -x "${MBD_PREINSTALL_HOOK}" ]; then
			${MBD_LOG} -s "${MBD_TMP_LOGPRE}: Running local hook for ${mbdParseCF_arch}:"
			${MBD_PREINSTALL_HOOK} "${MBD_TMP_CF}" 2>&1 | ${MBD_LOG} -s || true
		fi

		exit 0
	else
		(
			echo "E: Direct binary upload (${mbdParseCF_maintainer} != ${MBD_AUTOBUILD_MAINTAINER})."
			echo "I: Only source-only uploads are accepted; use \"-S\" option for *-buildpackage."
			echo "I: Uploaded files purged."
			for f in ${mbdParseCF_files}; do
				rm "$(dirname "${MBD_TMP_CF}")/${f}" || true
			done
		) 2>&1 | mail -s "DISCARD: ${mbdParseCF_package} ${mbdParseCF_arch}" "${mbd_mail}"
		${MBD_LOG} -s "${MBD_TMP_LOGPRE}: DISCARD: Direct ${mbdParseCF_arch} DBP upload."
		exit 42
	fi
fi
