#!/bin/bash
#  Licensed to the Apache Software Foundation (ASF) under one
#  or more contributor license agreements.  See the NOTICE file
#  distributed with this work for additional information
#  regarding copyright ownership.  The ASF licenses this file
#  to you under the Apache License, Version 2.0 (the
#  "License"); you may not use this file except in compliance
#  with the License.  You may obtain a copy of the License at

#     http://www.apache.org/licenses/LICENSE-2.0

#  Unless required by applicable law or agreed to in writing,
#  software distributed under the License is distributed on an
#  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
#  KIND, either express or implied.  See the License for the
#  specific language governing permissions and limitations
#  under the License.

###############################################################################
# In most cases just execute ./changelog.sh should suffice.
#
# To tune commiter names/remove dups, adjust the .mailmap file
# (see https://git-scm.com/docs/gitmailmap)
###############################################################################

TAG_SEARCH=spifly*
WORK_DIR=.
CHANGELOG=${WORK_DIR}/changelog.md

###############################################################################
############# Do not edit below ###############################################
###############################################################################

# collect all the tags that match our pattern and reverse the order
ALL_TAGS=( $(git tag -l $TAG_SEARCH | xargs -n 1 | tac) )
PREVIOUS_TAG="${ALL_TAGS[0]}"
TAGS=${ALL_TAGS[@]:1}

if [ -f $CHANGELOG ]; then
    UPDATE=$PREVIOUS_TAG
fi

while (( "$#" )); do
	case "$1" in
		-u|--update-changelog)
			if [ -n "$2" ] && [ ${2:0:1} != "-" ]; then
				UPDATE=$2
				shift 2
			else
				echo "Error: Tag for $1 is missing" >&2
				exit 1
			fi
			;;
		-*|--*=) # unsupported flags
			echo "Error: Unsupported flag $1" >&2
			exit 1
			;;
		*) # preserve positional arguments
			shift
			;;
	esac
done

if [ -v UPDATE ]; then
	printf "Updating $CHANGELOG\n"
	# update the file if asked (appends to head of file)

	# read the first tag in the existing changelog
	line=$(head -n 1 $CHANGELOG)
	TAGS=("${line#\#\# }")

	# set the previous tag to the passed argument
	PREVIOUS_TAG=$UPDATE
	printf "Collecting changes from $TAGS to $PREVIOUS_TAG\n"

	# swap the changelog for a temp file
	ORIGINAL_FILE=$CHANGELOG
	CHANGELOG="$CHANGELOG.tmp"
else
	printf "Creating $CHANGELOG\n"
fi

# create the file if it doesn't exist
printf "" > $CHANGELOG

# write the changelog
for tag in $TAGS; do
	RESULT=$(git --no-pager shortlog --no-merges --grep 'maven-release-plugin' --invert-grep --format="- %s [%h]" -w0,2 -nc $tag..$PREVIOUS_TAG $WORK_DIR)

	if [[ ! -z "${RESULT// }" ]]; then
			echo "## $PREVIOUS_TAG" >> $CHANGELOG
			echo "$RESULT" >> $CHANGELOG
			echo "" >> $CHANGELOG
	fi

	PREVIOUS_TAG=$tag
done

if [ -v UPDATE ]; then
	# append the changelog to the end of temp
	cat $ORIGINAL_FILE >> $CHANGELOG

	# move the changelog temp over the changelog
	mv -f $CHANGELOG $ORIGINAL_FILE
fi
