#
# Bash commandline completion
#
_module_comgen_words_and_files() {
    local k=0
    local setnospace=1
    # do not append space to word completed if it is a directory (ends with /)
    for val in $(compgen -W "$1" -- "$2"); do
        if [ !$setnospace -a "${val: -1:1}" = '/' ]; then
            # Bash >=4.0 is required for compopt
            type compopt &>/dev/null && compopt -o nospace
            setnospace=0
        fi
        COMPREPLY[k++]="$val"
    done
}

_module_avail() {
    local cur="${1:-}"
    # skip avail call if word currently being completed is an option keyword
    if [ -z "$cur" -o "${cur:0:1}" != '-' ]; then
        module avail --color=never -s -t -S --no-indepth $cur 2>&1 | sed '
            /^-\+/d; /^\s*$/d;
            /->.*$/d;
            /:$/d;
            s#^\(.*\)/\(.\+\)(.*default.*)#\1\n\1\/\2#;
            s#(.*)$##g;
            s#\s*$##g;'
    fi
}

_module_savelist() {
    module savelist --color=never -s -t 2>&1 | sed '
        /No named collection\.$/d;
        /Named collection list$/d;
        /:$/d;'
}

_module_not_yet_loaded() {
    _module_avail ${1:-} | sort | @SED_ERE@ "\%^(${LOADEDMODULES//:/|})$%d"
}

_module_long_arg_list() {
    local cur="$1" i

    if [[ ${COMP_WORDS[COMP_CWORD-2]} == sw* ]]
    then
        _module_comgen_words_and_files "$(_module_not_yet_loaded $cur)" "$cur"
        return
    fi
    for ((i = COMP_CWORD - 1; i > 0; i--))
        do case ${COMP_WORDS[$i]} in
        add|load)
            _module_comgen_words_and_files "$(_module_not_yet_loaded $cur)" "$cur"
            break;;
        rm|del|remove|unload|switch|swap)
            COMPREPLY=( $(IFS=: compgen -W "${LOADEDMODULES}" -- "$cur") )
            break;;
        esac
    done
}

