# hsmwiz(1) completion                                   -*- shell-script -*-
#
# bash-completion - part of hsmwiz
#
# Copyright (C) 2020 Hans-Christoph Steiner <hans@eds.org>
#
# 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, either version 3 of the License, or
# (at your option) any later version.
#
# 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 <http://www.gnu.org/licenses/>.

__hsmwiz_init() {
    if type -t _init_completion >/dev/null; then
        _init_completion -n : || return
    else
	# manual initialization for older bash completion versions
	COMPREPLY=()
	cur="${COMP_WORDS[COMP_CWORD]}"
	prev="${COMP_WORDS[COMP_CWORD-1]}"
    fi

    (( $# >= 1 )) && __complete_${1}
    __ltrim_colon_completions "$cur"
}

__complete_options() {
    case "${prev}" in
        --so-path)
            _filedir -d
            return 0;;
        --new|--old|--pin|--so-pin)
	    COMPREPLY=( $( compgen -W "$(printenv | cut -d = -f 1 | xargs printf 'env:%s ')" -- $cur ) )
            return 0;;
    esac

    COMPREPLY=( $( compgen -W "${opts} --help --verbose ${lopts}" -- $cur ) )
}

__complete_changepin() {
    lopts="--affect-so-pin --new --old --randomize-new --so-path"
    __complete_options
}

__complete_checkengine() {
    lopts=" --so-path"
    __complete_options
}

__complete_explore() {
    __complete_options
}

__complete_format() {
    lopts=" --so-pin --so-path"
    __complete_options
}

__complete_gencrt() {
    opts="-i -s -v"
    lopts="--id --pin --so-path --subject --validity-days"
    __complete_options
}

__complete_gencsr() {
    opts="-i -s -v"
    lopts="--id --pin --so-path --subject"
    __complete_options
}

__complete_getkey() {
    opts="-f -v"
    lopts="--id --key-format --label --pin --so-path"
    case "${prev}" in
        -f|--key-format)
	    COMPREPLY=( $( compgen -W "pem ssh" -- $cur ) )
            return;;
    esac
    __complete_options
}

__complete_identify() {
    __complete_options
}

__complete_init() {
    __complete_options
}

__complete_keygen() {
    lopts="--id --label --pin --so-path"
    case "${cur}" in
        -*)
        ;;
        *)
	    # https://www.nitrokey.com/documentation/frequently-asked-questions-faq#which-algorithms-and-maximum-key-length-are-supported
	    # https://www.nitrokey.com/files/doc/Nitrokey_HSM_1_factsheet.pdf
	    # openssl ecparam -list_curves | sed -En 's,^ *([^:]+):.*,\1,p' | xargs printf ' EC:%s'
            lopts="$lopts
                   EC:brainpoolP192r1
                   EC:brainpoolP224r1
                   EC:brainpoolP256r1
                   EC:brainpoolP320r1
                   EC:brainpoolP384r1
                   EC:brainpoolP512r1
                   EC:prime192v1
                   EC:prime256v1
                   EC:secp192k1
                   EC:secp192r1
                   EC:secp256k1
                   EC:secp256r1
                   rsa:1024
		   rsa:1536
                   rsa:2048
                   rsa:3072
                   rsa:4096"
        ;;
    esac
    __complete_options
}

__complete_putcrt() {
    opts="-i"
    lopts="--id --label --pin --so-path"
    case "${cur}" in
        -*)
	    __complete_options
        ;;
        *)
	    _filedir '@(cert|cer|crt|pem)'
	;;
    esac
}

__complete_removekey() {
    lopts="--id --label --pin --so-path"
    __complete_options
}

__complete_unblock() {
        lopts="--pin --so-path --so-pin"
    __complete_options
}

__complete_verifypin() {
    lopts=" --pin --so-path --verify-sopin"
    __complete_options
}

# hsmwiz | cut -b5-23 | sort -u | xargs printf '%s \\\n'
__cmds=" \
changepin \
checkengine \
explore \
format \
gencrt \
gencsr \
getkey \
identify \
init \
keygen \
putcrt \
removekey \
unblock \
verifypin \
"

for c in $__cmds; do
    eval "_hsmwiz_${c} () {
                local cur prev opts lopts
                __hsmwiz_init ${c}
        }"
done

_hsmwiz() {
    local cmd
    cmd=${COMP_WORDS[1]}

    [[ $__cmds == *\ $cmd\ * ]] && _hsmwiz_${cmd} || {
            (($COMP_CWORD == 1)) && COMPREPLY=( $( compgen -W "${__cmds}" -- $cmd ) )
        }
}

complete -F _hsmwiz hsmwiz

return 0
