#!/bin/bash

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

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

source_makepkg

reponame="$1"
current_arch=""

[ "$UID" = "" ] && UID=$(uid)

WORKDIR="$TMPDIR/db-update.$svnrepo.$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

# Get the package name from the filename
# hackish, but should work for now
getpkgname() {
	local tmp

	tmp=${1##*/}
	tmp=${tmp%$PKGEXT}
	tmp=${tmp%-$current_arch}
	echo ${tmp%-*-*}
}

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

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

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

trap ctrl_c 2
trap cleanup 0

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

echo "==> Processing new/updated arch-independent packages for '$reponame'..." >&2
cd "$WORKDIR"
svnpath="$(get_svnpath $reponame)"
/usr/bin/svn checkout -N $svnpath checkout
cd checkout
to_add_any=""
if [ -n "$ANYPKGS" ]; then
	for pkg in $ANYPKGS; do
		_pkgfile=$(basename $pkg)
		_pkgname="$(getpkgname $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 $_pkgname"
			/usr/bin/svn up -q $_pkgname
			if [ -d "$_pkgname/repos/$svnrepo" ]; then
				. "$_pkgname/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 $_pkgname not found in $svnrepo"
			fi
		fi
	done
fi

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

	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

	svnpath="$(get_svnpath $reponame)"
	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.db.tar.$DB_COMPRESSION" ]; then
		/bin/cp "$ftppath/$reponame.db.tar.$DB_COMPRESSION" 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" || -n "$ANYPKGS" ]; then

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

		echo "==> Processing new/updated packages for repository '$reponame'..." >&2

		cd "$WORKDIR"
		/usr/bin/svn checkout -N $svnpath checkout
		cd checkout
	
		if [ -n "$ADDPKGS" ]; then
			for pkg in $ADDPKGS; do
				_pkgfile=$(basename $pkg)
				_pkgname="$(getpkgname $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 $_pkgname"
					/usr/bin/svn up -q $_pkgname
					if [ -d "$_pkgname/repos/$svnrepo" ]; then
						. "$_pkgname/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 $_pkgname not found in $svnrepo"
					fi
				fi
			done
		fi

		if [ -n "$to_add" || -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.db.tar.$DB_COMPRESSION" $pkgs
		else
			rm -f "build/$reponame.db.tar.$DB_COMPRESSION"
			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
		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
		for f in "$WORKDIR/build/"*any.pkg.tar.gz; do
			if ! /bin/cp "$f" "$ftppath_any"; then
				die "error: failure while copying files to $ftppath_any"
			fi
			if ! ln -s "$ftppath_any/$f" "$ftppath/$f"; then
				die "error: failed to make link for $f."
			fi
		done
		if ! /bin/cp "$WORKDIR/build/$reponame.db"* "$ftppath"; then
			die "failed to move repository $reponame-$A".
		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

/bin/rm $to_add_any
cleanup
# vim: set ts=4 sw=4 noet ft=sh: