#!/usr/bin/env bash

_abra_basename()
{
    echo "${1##*/}"
}

_abra_servers()
{
    # FIXME 3wc: copied from abra/get_servers()
    shopt -s nullglob dotglob
    local SERVERS=(~/.abra/servers/*)
    shopt -u nullglob dotglob

    for SERVER in "${SERVERS[@]}"; do
        _abra_basename "${SERVER}"
    done
}

_abra_complete_servers()
{
    mapfile -t COMPREPLY < <(compgen -W "$(_abra_servers)" -- "$1")
}

_abra_apps()
{
    shopt -s nullglob dotglob
    local APPS=(~/.abra/servers/*/*.env)
    shopt -u nullglob dotglob

    for APP in "${APPS[@]}"; do
        _abra_basename "${APP%.env}"
    done
}

_abra_complete_apps()
{
    mapfile -t COMPREPLY < <(compgen -W "$(_abra_apps)" -- "$1")
}

_abra_recipes()
{
    shopt -s nullglob dotglob
    local RECIPES=(~/.abra/apps/*)
    shopt -u nullglob dotglob

    for RECIPE in "${RECIPES[@]}"; do
        _abra_basename "${RECIPE%.env}"
    done
}

_abra_complete_recipes()
{
    mapfile -t COMPREPLY < <(compgen -W "$(_abra_recipes)" -- "$1")
}

_abra_complete()
{
    compopt +o default +o nospace
    COMPREPLY=()

    local -r cmds='
        app
        server
        recipe
    '
    local -r short_opts='-e      -h     -s      -v'
    local -r long_opts='--env --help --stack --version'

    # Scan through the command line and find the abra command
    # (if present), as well as its expected position.
    local cmd
    local cmd_index=1 # Expected index of the command token.
    local i
    for (( i = 1; i < ${#COMP_WORDS[@]}; i++ )); do
        local word="${COMP_WORDS[i]}"
        case "$word" in
            -*)
                ((cmd_index++))
                ;;
            *)
                cmd="$word"
                break
                ;;
        esac
    done

    local cur="${COMP_WORDS[COMP_CWORD]}"

    if (( COMP_CWORD < cmd_index )); then
        # Offer option completions.
        case "$cur" in
            --*)
                mapfile -t COMPREPLY < <(compgen -W "$long_opts" -- "$cur")
                ;;
            -*)
                mapfile -t COMPREPLY < <(compgen -W "$short_opts" -- "$cur")
                ;;
            *)
                # Skip completion; we should never get here.
                ;;
        esac
    elif (( COMP_CWORD == cmd_index )); then
        # Offer command name completions.
        mapfile -t COMPREPLY < <(compgen -W "$cmds" -- "$cur")
    else
        # Offer command argument completions.
        case "$cmd" in
            server)
                # Offer exactly one server name completion.
                if (( COMP_CWORD == cmd_index + 1 )); then
                    _abra_complete_servers "$cur"
                fi
                ;;
            app)
                # Offer exactly one app completion.
                if (( COMP_CWORD == cmd_index + 1 )); then
                    _abra_complete_apps "$cur"
                fi
                ;;
            recipe)
                # Offer exactly one app completion.
                if (( COMP_CWORD == cmd_index + 1 )); then
                    _abra_complete_recipes "$cur"
                fi
                ;;
            #help)
            #    # Offer exactly one command name completion.
            #    if (( COMP_CWORD == cmd_index + 1 )); then
            #        COMPREPLY=($(compgen -W "$cmds" -- "$cur"))
            #    fi
            #    ;;
            *)
                # Unknown command or unknowable argument.
                ;;
        esac
    fi
}

complete -o default -F _abra_complete abra