#!/bin/bash

dirname="$(dirname "$(readlink -e "$0")")"
. "${dirname}/../config"
. "${dirname}/../db-functions"
pushd "${WORKDIR}" >/dev/null

script_lock

for repo in "${PKGREPOS[@]}"; do
	for arch in "${ARCHES[@]}"; do
		repo_lock "${repo}" "${arch}" || exit 1
	done
done

#adjust the nice level to run at a lower priority
renice +10 -p $$ > /dev/null

# Create a readable file for each repo with the following format
# <pkgbase|pkgname> <pkgver>-<pkgrel> <arch> <license>[ <license>]
for repo in "${PKGREPOS[@]}"; do
	# The %n+awk+cut bit is because we can't trust %e, as makepkg
	# <5.1 didn't set pkgbase in .PKGINFO for non-split packages
	# when when pkgbase==pkgname; so until all packages have been
	# rebuilt with makepkg 5.1, we need to look at both pkgbase
	# (%e) and pkgname (%n) to reliably get pkgbase.
	for arch in "${ARCHES[@]}"; do
		# Repo does not exist; skip it
		if [[ ! -f ${FTP_BASE}/${repo}/os/${arch}/${repo}${DBEXT} ]]; then
			continue
		fi
		arch_expac "$repo" "$arch" '%n %e %v %a %L'
	done | awk -F' ' '$2 == "(null)" { $2 = $1 } { print }' | cut -d' ' -f2- |
		sort -u > "${WORKDIR}/db-${repo}"
done

for repo in "${PKGREPOS[@]}"; do
	for arch in "${ARCHES[@]}"; do
		repo_unlock "${repo}" "${arch}"
	done
done

# Create a list of all available source package file names
for f in "${FTP_BASE}"/${SRCPOOL}/*${SRCEXT}; do
	if [[ -f $f ]]; then
		printf '%s\n' "${f##*/}"
	fi
done | sort -u > "${WORKDIR}/available-src-pkgs"

# Check for all packages if we need to build a source package
for repo in "${PKGREPOS[@]}"; do
	newpkgs=()
	failedpkgs=()
	while read -r pkgbase pkgver pkgarch pkglicense; do
		read -ra pkglicense <<<"$pkglicense"

		# Should this package be skipped?
		if grep -Fqx "${pkgbase}" "${dirname}/sourceballs.skip"; then
			continue
		fi
		# Check if the license or .force file does not enforce creating a source package
		if ! ((( ${#ALLOWED_LICENSES[@]} == 0 )) || chk_license "${pkglicense[@]}" || grep -Fqx "${pkgbase}" "${dirname}/sourceballs.force"); then
			continue
		fi
		# Store the expected file name of the source package
		echo "${pkgbase}-${pkgver}${SRCEXT}" >> "${WORKDIR}/expected-src-pkgs"

		# Build the source package if its not already there
		if ! grep -Fqx "${pkgbase}-${pkgver}${SRCEXT}" "${WORKDIR}/available-src-pkgs"; then
			# Check if we had failed before
			if in_array "${pkgbase}-${pkgver}${SRCEXT}" "${failedpkgs[@]}"; then
				continue
			fi

			# Get the sources from vcs
			mkdir -p -m0770 "${WORKDIR}/pkgbuilds/${repo}-${pkgarch}"
			vcs_export "$repo" "$pkgarch" "$pkgbase" \
				"${WORKDIR}/pkgbuilds/${repo}-${pkgarch}/${pkgbase}"
			if (( $? >= 1 )); then
				failedpkgs+=("${pkgbase}-${pkgver}${SRCEXT}")
				continue
			fi

			# Build the actual source package
			pushd "${WORKDIR}/pkgbuilds/${repo}-${pkgarch}/${pkgbase}" >/dev/null
			SRCPKGDEST=. makepkg --nocolor --allsource --ignorearch --skippgpcheck >"${WORKDIR}/${pkgbase}.log" 2>&1
			if (( $? == 0 )) && [[ -f ${pkgbase}-${pkgver}${SRCEXT} ]]; then
				mv_acl "${pkgbase}-${pkgver}${SRCEXT}" "${FTP_BASE}/${SRCPOOL}/${pkgbase}-${pkgver}${SRCEXT}"
				# Avoid creating the same source package for every arch
				echo "${pkgbase}-${pkgver}${SRCEXT}" >> "${WORKDIR}/available-src-pkgs"
				newpkgs+=("${pkgbase}-${pkgver}${SRCEXT}")
			else
				failedpkgs+=("${pkgbase}-${pkgver}${SRCEXT}")
				cat "${WORKDIR}/${pkgbase}.log" >> "${WORKDIR}/makepkg-fail.log"
			fi
			popd >/dev/null
		fi
	done < "${WORKDIR}/db-${repo}"

	if [ ${#newpkgs[@]} -ge 1 ]; then
		msg "Adding source packages for [%s]..." "$repo"
		for new_pkg in "${newpkgs[@]}"; do
			msg2 '%s' "${new_pkg}"
		done
	fi
	if [ ${#failedpkgs[@]} -ge 1 ]; then
		msg "Failed to create source packages for [%s]..." "$repo"
		for failed_pkg in "${failedpkgs[@]}"; do
			msg2 '%s' "${failed_pkg}"
		done
	fi
done

# Cleanup old source packages
sort -u "${WORKDIR}/expected-src-pkgs" > "${WORKDIR}/expected-src-pkgs.sort"
sort -u "${WORKDIR}/available-src-pkgs" > "${WORKDIR}/available-src-pkgs.sort"
old_pkgs=($(comm -23 "${WORKDIR}/available-src-pkgs.sort" "${WORKDIR}/expected-src-pkgs.sort"))

if (( ${#old_pkgs[@]} >= 1 )); then
	msg "Removing old source packages..."
	[[ $SOURCE_CLEANUP_DRYRUN = true ]] && warning 'dry run mode is active'
	for old_pkg in "${old_pkgs[@]}"; do
		msg2 '%s' "${old_pkg}"
		if [[ $SOURCE_CLEANUP_DRYRUN != true ]]; then
			mv_acl "$FTP_BASE/${SRCPOOL}/${old_pkg}" "${SOURCE_CLEANUP_DESTDIR}/${old_pkg}"
			touch "${SOURCE_CLEANUP_DESTDIR}/${old_pkg}"
		fi
	done
fi

unset old_pkgs
touch -d "${SOURCE_CLEANUP_KEEP} days ago"  "${WORKDIR}/cleanup_timestamp"
for f in "${SOURCE_CLEANUP_DESTDIR}"/*${SRCEXT}; do
	if [[ ${WORKDIR}/cleanup_timestamp -nt $f ]]; then
		old_pkgs+=("${f##*/}")
	fi
done

if (( ${#old_pkgs[@]} >= 1 )); then
	msg "Removing old source packages from the cleanup directory..."
	for old_pkg in "${old_pkgs[@]}"; do
		msg2 '%s' "${old_pkg}"
		[[ $SOURCE_CLEANUP_DRYRUN = true ]] || rm -f "${SOURCE_CLEANUP_DESTDIR}/${old_pkg}"
	done
fi

if [[ -f ${WORKDIR}/makepkg-fail.log ]]; then
	msg "Log of failed packages"
	cat "${WORKDIR}/makepkg-fail.log"
fi

script_unlock