@compatversion@# define completion relative to active version
@compatversion@if [ "$MODULES_USE_COMPAT_VERSION" = '1' ]; then
@compatversion@_module() {
@compatversion@   local cur="$2" prev="$3" cmds opts
@compatversion@
@compatversion@   COMPREPLY=()
@compatversion@
@compatversion@   cmds="add apropos avail clear display del help\
@compatversion@      initadd initclear initlist initprepend initrm initswitch\
@compatversion@      keyword list load purge refresh remove rm show swap switch\
@compatversion@      unload unuse update use whatis"
@compatversion@
@compatversion@   opts="-c -f -h -i -l -s -t -u -v -H -V\
@compatversion@      --create --force  --help  --human   --icase\
@compatversion@      --long   --silent --terse --userlvl --verbose --version"
@compatversion@
@compatversion@   case "$prev" in
@compatversion@   add|load)   COMPREPLY=( $(compgen -W "$(_module_not_yet_loaded)" -- "$cur") );;
@compatversion@   rm|del|remove|unload|switch|swap)
@compatversion@      COMPREPLY=( $(IFS=: compgen -W "${LOADEDMODULES}" -- "$cur") );;
@compatversion@   unuse)      COMPREPLY=( $(IFS=: compgen -W "${MODULEPATH}" -- "$cur") );;
@compatversion@   use|*-a*)   ;;       # let readline handle the completion
@compatversion@   -u|--userlvl)  COMPREPLY=( $(compgen -W "novice expert advanced" -- "$cur") );;
@compatversion@   av*|disp*|help|show|whatis)
@compatversion@      COMPREPLY=( $(compgen -W "$(_module_avail)" -- "$cur") );;
@compatversion@   *) if test $COMP_CWORD -gt 2
@compatversion@      then
@compatversion@      _module_long_arg_list "$cur"
@compatversion@      else
@compatversion@      case "$cur" in
@compatversion@      # The mappings below are optional abbreviations for convenience
@compatversion@      ls)   COMPREPLY="list";;   # map ls -> list
@compatversion@      r*)   COMPREPLY="rm";;  # also covers 'remove'
@compatversion@      sw*)  COMPREPLY="switch";;
@compatversion@
@compatversion@      -*)   COMPREPLY=( $(compgen -W "$opts" -- "$cur") );;
@compatversion@      *) COMPREPLY=( $(compgen -W "$cmds" -- "$cur") );;
@compatversion@      esac
@compatversion@      fi;;
@compatversion@   esac
@compatversion@}
@compatversion@else
_module() {
    local cur="$2" prev="$3" cmds opts

    COMPREPLY=()

    cmds="add apropos aliases avail append-path clear config del display help\
        initadd initclear initlist initprepend initrm is-loaded is-saved\
        is-used is-avail info-loaded keyword list load path paths purge\
        prepend-path refresh reload restore rm remove remove-path save\
        savelist saveshow saverm search show sh-to-mod source swap switch\
        test unload unuse use whatis"

    opts="-D -h -s -T -v -V --debug --help --silent --trace --verbose\
        --version --paginate --no-pager --color --color="
    load_opts="--auto --no-auto --force -f -i --icase"
    list_opts="-j -l -t --json --long --terse"
    clear_opts="--force -f"
    path_opts="-d --delim --duplicates"
    rm_path_opts="-d --delim --index"
    avail_opts="-a -C -d -j -i -L -l -S -t --all --contains --default --icase\
        --json --latest --long --starts-with --terse --indepth --no-indepth"
    isavail_opts="-a -i --all --icase"
    aliases_opts="-a --all"
    mfile_opts="-i --icase"
    search_opts="-a -j --all --json"
    whatis_opts="-a -i -j --all --icase --json"
    config_opts="--dump-state --reset advanced_version_spec auto_handling\
        avail_indepth collection_pin_version collection_target color colors\
        contact extended_default extra_siteconfig home icase implicit_default\
        locked_configs ml nearly_forbidden_days pager rcfile run_quarantine\
        search_match set_shell_startup silent_shell_debug term_background\
        unload_match_order verbosity wa_277"

    case "$prev" in
    add|load)       _module_comgen_words_and_files "$load_opts $(_module_not_yet_loaded $cur)" "$cur";;
    avail)          _module_comgen_words_and_files "$avail_opts $(_module_avail $cur)" "$cur";;
    aliases)  COMPREPLY=( $(compgen -W "$aliases_opts" -- "$cur") );;
    list|savelist)  COMPREPLY=( $(compgen -W "$list_opts" -- "$cur") );;
    clear)  COMPREPLY=( $(compgen -W "$clear_opts" -- "$cur") );;
    restore|save|saveshow|saverm|is-saved)
                    COMPREPLY=( $(compgen -W "$(_module_savelist)" -- "$cur") );;
    rm|del|remove|unload|switch|swap)
                    COMPREPLY=( $(compgen -W "$load_opts ${LOADEDMODULES//:/ }" -- "$cur") );;
    unuse|is-used)  COMPREPLY=( $(IFS=: compgen -W "${MODULEPATH}" -- "$cur") );;
    use|-a|--append)   ;;               # let readline handle the completion
    display|help|show|test|path|paths|is-loaded|info-loaded)
                    _module_comgen_words_and_files "$mfile_opts $(_module_avail $cur)" "$cur";;
    is-avail)
                    _module_comgen_words_and_files "$isavail_opts $(_module_avail $cur)" "$cur";;
    whatis)
                    _module_comgen_words_and_files "$whatis_opts $(_module_avail $cur)" "$cur";;
    apropos|keyword|search)
                    COMPREPLY=( $(compgen -W "$search_opts" -- "$cur") );;
    config|--reset) COMPREPLY=( $(compgen -W "$config_opts" -- "$cur") );;
    -h|--help|-V|--version|purge|refresh|reload|sh-to-mod|source)
                    ;;
    append-path|prepend-path)
                    COMPREPLY=( $(compgen -W "$path_opts" -- "$cur") );;
    remove-path)
                    COMPREPLY=( $(compgen -W "$rm_path_opts" -- "$cur") );;
    initadd|initclear|initlist|initprepend|initrm)
                    ;;
    *)  if test $COMP_CWORD -gt 2
        then
            _module_long_arg_list "$cur"
        else
            case "$cur" in
            # The mappings below are optional abbreviations for convenience
            ls)     COMPREPLY="list";;      # map ls -> list
            sw*)    COMPREPLY="switch";;

            -*)     COMPREPLY=( $(compgen -W "$opts" -- "$cur") );;
            *)      COMPREPLY=( $(compgen -W "$opts $cmds" -- "$cur") );;
            esac
        fi;;
    esac
}

