#
# git-flow -- A collection of Git extensions to provide high-level
# repository operations for Vincent Driessen's branching model.
#
# Original blog post presenting this model is found at:
#    http://nvie.com/git-model
#
# Feel free to contribute to this project at:
#    http://github.com/nvie/gitflow
#
# Copyright 2010 Vincent Driessen. All rights reserved.
# 
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are met:
# 
#    1. Redistributions of source code must retain the above copyright notice,
#       this list of conditions and the following disclaimer.
# 
#    2. Redistributions in binary form must reproduce the above copyright
#       notice, this list of conditions and the following disclaimer in the
#       documentation and/or other materials provided with the distribution.
# 
# THIS SOFTWARE IS PROVIDED BY VINCENT DRIESSEN ``AS IS'' AND ANY EXPRESS OR
# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
# MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
# EVENT SHALL VINCENT DRIESSEN OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
# INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
# OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
# NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
# EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
# 
# The views and conclusions contained in the software and documentation are
# those of the authors and should not be interpreted as representing official
# policies, either expressed or implied, of Vincent Driessen.
#

require_git_repo
require_gitflow_initialized
gitflow_load_settings
VERSION_PREFIX=$(eval "echo `git config --get gitflow.prefix.versiontag`")
PREFIX=$(git config --get gitflow.prefix.support)

warn "note: The support subcommand is still very EXPERIMENTAL!"
warn "note: DO NOT use it in a production situation."

usage() {
	echo "usage: git flow support [list] [-v]"
	echo "       git flow support start [-F] <version> <base>"
}

cmd_default() {
	cmd_list "$@"
}

cmd_list() {
	DEFINE_boolean verbose false 'verbose (more) output' v
	parse_args "$@"

	local support_branches
	local current_branch
	local short_names
	support_branches=$(echo "$(git_local_branches)" | grep "^$PREFIX")
	if [ -z "$support_branches" ]; then
		warn "No support branches exist."
                warn ""
                warn "You can start a new support branch:"
                warn ""
                warn "    git flow support start <name> <base>"
                warn ""
		exit 0
	fi
	current_branch=$(git branch --no-color | grep '^\* ' | grep -v 'no branch' | sed 's/^* //g')
	short_names=$(echo "$support_branches" | sed "s ^$PREFIX  g")

	# determine column width first
	local width=0
	local branch
	for branch in $short_names; do
		local len=${#branch}
		width=$(max $width $len)
	done
	width=$(($width+3))

	local branch
	for branch in $short_names; do
		local fullname=$PREFIX$branch
		local base=$(git merge-base "$fullname" "$MASTER_BRANCH")
		local master_sha=$(git rev-parse "$MASTER_BRANCH")
		local branch_sha=$(git rev-parse "$fullname")
		if [ "$fullname" = "$current_branch" ]; then
			printf "* "
		else
			printf "  "
		fi
		if flag verbose; then
			printf "%-${width}s" "$branch"
			if [ "$branch_sha" = "$master_sha" ]; then
				printf "(no commits yet)"
			else
				local tagname=$(git name-rev --tags --no-undefined --name-only "$base")
				local nicename
				if [ "$tagname" != "" ]; then
					nicename=$tagname
				else
					nicename=$(git rev-parse --short "$base")
				fi
				printf "(based on $nicename)"
			fi
		else
			printf "%s" "$branch"
		fi
		echo
	done
}

cmd_help() {
	usage
	exit 0
}

parse_args() {
	# parse options
	FLAGS "$@" || exit $?
	eval set -- "${FLAGS_ARGV}"

	# read arguments into global variables
	VERSION=$1
	BASE=$2
	BRANCH=$PREFIX$VERSION
}

require_version_arg() {
	if [ "$VERSION" = "" ]; then
		warn "Missing argument <version>"
		usage
		exit 1
	fi
}

require_base_arg() {
	if [ "$BASE" = "" ]; then
		warn "Missing argument <base>"
		usage
		exit 1
	fi
}

require_base_is_on_master() {
	if ! git branch --no-color --contains "$BASE" 2>/dev/null \
			| sed 's/[* ] //g' \
	  		| grep -q "^$MASTER_BRANCH\$"; then
		die "fatal: Given base '$BASE' is not a valid commit on '$MASTER_BRANCH'."
	fi
}

cmd_start() {
	DEFINE_boolean fetch false "fetch from $ORIGIN before performing finish" F
	parse_args "$@"
	require_version_arg
	require_base_arg
	require_base_is_on_master

	# sanity checks
	require_clean_working_tree

	# fetch remote changes
	if flag fetch; then
		git fetch -q "$ORIGIN" "$BASE"
	fi
	require_branch_absent "$BRANCH"

	# create branch
	git checkout -b "$BRANCH" "$BASE"

	echo
	echo "Summary of actions:"
	echo "- A new branch '$BRANCH' was created, based on '$BASE'"
	echo "- You are now on branch '$BRANCH'"
	echo
}
