#!/bin/sh

readonly PAGER=${PAGER:-less}
readonly PAGER_DIFF=${PAGER_DIFF:-$PAGER}
readonly PKGNAME=$(make -V PKGNAME 2>/dev/null)
readonly PLIST=$(make -V PLIST 2>/dev/null)

display_usage() {
	<< EOF >&2 cat
Usage: ${0##*/} -h
       ${0##*/} [-s <subname>]

    -h show this help
    -s insert new entries with %%subname%% prefix

EOF
	exit 1
}

awk_args="-v plist_file=$PLIST"

while getopts "hs:" option; do
	case $option in
	s)
		awk_args="$awk_args -v subname=$OPTARG" ;;
	*)
		display_usage
	esac
done

if ! which plist-sort >/dev/null; then
	echo "===> Required script plist-sort not found" >&2
	exit 1
fi

if [ ! "$PKGNAME" ]; then
	echo "===> This is not port directory" >&2
	exit 1
fi

tempfile=$(mktemp -t "${0##*/}")
if [ ! "$tempfile" ]; then
	echo "===> Failed to create temporary file" >&2
	exit 1
fi
if [ -f "$PLIST" ]; then
	wrkdir=$(make -V WRKDIR)
	plist_out="$wrkdir/.pkg-plist.new"
else
	plist_out="$PLIST"
fi

options_subs="PORTDOCS PORTEXAMPLES"
for sub in $(make -V PLIST_SUB); do
	case $sub in *@comment*)
		case $sub in NO_*) sub=${sub##NO_}; esac
		options_subs="$options_subs ${sub%%=*}"
	esac
done

make check-plist 2>&1 | awk $awk_args -v options_subs="$options_subs" \
	-v plist_subs="$(make -V PLIST_SUB)" '
BEGIN {
	# blacklisted plist subs that should
	# not be in final version of new plist
	subs_blacklist["QT_BINDIR"] = "bin";
	subs_blacklist["QT_LIBDIR"] = "lib";

	n = split(options_subs, s_array, " ");
	for (i=1; i<=n; i++)
		opt_subs[s_array[i]] = s_array[i];

	n = split(plist_subs, array, " ");
	for (pair=1; pair<=n; pair++) {
		if (split(array[pair], p_array, "=") != 2)
			continue;

		if (p_array[1] in opt_subs)
			continue;

		gsub("\"", "", p_array[2]);
		if (p_array[2] && p_array[2] != "@comment")
			subs[p_array[1]] = p_array[2];
	}
	if (plist_file) {
		while ((getline line < plist_file) > 0) {
			if (match(line, "@\(dir|sample\)") ||
			    match(line, "@\\(.*\\)")) {
				plist_split(substr(line, RSTART), p);
				plist[ no_subs_path(p[2]) ] = line;
			} else
				plist[ no_subs_path(line) ] = line;
		}
		close(plist_file);
	}
	if (subname)
		subname = "%%" subname "%%";
}

function get_plist_path() {
	$1 = $2 = "";
	if ($3 == "@dir")
		$3 = "";

	sub("^ *", "", $0);
	return $0;
}

function no_subs_path(path) {
	new_path = "";

	if ((n = split(path, array, "%%")) == 1)
		return path;

	for (i=1; i<=n; i++) {
		if (array[i] in opt_subs)
			continue;

		if (array[i] in subs) {
			new_path = new_path subs[array[i]];
			continue;
		}
		new_path = new_path array[i];
	}
	return new_path;
}

function plist_split(string, array) {
	n = index(string, " ");
	array[1] = substr(string, 1, n-1);
	array[2] = substr(string, n+1);
}

function remove_blacklisted_subs(path) {
	if ((n = split(path, array, "%%")) == 1)
		return path;

	for (i=1; i<=n; i++) {
		if (array[i] in subs_blacklist &&
		    subs_blacklist[array[i]] == subs[array[i]])
			sub("%%" array[i] "%%", subs[array[i]], path);
	}
	return path;
}

/^Error: Missing:/ {
	path = get_plist_path();
	path = no_subs_path(path);

	if (path in plist)
		delete plist[path];
}

/^Error: Orphaned:/ {
	dir = ($3 == "@dir") ? "@dir " : "";
	path = get_plist_path();
	ns_path = no_subs_path(path);

	if (ns_path in plist == 0) {
		path = remove_blacklisted_subs(path);
		plist[ns_path] = subname dir path;
	}
}

END {
	for (file in plist)
		print plist[file];
}' > "$tempfile"

plist-sort "$tempfile" > "$plist_out"
rm "$tempfile"
[ "$plist_out" = "$PLIST" ] && exit 0

if ! cmp -s "$PLIST" "$plist_out"; then
	diff -u "$PLIST" "$plist_out" | $PAGER_DIFF

	while true; do
		read -r -p "Use newly generated plist (y/n)? " cmd
		case $cmd in
		[Yy])
			mv "$plist_out" "$PLIST"
			exit 0 ;;
		[Nn])
			break
		esac
	done
fi
