#!/bin/sh ## Only here for syntax highlighting

_singularity() {
    local cur cmd opts cmd_idx container_idx
    COMPREPLY=()
    cur="${COMP_WORDS[COMP_CWORD]}"
    prev_idx=$(( $COMP_CWORD - 1))
    prev="${COMP_WORDS[$prev_idx]}"

    # TODO: This can be dynamically generated by the following:
    #   find /opt/singularity/libexec/singularity/cli -maxdepth 1 -mindepth 1 -name '*.exec' -type f -exec basename {} \; | sed -e 's|.exec||' | sort -u
    # but we then need to auto-generate this file with autoconf.
    local -r cmds="help exec run shell test bootstrap copy create expand export import mount"

    # Find the first command (skipping any global options)
    cmd_idx=1
    while [ $cmd_idx -lt $COMP_CWORD ]; do
        cmd="${COMP_WORDS[$cmd_idx]}"
        if [[ ${cmd} != -* ]] ; then
            break;
        fi
        cmd_idx=$(( $cmd_idx + 1 ))
    done

    # In this case, no command is present.
    if [ $cmd_idx -eq $COMP_CWORD ]; then
        if [[ ${cur} == -* ]] ; then
            opts="--help --verbose --debug --quiet --shdebug"
            COMPREPLY=( $(compgen -W "${opts}" -- ${cur}) )
            return 0
        else
            COMPREPLY=( $(compgen -W "${opts} ${cmds}" -- ${cur}) )
            return 0
        fi
    fi

    # Try to determine if a container has been specified.
    container_idx=$(( $cmd_idx + 1 ))
    while [ $container_idx -lt $COMP_CWORD ]; do
        container="${COMP_WORDS[$container_idx]}"
        if [[ ${container} != -* ]] ; then
            break;
        fi
        # Skip arguments to options
        if [[ ${container} == -H || ${container} == --home ]]; then
            container_idx=$(( $container_idx + 1 ))
        fi
        if [[ ${container} == -B || ${container} == --bind ]]; then
            container_idx=$(( $container_idx + 1 ))
        fi
        if [[ ${container} == -W || ${container} == --workdir ]]; then
            container_idx=$(( $container_idx + 1 ))
        fi
        container_idx=$(( $container_idx + 1 ))
    done

    case "${cmd}" in
        help)
            return 0
        ;;

        run|shell|exec)
            # If we specified a container, treat this as a command
            if [ $container_idx -lt $COMP_CWORD ]; then
                if [[ ${cmd} == run || ${cmd} == exec ]]; then
                    _command_offset $(( $container_idx + 1 ))
                    return 0
                fi
            fi

            if [[ ${cur} == -B || ${cur} == --bind ]]; then
                #TODO: Not really a path, but this should be a bind spec...
                _filedir
            elif [[ ${cur} == -S || ${cur} == --scratch* || ${cur} == --pwd ]]; then
                _filedir
            elif [[ ${cur} == -H || ${cur} == --home ]]; then
                COMPREPLY=( $(compgen -f -- ${cur}) )
            elif [[ ${cur} == -W || ${cur} == --workdir || ${cur} == --wdir ]]; then
                COMPREPLY=( $(compgen -f -- ${cur}) )
            elif [[ ${cur} == -* ]] ; then
                COMPREPLY=( $(compgen -W "--help --bind --scratch --home --pwd --contain --containall --ipc --pid --user --workdir --writable" -- ${cur}) )
            else
                _filedir
            fi
            return 0
        ;;

        bootstrap)
            if [[ ${cur} == -* ]] ; then
                COMPREPLY=( $(compgen -W "--force --help" -- ${cur}) )
            else
                _filedir
            fi
            return 0
        ;; 

        test|mount)
            if [[ ${cur} == -* ]] ; then
                COMPREPLY=( $(compgen -W "--force --help" -- ${cur}) )
            else
                _filedir
            fi
            _filedir
            return 0
        ;; 

        copy)
            _filedir
            return 0
        ;;

        create)
            if [[ ${cur} == -s || ${cur} == --size ]]; then
                # Specify a number; no completion. 
                return 0
            elif [[ ${cur} == -* ]] ; then
                 COMPREPLY=( $(compgen -W "--help --size --force" -- ${cur}) )
            elif [ $container_idx -lt $COMP_CWORD ]; then
                return 0
            else
                _filedir
            fi
            return 0
        ;;

        expand)
            if [[ ${cur} == -s || ${cur} == --size ]]; then
                # Specify a number; no completion.
                return 0
            elif [[ ${cur} == -* ]] ; then
                COMPREPLY=( $(compgen -W "--help --size" -- ${cur}) )
            elif [ $container_idx -lt $COMP_CWORD ]; then
                return 0
            else
                _filedir
            fi
            return 0
        ;;

        import|export)
            if [[ ${cur} == -* ]] ; then
                COMPREPLY=( $(compgen -W "--help --file --command" -- ${cur}) )
            elif [[ ${prev} == --command ]]; then
                return 0
            elif [ $container_idx -lt $COMP_CWORD ]; then
                return 0
            else
                _filedir
            fi
            return 0
        ;;

    esac
}

complete -F _singularity singularity

