#!/hint/bash

# Within this file (and in most of dbscripts, really):
# - "pkgarch" refers to the package architecture; may be "any"
# - "tarch" refers to the repo architecture; may NOT be "any"

if [[ -n ${SVNUSER} ]]; then
	setfacl -m u:"${SVNUSER}":rwx "${WORKDIR}"
	setfacl -m d:u:"${USER}":rwx "${WORKDIR}"
	setfacl -m d:u:"${SVNUSER}":rwx "${WORKDIR}"
fi

arch_svn() {
	if [[ -z ${SVNUSER} ]]; then
		/usr/bin/svn "${@}"
	else
		sudo -u "${SVNUSER}" -- /usr/bin/svn --username "${USER}" "${@}"
	fi
}

_svn_checkout() {
	local pkgbase=$1
	if ! [[ -d ${WORKDIR}/svn ]]; then
		arch_svn checkout -q -N "${SVNREPO}" "${WORKDIR}/svn" >/dev/null
	fi
	if ! [[ -d ${WORKDIR}/svn/${pkgbase} ]]; then
		arch_svn up -q "${WORKDIR}/svn/${pkgbase}" >/dev/null
	fi
}

# usage: vcs_move_preflight_check repo_from pkgarch pkgbase
#
# Verify that $pkgbase exists in $repo_from in SVN, such that we can
# move it to a different repo.
vcs_move_preflight_check() {
	local repo_from=$1
	local tarch=$2
	local pkgbase=$3

	_svn_checkout "$pkgbase"
	local reposdir="${WORKDIR}/svn/${pkgbase}/repos"
	[[ -r ${reposdir}/${repo_from}-${tarch}/PKGBUILD || -r ${reposdir}/${repo_from}-any/PKGBUILD ]]
}

# usage: vcs_move_start repo_from repo_to pkgbase
#
# Begin a VCS transaction moving $pkgbase from $repo_from to $repo_to.
# This should be followed by a call to vcs_move_arch for each
# architecture we're movin it for, and finally by a call to
# vcs_move_finish.
vcs_move_start() {
	svn_move_repo_from=$1
	svn_move_repo_to=$2
	svn_move_pkgbase=$3

	svn_move_tag_list=""
}

# usage: vcs_move_arch tarch
#
# Add an architecture to a VCS transaction started by vcs_move_start.
#
# If the "from" PKGBUILD doesn't exist, this is a no-op (not an
# error).  This is because we expect to be called exactly once for
# each tarch (eg: x86_64, i686), but if arch=(any) then we only need
# do the work once; on the subsequent calls the "from" PKGBUILD won't
# exist anymore.  If the source PKGBUILD never existed, we expect that
# to have already been caught by vcs_move_preflight_check.
vcs_move_arch() {
	local tarch=$1

	local repo_from=$svn_move_repo_from
	local repo_to=$svn_move_repo_to
	local pkgbase=$svn_move_pkgbase

	local pkgarch
	if [[ -r "${WORKDIR}/svn/${pkgbase}/repos/${repo_from}-${tarch}/PKGBUILD" ]]; then
		pkgarch=$tarch
	elif [[ -r "${WORKDIR}/svn/${pkgbase}/repos/${repo_from}-any/PKGBUILD" ]]; then
		pkgarch=any
	else
		return 0
	fi

	local svnrepo_from="${WORKDIR}/svn/${pkgbase}/repos/${repo_from}-${pkgarch}"
	local svnrepo_to="${WORKDIR}/svn/${pkgbase}/repos/${repo_to}-${pkgarch}"

	if [[ -d ${svnrepo_to} ]]; then
		for file in $(arch_svn ls "${svnrepo_to}"); do
			arch_svn rm -q "${svnrepo_to}/$file@"
		done
	else
		mkdir "${svnrepo_to}"
		arch_svn add -q "${svnrepo_to}"
	fi

	for file in $(arch_svn ls "${svnrepo_from}"); do
		arch_svn mv -q -r HEAD "${svnrepo_from}/$file@" "${svnrepo_to}/"
	done
	arch_svn rm --force -q "${svnrepo_from}"
	svn_move_tag_list+=", $pkgarch"
}

# usage: vcs_move_finish
#
# Commit/finalize a VCS transaction started by vcs_move_start.
vcs_move_finish() {
	local repo_from=$svn_move_repo_from
	local repo_to=$svn_move_repo_to
	local pkgbase=$svn_move_pkgbase

	local tag_list="${svn_move_tag_list#, }"
	arch_svn commit -q "${WORKDIR}/svn/${pkgbase}" -m "${0##*/}: moved ${pkgbase} from [${repo_from}] to [${repo_to}] (${tag_list})"
}

# usage: vcs_remove repo tarch pkgbase
#
# Remove the given package in VCS.
vcs_remove() {
	local repo=$1
	local tarch=$2
	local pkgbase=$3

	local svnrepo="$repo-$arch"

	_svn_checkout "$pkgbase"
	if [[ -d ${WORKDIR}/svn/$pkgbase/repos/$repo-$tarch ]]; then
		pkgarch=$tarch
	elif [[ -d ${WORKDIR}/svn/$pkgbase/repos/$repo-any ]]; then
		pkgarch=any
	fi
	if [[ -d ${WORKDIR}/svn/$pkgbase/repos/$repo-$pkgarch ]]; then
		arch_svn rm --force -q "${WORKDIR}/svn/$pkgbase/repos/$svnrepo"
		arch_svn commit -q "${WORKDIR}/svn/$pkgbase" -m "${0##*/}: $pkgbase removed by $(id -un)"
		svn_removed+=("$repo-$pkgarch/$pkgbase")
	elif ! in_array "$repo-$pkgarch/$pkgbase" "${svn_removed[@]}"; then
		warning "pkgbase '%s' not found in svn; unable to commit removal to svn" "$pkgbase"
	fi
}

# usage: vcs_export repo pkgarch pkgbase dest
#
# Export the VCS files for a package to the given $dest directory.
vcs_export() {
	local repo=$1
	local pkgarch=$2
	local pkgbase=$3
	local dest=$4

	arch_svn export -q "${SVNREPO}/${pkgbase}/repos/${repo}-${pkgarch}" \
		 "${dest}" >/dev/null 2>&1
}