# define completion for ml command if command exists
if $(type -t ml >/dev/null); then
    _ml() {
        local cur="$2" prev="$3" cmds opts

        COMPREPLY=()

        cmds="add apropos aliases avail append-path clear config del display help\
            initadd initclear initlist initprepend initrm is-loaded is-saved\
            is-used is-avail info-loaded keyword list load path paths purge\
            prepend-path refresh reload restore rm remove remove-path save\
            savelist saveshow saverm search show sh-to-mod source swap switch\
            test unload unuse use whatis"

        opts="-D -h -s -T -v -V --debug --help --silent --trace --verbose\
            --version --paginate --no-pager --color --color="
        load_opts="--auto --no-auto --force -f -i --icase"
        list_opts="-j -l -t --json --long --terse"
        clear_opts="--force -f"
        path_opts="-d --delim --duplicates"
        rm_path_opts="-d --delim --index"
        avail_opts="-a -C -d -j -i -L -l -S -t --all --contains --default --icase\
            --json --latest --long --starts-with --terse --indepth --no-indepth"
        isavail_opts="-a -i --all --icase"
        aliases_opts="-a --all"
        mfile_opts="-i --icase"
        search_opts="-a -j --all --json"
        whatis_opts="-a -i -j --all --icase --json"
        config_opts="--dump-state --reset advanced_version_spec auto_handling\
            avail_indepth collection_pin_version collection_target color colors\
            contact extended_default extra_siteconfig home icase implicit_default\
            locked_configs ml nearly_forbidden_days pager rcfile run_quarantine\
            search_match set_shell_startup silent_shell_debug term_background\
            unload_match_order verbosity wa_277"

        case "$prev" in
        add|load)       _module_comgen_words_and_files "$load_opts $(_module_not_yet_loaded $cur)" "$cur";;
        avail)          _module_comgen_words_and_files "$avail_opts $(_module_avail $cur)" "$cur";;
        aliases)  COMPREPLY=( $(compgen -W "$aliases_opts" -- "$cur") );;
        list|savelist)  COMPREPLY=( $(compgen -W "$list_opts" -- "$cur") );;
        clear)  COMPREPLY=( $(compgen -W "$clear_opts" -- "$cur") );;
        restore|save|saveshow|saverm|is-saved)
                        COMPREPLY=( $(compgen -W "$(_module_savelist)" -- "$cur") );;
        rm|del|remove|unload|switch|swap)
                        COMPREPLY=( $(compgen -W "$load_opts ${LOADEDMODULES//:/ }" -- "$cur") );;
        unuse|is-used)  COMPREPLY=( $(IFS=: compgen -W "${MODULEPATH}" -- "$cur") );;
        use|-a|--append)   ;;               # let readline handle the completion
        display|help|show|test|path|paths|is-loaded|info-loaded)
                        _module_comgen_words_and_files "$mfile_opts $(_module_avail $cur)" "$cur";;
        is-avail)
                        _module_comgen_words_and_files "$isavail_opts $(_module_avail $cur)" "$cur";;
        whatis)
                        _module_comgen_words_and_files "$whatis_opts $(_module_avail $cur)" "$cur";;
        apropos|keyword|search)
                        COMPREPLY=( $(compgen -W "$search_opts" -- "$cur") );;
        config|--reset) COMPREPLY=( $(compgen -W "$config_opts" -- "$cur") );;
        -h|--help|-V|--version|purge|refresh|reload|sh-to-mod|source)
                        ;;
        append-path|prepend-path)
                        COMPREPLY=( $(compgen -W "$path_opts" -- "$cur") );;
        remove-path)
                        COMPREPLY=( $(compgen -W "$rm_path_opts" -- "$cur") );;
        initadd|initclear|initlist|initprepend|initrm)
                        ;;
        *)  if test $COMP_CWORD -gt 2
            then
                _module_long_arg_list "$cur"
            else
                case "$cur" in
                # The mappings below are optional abbreviations for convenience
                ls)     COMPREPLY="list";;      # map ls -> list
                sw*)    COMPREPLY="switch";;

                -*)     COMPREPLY=( $(compgen -W "$opts" -- "$cur") )
                        loaded_modules=""
                        for i in ${LOADEDMODULES//:/ }; do
                            loaded_modules+="-${i} "
                        done
                        COMPREPLY=( "${COMPREPLY[@]}" $(compgen -W "$load_opts $loaded_modules" -- "$cur") );;
                *)       _module_comgen_words_and_files "$load_opts $(_module_not_yet_loaded $cur)" "$cur"
                        COMPREPLY=( "${COMPREPLY[@]}" $(compgen -W "$opts $cmds" -- "$cur") )
                        loaded_modules=""
                        for i in ${LOADEDMODULES//:/ }; do
                            loaded_modules+="-${i} "
                        done
                        COMPREPLY=( "${COMPREPLY[@]}" $(compgen -W "$load_opts $loaded_modules" -- "$cur") );;
                esac
            fi;;
        esac
    }
    complete -o default -F _ml ml
fi
@compatversion@fi
complete -o default -F _module module
