# -*- shell-script -*-
#
# Bash tab auto-completion rules for git-buildpackage.
#
# Copyright (C) 2010  Siegfried-Angel Gevatter Pujals <siegfried@gevatter.com>
# Copyright (C) 2010,2013,2015  Guido Günther <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_remote_configs ()
{
    GBP_DISABLE_GBP_CONF_DEPRECATION=true \
    GBP_DISABLE_SECTION_DEPRECATION=true \
        gbp create-remote-repo list | sed -ne 's/^ \+\([a-z]\+\)/\1/p'
}


_gbp_options ()
{
    GBP_DISABLE_GBP_CONF_DEPRECATION=true \
    GBP_DISABLE_SECTION_DEPRECATION=true \
        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:-"--debian-branch\= --upstream-branch\= --upstream-tree\="}
    local tag_opts=${3:-"--debian-tag\= --upstream-tag\= --upstream-vcs-tag\="}
    local tristate_opts=${4:-"--color\="}
    local cbdist_opts=${5:-"--git-dist\="}
    local remote_config_opts="--remote-config\="
    local file_opts="--postimport\= --git-builder\= --git-cleaner\= \
                     --git-export-dir\= --git-postbuild\= --git-postexport\= \
                     --git-posttag\= --git-prebuild\= --git-preexport\= --git-tarball-dir\= \
                     --posttag\= --tarball-dir\="
    local start_opt=""

# 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
        start_opt=1
        cur=""
    fi

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

      if [[ "${tag_opts}" == *$prev* && "${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

      if [[ "${remote_config_opts}" == *$prev* ]]; then
          local remote_configs=$(_gbp_remote_configs)
          COMPREPLY=( $(compgen -W "$remote_configs" -- $cur ) )
          return 0
      fi

      if [[ "${file_opts}" == *$prev* ]]; then
          COMPREPLY=( $(compgen -f -- $cur ) )
          return 0
      fi
    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'
    if [ -n "$start_opt" ]; then
        COMPREPLY=""  # we don't have any good suggestions
    else
        COMPREPLY=($(compgen -W "$tab_opts" -- $cur))
    fi
}

# 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\="

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


_gbp-pq ()
{
    local options=$(_gbp_options pq)
    options="$options export import rebase drop apply switch"
    _gbp_comp "$options"
}


_gbp-create-remote-repo ()
{
    local options=$(_gbp_options create-remote-repo)
    options="$options list"
    _gbp_comp "$options"
}


_gbp-generic-cmd()
{
    local options=$(_gbp_options "${1}")
    _gbp_comp "$options"
}


_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
        if type _gbp-"${command}" >& /dev/null; then
            _gbp-"${command}"
        else
            _gbp-generic-cmd "${command}"
        fi
    fi
} && complete -F _gbp -o default gbp
