#!/bin/bash

if [ $# -ne 1 ]; then
	echo "usage: $(basename $0) <reponame>"
	exit 1
fi

. "$(dirname $0)/db-functions"
. "$(dirname $0)/config"

reponame="$1"
current_arch=""

# ensure we should be playing with this DB on this server
repos="$(get_repos_for_host)"
found=0
for r in $repos; do
	if [ "$r" = "$reponame" ]; then
		found=1
	fi
done
if [ $found -ne 1 ]; then
	echo "error: you shouldn't be updating $reponame on this server!"
	exit 1
fi

WORKDIR="$TMPDIR/db-update.$reponame.$UID"
ADDPKGS=""
ANYPKGS=""

stagedir="$STAGING/$reponame"
if [ ! -d $stagedir ]; then
	echo "error: staging directory missing: $stagedir" >&2
	exit 1
fi

if [ -d "${stagedir}64" ]; then
	echo "--------------------------------------------------"
	echo "It looks like you have an old staging dir"
	echo "Packages are now differentiated by the arch in the filename."
	echo "Please delete '${stagedir}64'"
	echo "--------------------------------------------------"
	/bin/mv "${stagedir}64/add/"* "$stagedir/add/"
	/bin/mv "${stagedir}64/del/"* "$stagedir/del/"
fi

if [ -d "${stagedir}/add" ]; then
	echo "--------------------------------------------------"
	echo "It looks like you have an old staging dir"
	echo "The 'add' and 'del' dirs are no longer used."
	echo "Please delete staging/<reponame>/{add,del}"
	echo " and ensure you are using the newest devtools"
	echo "--------------------------------------------------"
	/bin/mv "${stagedir}/add/"* "$stagedir/"
fi

cleanup() {
    trap '' 0 2
	repo_unlock $reponame $current_arch
	rm -rf "$WORKDIR"
	[ "$1" ] && exit $1
}

ctrl_c() {
	echo "Interrupted" >&2
	cleanup 1
}

die() {
	echo "$*" >&2
	cleanup 1
}

trap ctrl_c 2
trap cleanup 0

# Remove any package from $stagedir that is already in the FTP repository
for current_arch in ${ARCHES[@]} any; do
	ftppath="$FTP_BASE/$reponame/os/$current_arch"
	for f in $stagedir/*-$current_arch$PKGEXT; do
		bf=$(basename $f)
		if [[ -f $ftppath/$bf ]]; then
			echo "    WARNING: Package file $bf already exists in FTP repo"
			echo "    Removing from $stagedir"
			/bin/rm $f
		fi
	done
done

# Process architecture-independent packages first.
if [ -d "$stagedir" ]; then
	ANYPKGS="$(/bin/ls $stagedir/*-any$PKGEXT 2>/dev/null)"
fi

mkdir -p $WORKDIR
cd "$WORKDIR"

if [ -n "$ANYPKGS" ]; then
	pkgtotal=$(echo "$ANYPKGS" | wc -w)
	echo "==> Processing $pkgtotal new/updated arch-independent packages for '$reponame'..." >&2

	/usr/bin/svn checkout -N $SVNREPO checkout
	cd checkout
	to_add_any=""
	for pkg in $ANYPKGS; do
		_pkgfile=$(basename $pkg)
		_pkgname="$(getpkgname $pkg)"
		_pkgbase="$(getpkgbase $pkg)"
		svnrepo="$reponame-any"
		echo "    Validating package arch (any) $_pkgname"
		if ! check_pkg_arch "$pkg" "any"; then
			echo "   ERROR: $_pkgfile is not architecture independent!"
		else
			echo "    Checking SVN for $_pkgbase"
			/usr/bin/svn up -q $_pkgbase
			if [ -d "$_pkgbase/repos/$svnrepo" ]; then
				. "$_pkgbase/repos/$svnrepo/$BUILDSCRIPT"
				if [ "$_pkgfile" = "$_pkgname-$pkgver-$pkgrel-any$PKGEXT" ]; then
					to_add_any="$to_add_any $pkg"
				else
					echo "    WARNING: $_pkgfile does not match $BUILDSCRIPT in $svnrepo"
				fi
			else
				echo "    WARNING: Package $_pkgbase not found in $svnrepo"
			fi
		fi
	done
fi

for current_arch in ${ARCHES[@]}; do

	ftppath="$FTP_BASE/$reponame/os/$current_arch"
	ftppath_any="$FTP_BASE/$reponame/os/any"

	if [ ! -d "$ftppath" ]; then
		echo "FTP path for this repo ($reponame) is missing"
		echo "   -> $ftppath"
		echo "Please contact a system administrator"
		exit 1
	fi

	svnrepo="$reponame-$current_arch"

	repo_lock $reponame $current_arch

	/bin/mkdir -p "$WORKDIR/build"
	cd "$WORKDIR"

	# copy the db file into our working area
	if [ -f "$ftppath/$reponame$DBEXT" ]; then
		/bin/cp "$ftppath/$reponame$DBEXT" build/
	fi

	echo "Updating DB for $svnrepo"

	to_add=""
	if [ -d "$stagedir" ]; then
		ADDPKGS="$(/bin/ls $stagedir/*-${current_arch}$PKGEXT 2>/dev/null)"
	fi

	if [ -n "$ADDPKGS" -o -n "$ANYPKGS" ]; then

		echo "==> Copying DB file from '$reponame'..." >&2
		if [ -f "$ftppath/$reponame$DBEXT" ]; then
			/bin/cp "$ftppath/$reponame$DBEXT" build/
		fi

		pkgtotal=$(echo "$ADDPKGS $ANYPKGS" | wc -w)
		echo "==> Processing $pkgtotal new/updated packages for repository '$reponame'..." >&2

		cd "$WORKDIR"
		/usr/bin/svn checkout -N $SVNREPO checkout
		cd checkout
	
		if [ -n "$ADDPKGS" ]; then
			for pkg in $ADDPKGS; do
				_pkgfile=$(basename $pkg)
				_pkgname="$(getpkgname $pkg)"
				_pkgbase="$(getpkgbase $pkg)"

				echo "    Validating package arch ($current_arch) $_pkgname"
				if ! check_pkg_arch "$pkg" "$current_arch"; then
					echo "   ERROR: $_pkgfile was built for the wrong architecture"
				else
					echo "    Checking SVN for $_pkgbase"
					/usr/bin/svn up -q $_pkgbase
					if [ -d "$_pkgbase/repos/$svnrepo" ]; then
						. "$_pkgbase/repos/$svnrepo/$BUILDSCRIPT"
						if [ "$_pkgfile" = "$_pkgname-$pkgver-$pkgrel-$current_arch$PKGEXT" ]; then
							to_add="$to_add $pkg"
						else
							echo "    WARNING: $_pkgfile does not match $BUILDSCRIPT in $svnrepo"
						fi
					else
						echo "    WARNING: Package $_pkgbase not found in $svnrepo"
					fi
				fi
			done
		fi

		if [ -n "$to_add" -o -n "$to_add_any" ]; then
			cd "$WORKDIR/build/"
			for f in $to_add $to_add_any; do /bin/cp "$f" .; done

			pkgs=""
			for pkg in $to_add $to_add_any; do pkgs="$pkgs $(basename $pkg)"; done

			/usr/bin/repo-add -q "$reponame$DBEXT" $pkgs
		else
			rm -f "build/$reponame$DBEXT"
			echo "Errors found when adding packages"
		fi
	else
		echo "No packages to add"
	fi

	# if non empty, move all build dirs
	if [ $(/bin/ls "$WORKDIR/build/" 2>/dev/null | wc -l) != 0 ]; then
		if [ $(/bin/ls "$WORKDIR/build/"*-$current_arch$PKGEXT 2>/dev/null | wc -l) != 0 ]; then
			echo "Copying new files to '$ftppath'"
			for f in "$WORKDIR/build/"*-$current_arch$PKGEXT; do
				if ! /bin/cp "$f" "$ftppath/"; then
					die "error: failure while copying files to $ftppath"
				fi
			done
		fi
		if [ $(/bin/ls "$WORKDIR/build/"*-any$PKGEXT 2>/dev/null | wc -l) != 0 ]; then
			echo "Copying new files to '$ftppath_any' and symlinking"
			for f in "$WORKDIR/build/"*-any$PKGEXT; do
				if ! /bin/cp "$f" "$ftppath_any"; then
					die "error: failure while copying files to $ftppath_any"
				fi
				bf=$(basename $f)
				if ! ln -s "../any/$bf" "$ftppath/$bf"; then
					die "error: failed to make link for $bf."
				fi
			done
		fi
		if ! /bin/cp "$WORKDIR/build/$reponame.db"* "$ftppath/"; then
			die "failed to move repository $reponame-$current_arch".
		fi
	else
		echo "Nothing to copy, no work done"
	fi

	if [ -n "$to_add" ]; then
		echo "Cleaning staging dir"
		/bin/rm $to_add
	fi

	repo_unlock $reponame $current_arch
done

if [ -n "$to_add_any" ]; then
	/bin/rm $to_add_any
fi

trap '' 0 2
rm -rf $WORKDIR
# vim: set ts=4 sw=4 noet ft=sh: