#!/usr/bin/env bash
# encoding: utf-8

# Handle release process
# Updates the VERSION.txt file and creates the tag

set -Eeuo pipefail

# Current Git branch
branch=$(git branch --show-current)

# Require master
if [[ "$branch" != "master" ]]; then
    echo "Not in master exiting"
    exit 1
fi

# Require the current working directory to be clean
if [[ -n "$(git status --porcelain)" ]]; then
    echo "Git repository is not clean exiting"
    exit 1
fi

# Require the version file
if [[ ! -f "VERSION.txt" ]]; then
    echo "VERSION.txt file not found exiting"
    exit 1
fi

# Parse the version file
major=$(grep "VERSION_MAJOR" VERSION.txt | cut -d" " -f2)
minor=$(grep "VERSION_MINOR" VERSION.txt | cut -d" " -f2)
patch=$(grep "VERSION_PATCH" VERSION.txt | cut -d" " -f2)
version_changed=
version_message=
gpg_sign=

parse_params() {
    while :; do
        case "${1-}" in
        -v | --verbose) set -x ;;
        --major)
            major=$((major + 1))
            minor=0
            patch=0
            version_changed=true
            ;;
        --minor)
            minor=$((minor + 1))
            patch=0
            version_changed=true
            ;;
        --patch)
            patch=$((patch + 1))
            version_changed=true
            ;;
        --sign)
            gpg_sign=true
            ;;
        -m | --message)
            version_message="${2-}"
            shift
            ;;
        -?*)
            echo "Unknown option: $1"
            exit 1
            ;;
        *) break ;;
        esac
        shift
    done

    return 0
}

parse_params "$@"

# If nothing has changed then just exit
if [[ -z $version_changed ]]; then
    echo "Nothing to do"
    exit 0
fi

# Sorry tag is already taken.
if [[ -n "$(git tag -l "v$major.$minor.$patch")" ]]; then
    echo "Tag 'v$major.$minor.$patch' was taken"
    exit 1
fi

if [[ "$patch" = 0 ]] && [[ -n "$(git tag -l "v$major.$minor")" ]]; then
    echo "Tag 'v$major.$minor' was taken"
    exit 1
fi

if [[ -z "$version_message" ]]; then
    version_message="Version $major.$minor.$patch"
fi

echo "Ready to commit and tag a new version: $major.$minor.$patch"
echo "Version message will be: $version_message"
read -p "Ready to commit? [Y/N]: " -n 1 -r
echo
if [[ $REPLY =~ ^[Yy]$ ]]; then
    # Update the version file.
    perl -pi -e "s/(VERSION_MAJOR)\s+[0-9]+/\1 $major/g" VERSION.txt
    perl -pi -e "s/(VERSION_MINOR)\s+[0-9]+/\1 $minor/g" VERSION.txt
    perl -pi -e "s/(VERSION_PATCH)\s+[0-9]+/\1 $patch/g" VERSION.txt

    if [[ -n "$gpg_sign" ]]; then
        echo "Create a SIGNED release"

        # Create a SIGNED release commit
        git commit -a -S -m "Incrementing version number to $major.$minor.$patch"

        # Tag it like a champ!
        git tag -s "v$major.$minor.$patch" -m "$version_message"
    else
        echo "Create an UNSIGNED release"

        # Create an UNSIGNED release commit
        git commit -am "Incrementing version number to $major.$minor.$patch"

        # Create an UNSIGNED tag
        git tag -a "v$major.$minor.$patch" -m "$version_message"
    fi

    echo "Committed and tagged a new release"

    read -p "Enter the name of the upstream remote (default: origin): " upstream -r
    upstream=${upstream:-origin}

    read -p "Push commit and tag to remote '$upstream'? [Y/N]: " -n 1 -r
    echo
    if [[ $REPLY =~ ^[Yy]$ ]]; then
        git push "$upstream" HEAD
        git push "$upstream" "$major.$minor.$patch"
        echo "Pushed data to remote '$upstream'. Congrats!"
    else
        echo "You need to 'git push $upstream HEAD' and 'git push $upstream --tags' manually."
    fi
else
    echo "Chicken!"
fi
