#!/usr/bin/env bash
# SPDX-FileCopyrightText: 2023 Linnea Gräf <nea@nea.moe>
#
# SPDX-License-Identifier: GPL-3.0-or-later
#
# ARG_OPTIONAL_BOOLEAN([no-check],[n],[Skip checking preconditions, such as a clean git working directory])
# ARG_OPTIONAL_BOOLEAN([no-test],[t],[Skip running gradle tests.])
# ARG_OPTIONAL_BOOLEAN([dry],[d],[Dry run])
# ARG_HELP([Script to help creating releases])
# ARGBASH_GO()
# needed because of Argbash --> m4_ignore([
### START OF CODE GENERATED BY Argbash v2.10.0 one line above ###
# Argbash is a bash code generator used to get arguments parsing right.
# Argbash is FREE SOFTWARE, see https://argbash.io for more info


die()
{
	local _ret="${2:-1}"
	test "${_PRINT_HELP:-no}" = yes && print_help >&2
	echo "$1" >&2
	exit "${_ret}"
}


begins_with_short_option()
{
	local first_option all_short_options='ntdh'
	first_option="${1:0:1}"
	test "$all_short_options" = "${all_short_options/$first_option/}" && return 1 || return 0
}

# THE DEFAULTS INITIALIZATION - OPTIONALS
_arg_no_check="off"
_arg_no_test="off"
_arg_dry="off"


print_help()
{
	printf '%s\n' "Script to help creating releases"
	printf 'Usage: %s [-n|--(no-)no-check] [-t|--(no-)no-test] [-d|--(no-)dry] [-h|--help]\n' "$0"
	printf '\t%s\n' "-n, --no-check, --no-no-check: Skip checking preconditions, such as a clean git working directory (off by default)"
	printf '\t%s\n' "-t, --no-test, --no-no-test: Skip running gradle tests. (off by default)"
	printf '\t%s\n' "-d, --dry, --no-dry: Dry run (off by default)"
	printf '\t%s\n' "-h, --help: Prints help"
}


parse_commandline()
{
	while test $# -gt 0
	do
		_key="$1"
		case "$_key" in
			-n|--no-no-check|--no-check)
				_arg_no_check="on"
				test "${1:0:5}" = "--no-" && _arg_no_check="off"
				;;
			-n*)
				_arg_no_check="on"
				_next="${_key##-n}"
				if test -n "$_next" -a "$_next" != "$_key"
				then
					{ begins_with_short_option "$_next" && shift && set -- "-n" "-${_next}" "$@"; } || die "The short option '$_key' can't be decomposed to ${_key:0:2} and -${_key:2}, because ${_key:0:2} doesn't accept value and '-${_key:2:1}' doesn't correspond to a short option."
				fi
				;;
			-t|--no-no-test|--no-test)
				_arg_no_test="on"
				test "${1:0:5}" = "--no-" && _arg_no_test="off"
				;;
			-t*)
				_arg_no_test="on"
				_next="${_key##-t}"
				if test -n "$_next" -a "$_next" != "$_key"
				then
					{ begins_with_short_option "$_next" && shift && set -- "-t" "-${_next}" "$@"; } || die "The short option '$_key' can't be decomposed to ${_key:0:2} and -${_key:2}, because ${_key:0:2} doesn't accept value and '-${_key:2:1}' doesn't correspond to a short option."
				fi
				;;
			-d|--no-dry|--dry)
				_arg_dry="on"
				test "${1:0:5}" = "--no-" && _arg_dry="off"
				;;
			-d*)
				_arg_dry="on"
				_next="${_key##-d}"
				if test -n "$_next" -a "$_next" != "$_key"
				then
					{ begins_with_short_option "$_next" && shift && set -- "-d" "-${_next}" "$@"; } || die "The short option '$_key' can't be decomposed to ${_key:0:2} and -${_key:2}, because ${_key:0:2} doesn't accept value and '-${_key:2:1}' doesn't correspond to a short option."
				fi
				;;
			-h|--help)
				print_help
				exit 0
				;;
			-h*)
				print_help
				exit 0
				;;
			*)
				_PRINT_HELP=yes die "FATAL ERROR: Got an unexpected argument '$1'" 1
				;;
		esac
		shift
	done
}

