#compdef kerl

# ------------------------------------------------------------------------------
# Description
# -----------
#
#  Completion script for kerl (https://github.com/kerl/kerl)
#
#  Source: https://github.com/sanmiguel/zsh-completions
#
# ------------------------------------------------------------------------------
# Authors
# -------
#
#  * Michael Coles (https://github.com/sanmiguel)
#
# ------------------------------------------------------------------------------

if [[ -z ${KERL_BASE_DIR+x} ]]; then
    KERL_BASE_DIR="$HOME/.kerl"
fi

_kerl_otp_releases() {
    releases=(${(f)"$(_call_program releases cat $KERL_BASE_DIR/otp_releases 2>/dev/null)"})
}

_kerl_otp_builds() {
    builds=(${(f)"$(_call_program builds cat $KERL_BASE_DIR/otp_builds 2>/dev/null | cut -f 2 -d ",")"})
}

_kerl_otp_installations_names() {
    installations=(${(f)"$(_call_program installations cat $KERL_BASE_DIR/otp_installations 2>/dev/null | cut -f 2 -d " ")"})
}

_kerl_otp_installations_directories() {
    installations=(${(f)"$(_call_program installations cat $KERL_BASE_DIR/otp_installations 2>/dev/null | cut -f 2 -d " " | xargs basename)"})
}

local -a _1st_arguments
_1st_arguments=(
    'build:Build specified release or git repository'
    'install:Install the specified release at the given location'
    'build-install:Builds and installs the specified release or git repository at the given location'
    'deploy:Deploy the specified installation to the given host and location'
    'update:Update the list of available releases from your source provider'
    'list:List releases, builds and installations'
    'delete:Delete builds and installations'
    'path:Print the path of a given installation'
    'active:Print the path of the active installation'
    'plt:Print Dialyzer PLT path for the active installation'
    'status:Print available builds and installations'
    'prompt:Print a string suitable for insertion in prompt'
    'cleanup:Remove compilation artifacts (use after installation)'
    'emit-activate:Print the activate script'
    'upgrade:Fetch and install the most recent kerl release'
    'version:Print current version'
)

local -a _list_options
_list_options=(
    'releases:Available OTP releases'
    'builds:All locally built OTP releases'
    'installations:All locally installed OTP builds'
)
local -a _delete_options
_delete_options=(
    'build:Delete a specific build'
    'installation:Delete a specific installation'
)
local -a _list_releases_options
_list_releases_options=(
    'all:All available OTP releases'
)
local -a _update_options
_update_options=(
    'releases:All available OTP releases'
)

_arguments \
    '*:: :->subcmds' && return 0

if (( CURRENT == 1 )); then
    _describe -t commands 'kerl subcommand' _1st_arguments
    return
fi

case "${words[1]}" in
    build)
        _arguments \
            '1: :->release' \
            && return 0
        if [[ "$state" == "release" ]]; then
            _kerl_otp_releases
            releases=('git' "$releases")
            _wanted releases expl 'all releases' compadd -a releases
        fi
        ;;
    install)
        _arguments \
            '1: :->build_name' \
            && return 0
        if [[ "$state" == "build_name" ]]; then
            _kerl_otp_builds
            _wanted builds expl 'all builds' compadd -a builds
            return
        fi
        _directories
        ;;
    build-install)
        _arguments \
            '1: :->release' \
            && return 0
        if [[ "$state" == "release" ]]; then
            _kerl_otp_releases
            releases=('git' "$releases")
            _wanted releases expl 'all releases' compadd -a releases
        fi
        ;;
    deploy)
        _arguments \
            '1: :->user_host' \
            '2: :->directory' \
            && return 0
        if [[ "$state" == "user_host" ]]; then
            _hosts
        elif [[ "$state" == "directory" ]]; then
            _kerl_otp_installations_names
            _wanted installations expl 'all installations' compadd -a installations
        fi
        ;;
    update)
        _arguments \
            '1: :->releases' \
            && return 0
        if [[ "$state" == "releases" ]]; then
            _describe 'kerl update options' _update_options
        fi
        ;;
    list)
        _arguments \
            '1: :->releases_builds_installations' \
            '2: :->all' \
            && return 0
        if [[ "$state" == "releases_builds_installations" ]]; then
            _describe 'kerl list options' _list_options
        elif [[ "$state" == all ]] && [[ "${words[2]}" == "releases" ]]; then
            _describe 'kerl list release options' _list_releases_options
        fi
        ;;
    delete)
        _arguments \
            '1: :->build_installation' \
            '2: :->build_name_or_directory' \
            && return 0
        if [[ "$state" == "build_installation" ]]; then
            _describe 'kerl delete options' _delete_options
        elif [[ "$state" == "build_name_or_directory" ]]; then
          if [[ "${words[2]}" == "build" ]]; then
              _kerl_otp_builds
              _wanted builds expl 'all builds' compadd -a builds
          elif [[ "${words[2]}" == "installation" ]]; then
              _kerl_otp_installations_names
              _wanted installations expl 'all installations' compadd -a installations
          fi
        fi
        ;;
    path)
        _arguments \
            '1: :->installation' \
            && return 0
        if [[ "$state" == "installation" ]]; then
            _kerl_otp_installations_directories
            _wanted installations expl 'all installations' compadd -a installations
        fi
        ;;
    cleanup)
        if (( "$#words" > 2 )); then
          return
        fi
        _kerl_otp_builds
        builds=('all' "$builds")
        _wanted builds expl 'all builds' compadd -a builds
        ;;
    emit-activate)
        _arguments \
            '1: :->release' \
            '2: :->build_name' \
            '3: :->directory' \
            '4: :->shell' \
            && return 0
        if [[ "$state" == "release" ]]; then
            _kerl_otp_releases
            _wanted releases expl 'all releases' compadd -a releases
        elif [[ "$state" == "build_name" ]]; then
              _kerl_otp_builds
              _wanted builds expl 'all builds' compadd -a builds
        elif [[ "$state" == "directory" ]]; then
            _kerl_otp_installations_names
            _wanted installations expl 'all installations' compadd -a installations
        elif [[ "$state" == "shell" ]]; then
          shells=('sh' 'bash' 'fish' 'csh')
          _wanted shells expl 'supported shells' compadd -a shells
        fi
        ;;
esac
