#compdef zplug

local    curcontext="$curcontext" state
local    p desc
local -i ret=1
local -a -U zplug_cmds
local -a _zplug_boolean_true _zplug_boolean_false
local -a cmds tags

cmds=( "$ZPLUG_ROOT"/autoload/commands/__*__(:t:gs:_:) )
tags=( "$ZPLUG_ROOT"/autoload/tags/__*__(:t:gs:_:) )

_zplug_boolean_true=("true" "yes" "on" 1)
_zplug_boolean_false=("false" "no" "off" 0)

zplug_cmds=(
'check:check whether an update or install is available'
'clean:remove a package'
'clear:remove cache file'
'install:install a package in parallel'
'list:list installed packages with its tags information'
'load:load an installed package'
'status:check if remote branch is up-to-date'
'update:freshen up a installed package in parallel'
'info:information about a package'
)

# Completions for user-defined commands
for p in ${^path}/zplug-*(N-.)
do
    desc="$(sed -n '2p' "$p" | sed -E 's/^.*[Dd]esc(ription)?: ?//')"
    desc="${desc:+"\[User-defined\] $desc"}"
    zplug_cmds+=("${p:t:gs:zplug-:}:${desc:-"User-defined command"}")
done

_arguments \
    '(-)--help[show help message]: :->comp' \
    '(-)--version[version information]: :' \
    '(-)--log=[view zplug error log]: :->log' \
    '*:: :->comp' && return 0

if (( CURRENT == 1 )); then
    _describe -t commands "zplug subcommand" zplug_cmds
    return 0
fi

case "$words[1]" in
    check)
        _arguments \
            '(--verbose)--verbose[show non-installed items in output]' \
            '*:: :( "${(k)zplugs[@]}" )'
        ret=0
        ;;
    update)
        _arguments \
            '(- 1 *)--self[update zplug by itself]' \
            '(--select)--select[select items with interactive filters]' \
            '*:: :( "${(k)zplugs[@]}" )'
        ret=0
        ;;
    install)
        _arguments \
            '(--verbose)--verbose[show non-installed items in output]' \
            '(--select)--select[select items with interactive filters]' \
            '*:: :compadd -X "%F{green}Accept%f %Busername/reponame%b arguments"'
        ret=0
        ;;
    load)
        _arguments \
            '(--verbose)--verbose[display loading files]'
        ret=0
        ;;
    status|list)
        _arguments \
            '(--select)--select[select items with interactive filters]' \
            '*:: :( "${(k)zplugs[@]}" )'
        ret=0
        ;;
    clean)
        _arguments \
            '(--force --select)--force[force the removing activity]' \
            '(--select --force)--select[select items with interactive filters]' \
            '*:: :( "${(k)zplugs[@]}" )'
        ret=0
        ;;
    clear)
        _arguments \
            '(--force)--force[force the removing activity]'
        ret=0
        ;;
    info)
        _arguments \
            '*:: :( "${(k)zplugs[@]}" )'
        ret=0
        ;;
    */*)
        _values -S : -s , "zplug tags" \
            "as[Specify whether to register as commands or to register as plugins]:as:(plugin command)" \
            "use[Specify the pattern to source (for plugin) or relative path to export (for command)]:use:->use" \
            "from[Specify the services you use to install]:from:(gh-r gist oh-my-zsh github bitbucket local)" \
            "at[Support branch/tag installation]:at:" \
            "rename-to[Specify filename you want to rename]:rename-to:" \
            "dir[Installation directory (RO)]:dir:->dir" \
            "if[Specify the conditions under which to source or add to \$PATH]:if:" \
            "hook-build[Commands to run after installation/update]:hook-build:" \
            "hook-load[Commands to run after loading]:hook-load:" \
            "frozen[Do not update unless explicitly specified]:frozen:->boolean" \
            "on[Dependencies (RO)]:on:->on" \
            "defer[Priority of loading the plugins]:defer:->defer" \
            "ignore[Specify exception pattern so as not to load the files]:ignore:" \
            "lazy[Lazy loading]:lazy:->boolean" \
            "depth[Clone depth]:depth:({0..10})" && ret=0
        case $state in
            on|dir)
                compadd -X "%F{green}READ ONLY%f %Bno arguments%b"
                ;;
            use)
                compadd -J 'command/plugin' -X "%F{yellow}Completing%f %BExample patterns%b" \
                    '*.zsh' \
                    '*.sh' \
                    'zsh/*.zsh' \
                    '*.plugin.zsh' \
                    'init.zsh'
                compadd -J 'gh-r' -X "%F{yellow}Completing%f %BGitHub Releases (example)%b" \
                    'amd64' \
                    'darwin*amd64' \
                    'linux*amd64' \
                    '386' \
                    'darwin*386' \
                    'linux*386' \
                    'darwin' \
                    'linux'
                ;;
            defer)
                compadd -V 'default' -X "%F{yellow}Completing%f %Bpriority (default)%b" 0
                compadd -V 'defer' -X "%F{yellow}Completing%f %Bpriority%b" -- 1
                compadd -V 'after_compinit' -X "%F{yellow}Completing%f %Bpriority (after compinit)%b" 2 3
                ;;
            boolean)
                compadd -J 'boolean/true' -X "%F{yellow}Completing%f %Btrue word%b" $_zplug_boolean_true
                compadd -J 'boolean/false' -X "%F{yellow}Completing%f %Bfalse word%b" $_zplug_boolean_false
                ;;
        esac
        ;;
esac

case $state in
    "comp")
        is_help="yes"
        _describe -t help_cmds "commands" cmds
        _describe -t help_tags "tags" tags
        return 0
        ;;
    "log")
        compadd -J 'log/jq' -X "%F{yellow}Completing%f %Bwith jq%b" \
            'jq'
        compadd -J 'log/pager' -X "%F{yellow}Completing%f %Bwith pager%b" \
            'less' \
            'more'
        compadd -J 'log/edit' -X "%F{yellow}Completing%f %Bwith editor%b" \
            'edit'
        compadd -J 'log/log' -X "%F{yellow}Completing%f %Bwith log%b" \
            'oneline' \
            'clear' \
            'count' \
            'latest'
esac

return ret