parse_commandline "$@"

# OTHER STUFF GENERATED BY Argbash

### END OF CODE GENERATED BY Argbash (sortof) ### ])
# [ <-- needed because of Argbash
set -euo pipefail

REMOTE=origin

basedir="$(dirname "$(dirname "$(realpath "$0")")")"
echo "Found base directory at $basedir"

if ! [ -d "$basedir/.git" ]; then
    echo Could not find git directory.
    exit 1
fi

if ! "${JAVA_HOME}"/bin/java -version 2>&1 | grep 'version "21.'>/dev/null && [ "$_arg_no_check" == off ]; then
    echo Wrong java version
    exit 1
fi

if [ -n "$(git status --porcelain)" ] && [ "$_arg_no_check" == off ]; then
    echo Unclean git working environment
    exit 1
fi

current_branch="$(git rev-parse --abbrev-ref HEAD)"

if ! [[ "$current_branch" = "master" ]] && ! [[ "$current_branch" = mc-* ]]; then
    echo "Not on branch master or a mc- branch."
    exit 1
fi

git fetch --tags "$REMOTE"

git tag --list --sort=v:refname

oldversion="$(git describe --tags --abbrev=0|tr -d '\n')"

echo "Choosing old version as $oldversion"

# TODO: auto choose next version based on a command line flag: --minor --hotfix --major as well as minecraft info from libs.versions.toml
echo -n "Choosing next version as: "
read newversion

if ! [[ "$newversion" = *+mc* ]] && [ "$_arg_no_check" == off ]; then
	echo "Illegal next version $newversion. Please use a.b.c+mcx.y.z"
	exit 1
fi

echo "Confirming new version as $newversion"

if [ "$_arg_dry" == off ]; then
	echo Committing release commit
	git commit --allow-empty -m 'Prepare release '"$newversion"'

[no changelog]'
	echo Tagging release commit
    git tag "$newversion"
fi
mkdir -p "$basedir/.gradle"
releasenotes="$basedir/.gradle/releasenotes.md"

comparetag="$(
if [ "$_arg_dry" == off ]; then
	echo "$newversion"
else
	echo "HEAD"
fi)"

echo Building release notes
echo "**Full Changelog**: <https://github.com/nea89o/Firmament/compare/$oldversion...$comparetag>" > "$releasenotes"
echo >> "$releasenotes"
git log --pretty='- %s' --grep '[no changelog]' --invert-grep --fixed-strings "$oldversion..$comparetag" | tac >> "$releasenotes"
echo >> "$releasenotes"

echo Check Release notes:
echo ----------------------------------------------
cat "$releasenotes"
echo ----------------------------------------------
echo Press Enter to resume
read

echo Building JAR
"$basedir"/gradlew --stop
if [ "$_arg_no_test" == off ]; then
	echo Building and testing
	"$basedir"/gradlew clean build
else
	echo Building without testing
	"$basedir"/gradlew clean assemble
fi

echo Release notes:
echo ----------------------------------------------
cat "$releasenotes"
echo ----------------------------------------------

if [ "$_arg_dry" == off ]; then
	echo Pushing to github
	git push "$REMOTE" "HEAD" "$newversion"
	if command -v gh; then
        echo Creating github release
        (set -x; gh release create -t "Firmament $newversion" "$newversion" -F "$releasenotes" "$basedir/build/libs/Firmament-$newversion.jar")
    else
        echo Could not find github command utility. Opening github releases
        xdg-open "https://github.com/nea89o/firmament/releases/new"
    fi
fi

echo Opening modrinth releases
xdg-open "https://modrinth.com/mod/firmament/versions"

echo "Don't forget to upload a discord release as well:"

# ] <-- needed because of Argbash
