#  OpenVPN 3 Linux client -- Next generation OpenVPN client
#
#  Copyright (C) 2018 - 2019  OpenVPN Inc. <sales@openvpn.net>
#  Copyright (C) 2018 - 2019  David Sommerseth <davids@openvpn.net>
#
#  This program is free software: you can redistribute it and/or modify
#  it under the terms of the GNU Affero General Public License as
#  published by the Free Software Foundation, version 3 of the
#  License.
#
#  This program is distributed in the hope that it will be useful,
#  but WITHOUT ANY WARRANTY; without even the implied warranty of
#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#  GNU Affero General Public License for more details.
#
#  You should have received a copy of the GNU Affero General Public License
#  along with this program.  If not, see <https://www.gnu.org/licenses/>.
#

##
# @file  bash_completion_openvpn3
#
# @brief  A bash_completion helper script for the openvpn3 command line
#         programs.  This script makes use of the shell-completion command
#         provided by openvpn3 or openvpn3-admin, which provides up-to-date
#         insight on the various commands, options and arguments.
#
#         Also works with zsh after loading bascomphinit
#         (autoload -U +X bashcompinit && bashcompinit)

_openvpn3_generic_completion()
{
    local cmd first cur prev opts base
    COMPREPLY=()
    cmd="$1"
    first=${COMP_WORDS[1]}
    cur="${COMP_WORDS[COMP_CWORD]}"
    prev="${COMP_WORDS[COMP_CWORD-1]}"

    if [ $COMP_CWORD -eq 1 ]; then
        # The first argument is always an openvpn3 command
        o3cmds="$($cmd shell-completion --list-commands)"
        COMPREPLY=( $( compgen -W "$o3cmds" $cur ) )
    elif [ $COMP_CWORD -gt 1 ]; then
        selection=""
        if [ "${cur:0:2}" == "--" -o "${cur:0:1}" == "-" ]; then
            # If the argument starts with '-' or '--' provide list of options
            selopts="-W $($cmd shell-completion --list-options $first)"
        else
            # Some options can get some extra help from bash
            case "${prev}" in
            "--config")  # Takes configuration profile names and file names
                # Prepare a simple filter, providing partial matching
                filter="cat" # by default everything passes
                if [ -n "$cur" ]; then
                    filter="grep -E ^$cur"
                fi

                selopts="-W"
                if [ "config-import" = "${first}" -o "session-start" = "${first}" ]; then
                    # Only list files which most likely are OpenVPN configuration files
                    selopts="$selopts $(grep -sm1 -E '(client|remote |port |lport |rport |key |cert |ca )' ${cur}*.conf ${cur}*.ovpn | cut -d: -f1 | $filter | tr '\n' ' ')"

                    # Add directories too, but ignore those starting with '.{some-alpha-num-letters}'
                    selopts="$selopts $(compgen -d -- $cur | sed 's#$#/#' | grep -vE '^\.\w+' | tr '\n' ' ')"
                fi

                # In addition, extend with all pre-loaded configurations
                selopts="$selopts $($cmd shell-completion --list-options $first --arg-help $prev)"
                ;;

            "--grant"|"--revoke") # Takes username (or UID, which we don't tackle here)
                selopts="-u"
                ;;

            *)
                # Otherwise try to fill out with possible argument values for the
                # provided option
                selopts="-W $($cmd shell-completion --list-options $first --arg-help $prev)"
                ;;
            esac
        fi
        COMPREPLY=( $( compgen "${selopts}" -- $cur ) )
    fi
}

_openvpn3_completion()
{
    _openvpn3_generic_completion openvpn3
}
complete -F _openvpn3_completion openvpn3


_openvpn3admin_completion()
{
    _openvpn3_generic_completion openvpn3-admin
}
complete -F _openvpn3admin_completion openvpn3-admin
