#!/usr/bin/env bash

# Copyright (C) 2013-2014, 2017 Luke Shumaker <lukeshu@sbcglobal.net>
# Copyright (C) 2020 André Silva <emulatorman@hyperbola.info>
# Copyright (C) 2020 Márcio Silva <coadde@hyperbola.info>
#
# For code from db-functions (arch_svn):
#   Copyright (C) 2012 Pierre Schmitz <pierre@archlinux.de>
# For code from db-move+db-remove (move+unrelease):
#   Copyright (C) 2008-2009 Aaron Griffin <aaronmgriffin@gmail.com>
#   Copyright (C) 2009 Abhishek Dasgupta <abhidg@gmail.com>
#   Copyright (C) 2009, 2011 Dan McGee <dan@archlinux.org>
#   Copyright (C) 2009-2012 Pierre Schmitz <pierre@archlinux.de>
# For code just from db-move (move):
#   Copyright (C) 2011 Rémy Oudompheng <remyoudompheng@gmail.com>
#   Copyright (C) 2012 Florian Pritz <bluewind@xinu.at>
# For code just from db-remove (unrelease):
#   Copyright (C) 2009 Eric Bélanger <snowmaniscool@gmail.com>
#   Copyright (C) 2011 Florian Pritz <bluewind@xinu.at>
#
# License: GNU GPLv2+
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program.  If not, see <http://www.gnu.org/licenses/>.

load_config() {
	. "$(librelib conf)"
	load_files xbs-abs
	# SVNUSER is optional
	check_vars xbs-abs SVNDIR SVNREPOS ARCHES || exit 1
}

# This is taken from dbscripts:db-fuctions
arch_svn() {
	if [[ -z "${SVNUSER}" ]]; then
		/usr/bin/svn "${@}"
	else
		doas -u "${SVNUSER}" -- /usr/bin/svn --username "${USER}" "${@}"
	fi
}

pac2svn() {
	local pacrepo=$1

	# Figure out which svn repo we need
	local svnrepoStr
	for svnrepoStr in "${SVNREPOS[@]}"; do
		local svnrepoAry=($svnrepoStr)
		local svnrepo=${svnrepoAry[0]}
		local svnurl=${svnrepoAry[1]}
		local pacrepos=("${svnrepoAry[@]:2}")

		if in_array "$pacrepo" "${pacrepos[@]}"; then
			echo "$svnrepo"
			return 0
		fi
	done
	return 1
}

status() {
	load_config
	[[ -z $(arch_svn status -q) ]]
}

download() {
	load_config

	local svnrepoStr
	for svnrepoStr in "${SVNREPOS[@]}"; do
		local svnrepoAry=($svnrepoStr)
		local svnrepo=${svnrepoAry[0]}
		local svnurl=${svnrepoAry[1]}
		local pacrepos=("${svnrepoAry[@]:2}")

		if [[ -d "$SVNDIR/$svnrepo/.svn" ]]; then
			arch_svn -q up "$SVNDIR/$svnrepo"/*
		else
			# checkout non-recursive, then lazy load
			# necessary because:
			#  > DO NOT CHECK OUT THE ENTIRE SVN REPO. Your address
			#  > may be blocked.
			arch_svn -q checkout -N "$svnurl" "$SVNDIR/$svnrepo"
		fi
	done
}

release-client() {
	local repo=$1
	local arch=$2

	# Hack to use arch_svn as 'svn' in external scripts
	local tmpdir; tmpdir="$(mktemp -dt "xbs-abs-release.XXXXXXXXXX")"
	trap "$(printf 'rm -rf -- %q' "$tmpdir")" EXIT
	printf '%s\n' \
		'#!/bin/bash' \
		"$(declare -p SVNUSER 2>/dev/null)" \
		"$(declare -f arch_svn)" \
		'arch_svn "$@"' \
		> "$tmpdir/svn"
	chmod 755 "$tmpdir/svn"
	export PATH="$tmpdir:$PATH"

	"${0}.d/archrelease" -f "${repo}-${arch}"
	"${0}.d/commitpkg" "${repo}" "${arch}"
}

release-server() {
	# Do nothing
	:
}

unrelease() {
	local pkgbase=$1
	local repo=$2
	local arch=$3

	local tag="$repo-$arch"

	load_config
	local svndir
	svndir="${SVNDIR}/$(pac2svn "$repo")/${pkgbase}"
	arch_svn up -q "$svndir"

	# This is based off code from dbscripts:db-remove
	arch_svn rm --force -q "${svndir}/repos/${tag}"
	arch_svn commit -q "${svndir}" -m "${0##*/}: $pkgbase removed by $(id -un)"
}

move() {
	local repo_from=$1
	local repo_to=$2
	local pkgbase=$3

	load_config
	local svndir
	svndir="${SVNDIR}/$(pac2svn "$repo")/${pkgbase}"
	arch_svn up -q "$svndir"

	local tag_list=""
	local pkgarch
	local arches=()
	# this is based off code from dbscripts:db-move
	for pkgarch in "${ARCHES[@]}" 'any'; do
		local dir_from="${svndir}/repos/${repo_from}-${pkgarch}"
		local dir_to="${svndir}/repos/${repo_to}-${pkgarch}"

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

			local file
			for file in $(arch_svn ls "${dir_from}"); do
				arch_svn mv -q -r HEAD "${dir_from}/$file@" "${dir_to}/"
			done
			arch_svn rm --force -q "${dir_from}"
			tag_list="$tag_list, $pkgarch"
			arches+=("$pkgarch")
		fi
	done
	tag_list="${tag_list#, }"
	arch_svn commit -q "${svndir}" -m "${0##*/}: moved ${pkgbase} from [${repo_from}] to [${repo_to}] (${tag_list})"
	echo "${arches[*]}"
}

releasepath() {
	local pkgbase=$1
	local repo=$2
	local arch=$3

	load_config
	local svndir releasepath
	svndir="${SVNDIR}/$(pac2svn "$repo")/${pkgbase}"
	arch_svn up -q "${svndir}"
	releasepath="${svndir}/repos/${repo}-${arch}"
	if [[ -f "${releasepath}/PKGBUILD" ]]; then
		printf '%s\n' "$releasepath"
		return 0
	fi
	return 1
}

name() {
	echo SVN
}

case "$1" in
	status|download|release-client|release-server|unrelease|move|releasepath|name) "$@";;
	*) exit 127;;
esac
