# Bash completions for the ws tool.
#
# Copyright (c) 2017-2018 Xevo Inc. All rights reserved.
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in
# all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.
#

_ws_list_projects() {
    local projects="$(ws list 2>/dev/null)"
    COMPREPLY=($(compgen -W "$projects" -- $current))
}

_ws_list_workspaces() {
    local workspaces="$(ws list -w 2>/dev/null)"
    COMPREPLY=($(compgen -W "$workspaces" -- $current))
}

_complete_ws() {
    local i=1
    local posargs=1
    local cmd_index=0
    while (( $i < $COMP_CWORD )); do
        # Set command to the last positional argument, or the second if there
        # are more than two. This makes sense because the syntax is:
        # ws [cmd] ...
        local word=${COMP_WORDS[i]}
        if [[ ${word:0:1} != - ]]; then
            let posargs=posargs+1
            if (( $posargs <= 2 )); then
                local cmd_index=$i
            elif (( $posargs == 3)); then
                local project_index=$i
            else
                break
            fi
        fi
        let i=i+1
    done
    local cmd=${COMP_WORDS[cmd_index]}
    local current=${COMP_WORDS[COMP_CWORD]}
    local last=${COMP_WORDS[$COMP_CWORD-1]}

    if [[ $last == -w ]]; then
        # "ws -w <TAB>"
        _ws_list_workspaces
        return
    fi

    case "$cmd" in
        ws)
            # Commands.
            local subcmds="init list rename remove default config clean build env"
            COMPREPLY=($(compgen -W "$subcmds" -- $current))
            ;;
        default|rename|remove)
            # Workspaces.
            local workspaces="$(ws list -w 2>/dev/null)"
            if [[ $posargs == 2 ]]; then
                COMPREPLY=($(compgen -W "$workspaces" -- $current))
            fi
            ;;

        init)
            if [[ $last == -s || $last == --manifest-source ]]; then
                COMPREPLY=($(compgen -W "fs repo" -- $current))
            elif [[ $last == -t || $last == --type ]]; then
                COMPREPLY=($(compgen -W "debug release" -- $current))
            else
                COMPREPLY=($(compgen -W "-s -t -m" -- $current))
            fi
            ;;

        build|clean)
            # Projects.
            if [[ $posargs == 2 ]]; then
                _ws_list_projects
            fi
            ;;

        env)
            if [[ $posargs == 2 ]]; then
                # ws env <TAB>
                _ws_list_projects
            else
                # Completions inside a project's environment.
                local project=${COMP_WORDS[$project_index]}
                if [[ $posargs == 3 ]]; then
                    # "ws env project <TAB>"
                    # Command completions.
                    local switch=c
                else
                    # "ws env project arg <TAB>"
                    # We would like to recursively call bash's auto-complete for
                    # this, but there appears to be no good way to do it. So, just
                    # take a guess and complete files/directories, since it's more
                    # helpful than doing nothing.
                    local switch=f
                fi
                COMPREPLY=($(ws env $project bash -c "compgen -${switch} $current" 2>/dev/null))
            fi
            ;;

        config)
            if [[ $last == -p || $last == --project ]]; then
                # ws config -p <TAB>
                _ws_list_projects
            else
                # ws config <TAB>
                local i=1
                local project_arg=0
                while (( $i < $COMP_CWORD )); do
                    local word=${COMP_WORDS[i]}
                    if [[ $word == -p || $word == --project ]]; then
                        project_arg=1
                        break
                    fi
                    let i=i+1
                done

                local options
                if [[ $project_arg == 1 ]]; then
                    options="enable args="
                else
                    options="-p type"
                fi

                COMPREPLY=($(compgen -W "$options" -- $current))
            fi
            ;;
    esac
}

complete -F _complete_ws ws
