# -*- shell-script -*-
#
# Bash tab auto-completion rules for git-buildpackage.
#
# Copyright (C) 2010  Siegfried-Angel Gevatter Pujals <siegfried@gevatter.com>
# Copyright (C) 2010,2013  Guido Guenther <agx@sigxcpu.org>
#
# Distributed under the GNU General Public License, version 2.0.

_gbp_branches ()
{
     [ -d .git ] || return 0
     git  for-each-ref --format="%(refname:short)" refs/heads
}


_gbp_tags ()
{
     [ -d .git ] || return 0
     git  for-each-ref --format="%(refname:short)" refs/tags
}


_gbp_options ()
{
    gbp $1 --help | sed -ne  's/^ \+\(\(\-[a-z]\), \)\?\(\-\-[a-z\-]\+\=\?\).*/\2 \3/p'
}


_gbp_commands ()
{
    gbp --list-cmds | sed -ne  's/^ \+\([a-z\-]\+\) \-.*/\1/p'
}


_gbp_comp ()
{
    local cur="${COMP_WORDS[COMP_CWORD]}"
    local prev="${COMP_WORDS[COMP_CWORD - 1]}"
    local options=$1
    local branch_opts=$2
    local tag_opts=$3
    local tristate_opts=$4

# COMPREPLY considers '=' as a word. For $prev we prefer the word before the actual "="
    if [[ "$prev" == "=" ]]; then
        prev="${COMP_WORDS[COMP_CWORD - 2]}"
    elif [[ "$cur" == "=" ]]; then
        cur=""
    fi

    if [[ "${branch_opts}" == *$prev* ]]; then
	local refs=$(_gbp_branches)
        COMPREPLY=( $(compgen -W "$refs" -- $cur ) )
        return 0
    fi

    if [[ "${tag_opts}" == *$prev* ]]; then
	local refs=$(_gbp_tags)
        COMPREPLY=( $(compgen -W "$refs" -- $cur ) )
        return 0
    fi

    if [[ "${tristate_opts}" == *$prev* ]]; then
        COMPREPLY=( $(compgen -W 'on off auto' -- $cur ) )
        return 0
    fi

    if [[ "${cbdist_opts}" == *$prev* ]]; then
        local BASE="/var/cache/pbuilder/base-"
        COMPREPLY=( $( compgen -o dirnames -G "${BASE}${cur}*.cow" \
                       | sed -e "s,${BASE}\(.*\)\.cow,\1,g" ) )
        return 0
    fi

    # separate opts by tab so we can append a space to all options not ending
    # with an equal sign
    tab_opts=$(echo "$options" | sed -e 's/ \+/\t/g' -e 's/[^=]$/& /g')
    type compopt &>/dev/null && compopt -o nospace
    local IFS=$'\t\n'
    COMPREPLY=($(compgen -W "$tab_opts" -- $cur))
}

# check if we can find a gbp command on the commandline
_gbp_find_cmd_on_cmdline ()
{
    local cmds="$1" # list of commands to check for
    local word cmd c=1

    while [ $c -lt $((COMP_CWORD)) ]; do
	word="${COMP_WORDS[c]}"
	for cmd in $cmds; do
	    if [ "$cmd" = "$word" ]; then
		echo "$cmd"
		return
	    fi
	done
	((c++))
    done
}

_gbp-buildpackage()
{
    local options=$(_gbp_options buildpackage)
    local branch_opts="--git-debian-branch\= --git-upstream-branch\= --git-upstream-tree\="
    local tag_opts="--git-debian-tag\= --git-upstream-tag\="
    local tristate_opts="--git-color\= --git-notify\="
    local cbdist_opts="--git-dist\="

    _gbp_comp "$options" "$branch_opts" "$tag_opts" "$tristate_opts" \
              "$cbdist_opts"
}

_gbp-dch ()
{
    local options=$(_gbp_options dch)
    local branch_opts="--debian-branch\="
    local tag_opts="--debian-tag\= --upstream-tag\="
    local tristate_opts="--color\="

    _gbp_comp "$options" "$branch_opts" "$tag_opts" "$tristate_opts"
}

_gbp-import-orig ()
{
    local options=$(_gbp_options import-orig)
    local branch_opts="--debian-branch\= --upstream-branch\="
    local tag_opts="--debian-tag\= --upstream-tag\="
    local tristate_opts="--color\="

    _gbp_comp "$options" "$branch_opts" "$tag_opts" "$tristate_opts"
}

_gbp-import-dsc ()
{
    local options=$(_gbp_options import-dsc)
    local branch_opts="--debian-branch\= --upstream-branch\="
    local tag_opts="--debian-tag\= --upstream-tag\="
    local tristate_opts="--color\="

    _gbp_comp "$options" "$branch_opts" "$tag_opts" "$tristate_opts"
}

_gbp-import-dscs ()
{
    local options="$(_gbp_options import-dscs) $(_gbp_options import-dsc)"
    local branch_opts="--debian-branch\= --upstream-branch\="
    local tag_opts="--debian-tag\= --upstream-tag\="
    local tristate_opts="--color\="

    _gbp_comp "$options" "$branch_opts" "$tag_opts" "$tristate_opts"
}

_gbp-pq ()
{
    local options=$(_gbp_options pq)
    options="$options export import rebase drop apply switch"
    local tristate_opts="--color\="

    _gbp_comp "$options" "" "" "$tristate_opts"
}

_gbp-pull ()
{
    local options=$(_gbp_options pull)
    local branch_opts="--debian-branch\= --upstream-branch\="
    local tag_opts="--debian-tag\= --upstream-tag\="
    local tristate_opts="--color\="

    _gbp_comp "$options" "$branch_opts" "$tag_opts" "$tristate_opts"
}

_gbp-clone ()
{
    local options=$(_gbp_options clone)
    local branch_opts="--debian-branch\= --upstream-branch\="
    local tag_opts="--debian-tag\= --upstream-tag\="
    local tristate_opts="--color\="

    _gbp_comp "$options" "$branch_opts" "$tag_opts" "$tristate_opts"
}

_gbp-create-remote-repo ()
{
    local options=$(_gbp_options create-remote-repo)
    local branch_opts="--debian-branch\= --upstream-branch\="
    local tristate_opts="--color\="

    _gbp_comp "$options" "$branch_opts" "" "$tristate_opts"
}

have gbp &&
_gbp ()
{
    local cur="${COMP_WORDS[COMP_CWORD]}"
    local commands=$(_gbp_commands)
    local func

    command=$(_gbp_find_cmd_on_cmdline "$commands")
    if [ -z $command ]; then
	COMPREPLY=( $(compgen -W "$commands" -- $cur ) )
    else
	func=_gbp-$(echo $command)
	$func
    fi
}
[ "${have:-}" ] && complete -F _gbp -o default gbp
