#!/bin/bash

function usage() {
	echo 'usage: --major | -M | --minor | -m | --patch | -p'
	exit 1
}

function setCommand() {
	#arg1 input, #arg2 return value
	declare -n ret=$2

	case $1 in
	-M | --major)
		ret='major'
		;;
	-m | --minor)
		ret='minor'
		;;
	-p | --patch)
		ret='patch'
		;;
	--help)
		usage
		;;
	*) # unknown option
		echo
		echo 'unknown option, quitting'
		echo
		usage
		;;
	esac
}

############# main

# check git covered
REPOSITORY=$(git config --get remote.origin.url)
if [[ "$?" -ne 0 ]]; then
	echo 'no remote origin defined yet, please perform: git remote add'
	exit 1
fi

# check if dirty status
changed=$(git status -s | wc -l)
if [[ ! $changed -eq 0 ]]; then
	echo "git commit required, please do so before processing further"
	exit 2
fi

git remote update
pulled_needed=$(git status -s -u no | wc -l)
if [[ ! $changed -eq 0 ]]; then
	echo "git pull required, please do so before processing further"
	exit 3
fi

current_branch=$(git rev-parse --abbrev-ref HEAD)
# check if push needed before tagging
push_needed=$(git rev-list --branches --not --remotes | wc -l)
if [[ $push_needed -ne 0 ]]; then
	echo 'git push needed'
	git push --set-upstream origin "$current_branch"
	echo 'git push done'
	echo '-------------'
fi

# check latest tagged version
LAST_TAG=$(git rev-list --tags --max-count=1 2>/dev/null)
if [[ $? -eq 0 && -n "$LAST_TAG" ]]; then
	echo "LAST=${LAST_TAG}"
	VERSION=$(git describe --tags $LAST_TAG)
else
	echo 'not yet tagged!'
	VERSION=0.0.0
fi

# split into array
VERSION_BITS=(${VERSION//./ })
MAJOR=${VERSION_BITS[0]:=0}
MINOR=${VERSION_BITS[1]:=0}
PATCH=${VERSION_BITS[2]:=0}

REPO_NAME=$(basename $REPOSITORY)
REPO_NAME=${REPO_NAME%.git}
if [[ $VERSION != '0.0.0' ]]; then
	echo "LATEST VERSION of '$REPO_NAME' is '$MAJOR.$MINOR.$PATCH'"
	COMMIT_ID=$(git log --format="%H" -n 1)
	if [[ $COMMIT_ID == $LAST_TAG ]]; then
		echo "cannot tag twice the same commit id : $LAST_TAG"
		exit 1
	fi
fi

COMMAND="${1:-ask}"
if [[ $COMMAND == 'ask' ]]; then
	echo -n "Press 'M' for Major, 'm' for minor, 'p' for patch ? "
	read -n1 input
	echo
	COMMAND="-$input"
fi

setCommand $COMMAND COMMAND

echo "before case"
case $COMMAND in
"major")
	let "MAJOR++"
	let "MINOR=0"
	let "PATCH=0"
	;;
"minor")
	let "MINOR++"
	let "PATCH=0"
	;;
"patch")
	let "PATCH++"
	;;
esac

echo "show TAG"
TAG="$MAJOR.$MINOR.$PATCH"
echo "new TAG $TAG"

# check if tag exists already!
if [[ -n $(git tag -l $TAG) ]]; then
	echo "WARNING: ${TAG} already exists!"
	exit 4
fi

# check whether NPM project detected, containing package.json on root project
GIT_ROOT_FOLDER=$(dirname $(git rev-parse --git-dir))
if [[ -f "${GIT_ROOT_FOLDER}/package.json" ]]; then

	echo "package.json detected, version replaced with new tag <${TAG}>"
	if ! command -v yq &>/dev/null; then
		echo 'command <yq> not found, hint: go and fetch latest release from https://github.com/mikefarah/yq'
		exit 5
	fi

	yq -i ".version=\"$TAG\"" "${GIT_ROOT_FOLDER}/package.json"
	git add ${GIT_ROOT_FOLDER}/package.json
fi

echo $TAG >${GIT_ROOT_FOLDER}/.semver_git_tag
git add ${GIT_ROOT_FOLDER}/.semver_git_tag
echo "tagging as $TAG ..."
git commit -am "tagged as ${TAG}"
git tag $TAG
git push origin "$current_branch" --tags
echo "done"
