#!/bin/sh

DEF_VER=v2.54.0-rc1

LF='
'

if test "$#" -lt 2 || test "$#" -gt 3
then
    echo >&2 "USAGE: $0 <SOURCE_DIR> (--format=<STRING>|<INPUT>) [<OUTPUT>]"
    exit 1
fi

SOURCE_DIR="$1"

case "$2" in
--format=*)
	INPUT="${2#--format=}"
	;;
*)
	if ! test -f "$2"
	then
		echo >&2 "Input is not a file: $2"
		exit 1
	fi
	INPUT=$(cat "$2")
	;;
esac

OUTPUT="$3"

# Protect us from reading Git version information outside of the Git directory
# in case it is not a repository itself, but embedded in an unrelated
# repository.
GIT_CEILING_DIRECTORIES="$SOURCE_DIR/.."
export GIT_CEILING_DIRECTORIES

if test -z "$GIT_VERSION"
then
	# First see if there is a version file (included in release tarballs),
	# then try git-describe, then default.
	if test -f "$SOURCE_DIR"/version
	then
		VN=$(cat "$SOURCE_DIR"/version) || VN="$DEF_VER"
	elif {
			test -d "$SOURCE_DIR/.git" ||
			test -d "${GIT_DIR:-.git}" ||
			test -f "$SOURCE_DIR"/.git;
		} &&
		VN=$(git -C "$SOURCE_DIR" describe --dirty --match="v[0-9]*" 2>/dev/null) &&
		case "$VN" in
		*$LF*) (exit 1) ;;
		esac
	then
		VN=$(echo "$VN" | sed -e 's/-/./g');
	else
		VN="$DEF_VER"
	fi

	GIT_VERSION=$(expr "$VN" : v*'\(.*\)')
fi

if test -z "$GIT_BUILT_FROM_COMMIT"
then
	GIT_BUILT_FROM_COMMIT=$(git -C "$SOURCE_DIR" rev-parse -q --verify HEAD 2>/dev/null)
fi

if test -z "$GIT_DATE"
then
	GIT_DATE=$(git -C "$SOURCE_DIR" show --quiet --format='%as' 2>/dev/null)
fi

if test -z "$GIT_USER_AGENT"
then
	GIT_USER_AGENT="git/$GIT_VERSION"
fi

# While released Git versions only have three numbers, development builds also
# have a fourth number that corresponds to the number of patches since the last
# release.
read GIT_MAJOR_VERSION GIT_MINOR_VERSION GIT_MICRO_VERSION GIT_PATCH_LEVEL trailing <<EOF
$(echo "$GIT_VERSION" 0 0 0 0 | tr '.a-zA-Z-' ' ')
EOF

REPLACED=$(printf "%s\n" "$INPUT" | sed -e "s|@GIT_VERSION@|$GIT_VERSION|" \
	-e "s|@GIT_MAJOR_VERSION@|$GIT_MAJOR_VERSION|" \
	-e "s|@GIT_MINOR_VERSION@|$GIT_MINOR_VERSION|" \
	-e "s|@GIT_MICRO_VERSION@|$GIT_MICRO_VERSION|" \
	-e "s|@GIT_PATCH_LEVEL@|$GIT_PATCH_LEVEL|" \
	-e "s|@GIT_BUILT_FROM_COMMIT@|$GIT_BUILT_FROM_COMMIT|" \
	-e "s|@GIT_USER_AGENT@|$GIT_USER_AGENT|" \
	-e "s|@GIT_DATE@|$GIT_DATE|"
)

if test -z "$OUTPUT"
then
	printf "%s\n" "$REPLACED"
else
	printf "%s\n" "$REPLACED" >"$OUTPUT".$$+
	if ! test -f "$OUTPUT" || ! cmp "$OUTPUT".$$+ "$OUTPUT" >/dev/null
	then
		mv "$OUTPUT".$$+ "$OUTPUT"
	else
		rm "$OUTPUT".$$+
	fi
fi
