#!/bin/sh

# Rebuild the Freight cache from the Freight library.  The cache contains
# actual repositories that are suitable targets for `apt-get` (and maybe
# more in the future).

#/ Usage: freight cache [-k] [-g <email>] [-p <passphrase-file>] [-c <conf>] [-v] [-h] [<manager>/<distro>][...]
#/   -k, --keep                          keep unreferenced versions of packages
#/   -g <email>, --gpg=<email>           GPG key to use
#/   -p <passphrase file>, 
#/   --passphrase-file=<passphrase-file> path to file containing the passphrase of the GPG key
#/   -c <conf>, --conf=<conf>            config file to parse
#/   -v, --verbose                       verbose mode
#/   -h, --help                          show this help message

set -e

usage() {
	grep "^#/" "$0" | cut -c"4-" >&2
	exit "$1"
}
while [ "$#" -gt 0 ]
do
	case "$1" in
		-k|--keep) KEEP=1 shift;;
		-g|--gpg) GPG="$2" shift 2;;
		-g*) GPG="$(echo "$1" | cut -c"3-")" shift;;
		--gpg=*) GPG="$(echo "$1" | cut -c"7-")" shift;;
		-p|--passphrase-file) GPG_PASSPHRASE_FILE="$2" shift 2;;
		-p*) GPG_PASSPHRASE_FILE="$(echo "$1" | cut -c"3-")" shift;;
		--passphrase-file=*) GPG_PASSPHRASE_FILE="$(echo "$1" | cut -c"19-")" shift;;
		-c|--conf) CONF="$2" shift 2;;
		-c*) CONF="$(echo "$1" | cut -c"3-")" shift;;
		--conf=*) CONF="$(echo "$1" | cut -c"8-")" shift;;
		-v|--verbose) VERBOSE=1 shift;;
		-h|--help) usage 0;;
		-*) echo "# [freight] unknown switch: $1" >&2;;
		*) break;;
	esac
done

LIB="$(cd "$(dirname "$(dirname "$0")")/share/freight" && pwd)"
. "$LIB/conf.sh"

# If `GPG_PASSPHRASE_FILE` is set the specified file should exist and be
# readable by the user running Freight.
[ -z "$GPG_PASSPHRASE_FILE" -o -r "$GPG_PASSPHRASE_FILE" ] || echo "# [freight] could not read passphrase file: $GPG_PASSPHRASE_FILE." >&2

# Create a working directory on the same device as the Freight cache.
mkdir -p "$VARCACHE"
TMP="$(mktemp -d "$VARCACHE/work.$$.XXXXXXXXXX")"
trap "rm -rf \"$TMP\"" EXIT INT TERM

# Enter the Freight library directory so that items in `$@` may be given as
# absolute paths or as partial paths of the form `<manager>/<distro>` that
# are ultimately taken relative to the Freight library.
mkdir -p "$VARLIB"
cd "$VARLIB"

# Rebuild each distro serially.
if [ -z "$*" ]
then
	DIRS="$(
		find "$VARLIB" -mindepth 2 -maxdepth 2 -type d -printf "%P\n" |
		grep -v "^\\." |
		tr "\n" " "
	)"
else
	DIRS="$@"
fi
for DIR in $DIRS
do

	# Parse the manager and distro out of the Freight library path.
	DIR="$(readlink -f "$DIR")"
	DIR="${DIR##"$VARLIB/"}"
	MANAGER="$(dirname "$DIR")"
	DIST="$(basename "$DIR")"

	# Should we follow symbolic links when finding components to cache?
	[ "$SYMLINKS" = "on" ] && FIND_L="-L" || FIND_L=""

	# From here the process is customized on a per-manager basis.  The
	# sorted list of package filenames comes on `stdin` and the name of
	# the distro is the only argument.  From there, each manager can do
	# whatever it wants.
	. "$LIB/$MANAGER.sh"
	SORT="$(sort -V <"/dev/null" 2>"/dev/null" && echo "sort -V" || echo "sort")"
	find $FIND_L "$DIR" -type "f" -printf "%P\n" 2>"/dev/null" |
	eval "$SORT" |
	eval "${MANAGER}_cache" "$DIST"

	# Clean up old packages as dictated by the manager.
	[ -z "$KEEP" ] && eval "${MANAGER}_clean"

done
