#!/bin/sh
#
# SPDX-FileCopyrightText: StorPool <support@storpool.com>
# SPDX-License-Identifier: BSD-2-Clause

set -e

usage()
{
	cat <<EOUSAGE
Usage:	git-if-needed command /path/to/file.patch
	git-if-needed [-S] -s /path/to/series command

Options:
	-S	short paths: only use the last component of the patch path
	-s	series file: apply all the patches in that file

Examples:
	git if-needed am /path/to/local.patch
	git if-needed -s /path/to/many-patches/series am
EOUSAGE
}

apply_single()
{
	local cmd="$1" fname="$2"

	if [ ! -e "$fname" ] || [ ! -f "$fname" ] || [ ! -r "$fname" ]; then
		echo "Not a readable regular file: $fname" 1>&2
		exit 1
	fi

	local chgid=''
	chgid="$(awk -- '/^[[:space:]]*Change-Id:[[:space:]]+I[0-9a-f]+$/ { print $2 }' "$fname")"
	if ! expr "x$chgid" : 'xI[0-9a-f][0-9a-f]*$' > /dev/null; then
		echo "Expected a single Change-Id line in $fname" 1>&2
		exit 1
	fi

	if git --no-pager log | grep -Eqe "^[[:space:]]+Change-Id:[[:space:]]+${chgid}\$"; then
		echo "# Change $chgid already present in the Git history"
	elif git --no-pager "$cmd" -- "$fname"; then
		echo "# 'git $cmd $fname' succeeded"
	else
		echo "# 'git $cmd $fname' failed"
		git --no-pager status || echo "# 'git status' also failed"
		exit 1
	fi
}

apply_series()
{
	local cmd="$1" series="$2" short="$3"

	series="$(readlink -f -- "$series")"
	series_dir="$(dirname -- "$series")"
	curdir="$(readlink -f .)"

	while read -r filename; do
		dirname="$(dirname -- "$filename")"
		if [ -n "$short" ]; then
			dirname="$(basename -- "$dirname")"
		fi

		cd -- "$dirname"
		apply_single "$cmd" "$series_dir/$filename"
		cd -- "$curdir"
	done < "$series"
}

unset series short
while getopts 'Ss:' o; do
	case "$o" in
		S)
			short=1
			;;

		s)
			series="$OPTARG"
			;;

		*)
			usage 1>&2
			exit 1
			;;
	esac
done

shift "$((OPTIND - 1))"

if [ -n "$series" ]; then
	if [ "$#" -ne 1 ]; then
		usage 1>&2
		exit 1
	fi

	cmd="$1"
	apply_series "$cmd" "$series" "$short"
	exit 0
fi

if [ "$#" -ne 2 ]; then
	usage 1>&2
	exit 1
fi
cmd="$1"
fname="$2"

apply_single "$cmd" "$fname"
