#!/usr/bin/env bash
# License: Unspecified

shopt -s extglob

. "$(librelib messages)"

usage() {
	print 'Usage: %s [OPTIONS]' "${0##*/}"
	print 'Compare a locally built a package with the one in the repositories.'
	echo
	prose 'This should be run from a directory containing a
	       PKGBUILD.  It searches for a locally built package
	       corresponding to the PKGBUILD, and downloads the last
	       version of that package from the pacman repositories.
	       It then compares the list of .so files provided by each
	       version of the package.  It does this for each part of
	       a split package.'
	echo
	print "Options:"
	flag \
		'-h, --help' 'Show this message'
}

mode=run
if ! args="$(getopt -n "${0##*/}" -o 'h' -l 'help' -- "$@")"; then
	mode=errusage
else
	eval "set -- $args"
	while true; do
		flag=$1
		shift
		case "$flag" in
			-h | --help) mode=usage ;;
			--) break ;;
			*) panic 'unhandled flag: %q' "$flag" ;;
		esac
	done
	if [[ $mode == run && $# -gt 0 ]]; then
		gnuerror 'Extra arguments: %s' "$*"
		mode=errusage
	fi
fi
case "$mode" in
	errusage)
		print "Try '%s --help' for more information." "${0##*/}" >&2
		exit $EXIT_INVALIDARGUMENT
		;;
	usage)
		usage
		exit $EXIT_SUCCESS
		;;
	run) : ;;
	*) panic 'invalid mode: %q' "$mode" ;;
esac

# Source makepkg.conf; fail if it is not found
if [[ -r '/etc/makepkg.conf' ]]; then
	# shellcheck source=makepkg-x86_64.conf
	source '/etc/makepkg.conf'
else
	die '/etc/makepkg.conf not found!'
fi

# Source user-specific makepkg.conf overrides
if [[ -r "${XDG_CONFIG_HOME:-$HOME/.config}/pacman/makepkg.conf" ]]; then
	# shellcheck source=/dev/null
	source "${XDG_CONFIG_HOME:-$HOME/.config}/pacman/makepkg.conf"
elif [[ -r "$HOME/.makepkg.conf" ]]; then
	# shellcheck source=/dev/null
	source "$HOME/.makepkg.conf"
fi

if [[ ! -f PKGBUILD ]]; then
	error 'This must be run in the directory of a built package.'
	usage >&2
	exit 1
fi

# shellcheck source=PKGBUILD.proto
. ./PKGBUILD
if [[ ${arch[0]} == 'any' ]]; then
	CARCH='any'
fi

STARTDIR=$(pwd)
TEMPDIR=$(mktemp -d --tmpdir checkpkg-script.XXXX)

for _pkgname in "${pkgname[@]}"; do
	target_pkgver=$(get_full_version "$_pkgname")
	if ! pkgfile=$(find_cached_package "$_pkgname" "$target_pkgver" "$CARCH"); then
		die 'tarball not found for package: %s' "${_pkgname}-$target_pkgver"
	fi

	ln -s "$pkgfile" "$TEMPDIR"

	pkgurl=$(pacman -Spdd --print-format '%l' --noconfirm "$_pkgname") ||
		die "Couldn't download previous package for %s." "$_pkgname"

	oldpkg=${pkgurl##*://*/}

	if [[ ${oldpkg##*/} = "${pkgfile##*/}" ]]; then
		die "The built package (%s) is the one in the repo right now!" "$_pkgname"
	fi

	if [[ $pkgurl = file://* ]]; then
		ln -s "${pkgurl#file://}" "$TEMPDIR/$oldpkg"
	elif [[ -f "$PKGDEST/$oldpkg" ]]; then
		ln -s "$PKGDEST/$oldpkg" "$TEMPDIR/$oldpkg"
	elif [[ -f "$STARTDIR/$oldpkg" ]]; then
		ln -s "$STARTDIR/$oldpkg" "$TEMPDIR/$oldpkg"
	else
		curl -fsLC - --retry 3 --retry-delay 3 -o "$TEMPDIR/$oldpkg" "$pkgurl"
	fi

	bsdtar tf "$TEMPDIR/$oldpkg" | sort > "$TEMPDIR/filelist-$_pkgname-old"
	bsdtar tf "$pkgfile" | sort > "$TEMPDIR/filelist-$_pkgname"

	sdiff -s "$TEMPDIR/filelist-$_pkgname-old" "$TEMPDIR/filelist-$_pkgname"

	find-libprovides "$TEMPDIR/$oldpkg" 2>/dev/null | sort > "$TEMPDIR/libraries-$_pkgname-old"
	find-libprovides "$pkgfile" 2>/dev/null | sort > "$TEMPDIR/libraries-$_pkgname"
	if ! diff_output="$(sdiff -s "$TEMPDIR/libraries-$_pkgname-old" "$TEMPDIR/libraries-$_pkgname")"; then
		msg "Sonames differ in $_pkgname!"
		echo "$diff_output"
	else
		msg "No soname differences for %s." "$_pkgname"
	fi
done

msg "Files saved to %s" "$TEMPDIR"
