#compdef pbpst

# copy this file to /usr/share/zsh/site-functions/_pbpst

typeset -A opt_args
setopt extendedglob

_schm=("http\://" "https\://")

_provs() {
    local -a provider
    provider=( "http://" "https://" $(pbpst -DH) )
    typeset -U provider
    compadd "$@" -a provider
}

# options for passing to _arguments: main pbpst operations
_pbpst_opts_operations=(
    {-S,--sync}'[Create a paste]'
    {-s,--shorten}"[Create a redirect to URL]:URL:($_schm)"
    {-R,--remove}'[Remove a paste]'
    {-U,--update}'[Update a paste]'
    {-D,--database}'[Operate on the database]'
)

# options for passing to _arguments: options common to all operations
_pbpst_opts_common=(
    {-h,--help}'[Display syntax for the given operation]'
    {-b,--dbpath}'[Use the database at PATH]:Database location:_files -./'
    {-P,--provider}"[Specify an alternative pb host]:URL:_provs"
    {-V,--verbose}'[Output verbosely]'
    '--list-lexers[List available lexers and exit]'
    '--list-themes[List available themes and exit]'
    '--list-formats[List available formatters and exit]'
    '--version[List the version and exit]'
)

_lexers() {
    local -a lexer
    lexer=( $(pbpst --list-lexers) )
    typeset -U lexer
    compadd "$@" -a lexer
}

_themes() {
    local -a theme
    theme=( $(pbpst --list-themes) )
    typeset -U theme
    compadd "$@" -a theme
}

_formats() {
    local -a format
    format=( $(pbpst --list-formats) )
    typeset -U format
    compadd "$@" -a format
}

# options for passing to _arguments: options for -S
_pbpst_opts_sync=(
    {-f,--file}'[Create a paste from FILE]:Path to file:_files -./'
    {-l,--lexer}"[Lex paste with LANG]:LANG:_lexers"
    {-T,--theme}"[Style paste with pygments theme THEME]:THEME:_themes"
    {-F,--format}"[Format paste for FORM]:FORM:_formats"
    {-e,--extension}'[Specify MIME-type as EXT]'
    {-L,--line}'[Highlight LINE in paste]'
    {-p,--private}'[Return a less-guessable Id for paste]'
    {-x,--sunset}'[Slate the paste for auto-sunset in SECS seconds]'
    {-r,--render}'[Render paste from rst to HTML]'
    {-t,--term}'[Handle asciinema videos]'
    {-v,--vanity}'[Use NAME as a custom Id]'
    {-\#,--progress}'[Show a progress bar for the upload]'
    {-m,--message}'[Use MSG as the note in the database]'
)

_uuids() {
     local -a uuid
     uuid=( $(pbpst -Dq '' | awk '{ print $1 }') )
     typeset -U uuid
     compadd "$@" -a uuid
}

# options for passing to _arguments: options for -R
_pbpst_opts_remove=(
    {-u,--uuid}'[Use UUID as authentication credential]:UUID:_uuids'
    {-y,--prune}'[Remotely delete all expired pastes]'
)

# options for passing to _arguments: options for -U
_pbpst_opts_update=(
    {-f,--file}'[Create a paste from FILE]:Path to file:_files -./'
    {-l,--lexer}"[Lex paste with LANG]:LANG:_lexers"
    {-T,--theme}"[Style paste with pygments theme THEME]:THEME:_themes"
    {-F,--format}"[Format paste for FORM]:FORM:_formats"
    {-e,--extension}'[Specify MIME-type as EXT]'
    {-L,--line}'[Highlight LINE in paste]'
    {-p,--private}'[Return a less-guessable Id for paste]'
    {-x,--sunset}'[Slate the paste for auto-sunset in SECS seconds]'
    {-r,--render}'[Render paste from rst to HTML]'
    {-t,--term}'[Handle asciinema videos]'
    {-u,--uuid}'[Use UUID as authentication credential]:UUID:_uuids'
    {-\#,--progress}'[Show a progress bar for the upload]'
    {-m,--message}'[Use MSG as the note in the database]'
)

# options for passing to _arguments: options for -D
_pbpst_opts_database=(
    {-i,--init}'[Initalize a default database (no clobbering)]'
    {-H,--providers}'[List all providers in the database]'
    {-q,--query}'[Search the database for a paste matching STR]'
    {-d,--delete}'[Manually delete the paste with UUID]:UUID:_uuids'
    '--set-default[Set default provider]:URL:_provs'
    {-y,--prune}'[Remotely delete all expired pastes]'
)


# handles cases where no operation has yet been given
_pbpst_action_none() {
    _arguments -s : \
        "$_pbpst_opts_common[@]" \
        "$_pbpst_opts_operations[@]"
}

# handles --sync operation
_pbpst_action_sync() {
    _arguments -s : \
        '(--sync -S)'{-S,--sync} \
        "$_pbpst_opts_common[@]" \
        "$_pbpst_opts_sync[@]"
}

# handles --remove operation
_pbpst_action_remove() {
    _arguments -s : \
        '(--remove -R)'{-R,--remove} \
        "$_pbpst_opts_common[@]" \
        "$_pbpst_opts_remove[@]"
}

# handles --update operation
_pbpst_action_update() {
    _arguments -s : \
        '(--update -U)'{-U,--update} \
        "$_pbpst_opts_common[@]" \
        "$_pbpst_opts_update[@]"
}

# handles --database operation
_pbpst_action_database() {
    _arguments -s : \
        '(--database -D)'{-D,--database} \
        "$_pbpst_opts_common[@]" \
        "$_pbpst_opts_database[@]"
}

# main dispatcher
_pbpst() {
    local -a args cmds;
    local tmp
    args=( ${${${(M)words:#-*}#-}:#-*} )
    for tmp in $words; do
        cmds+=("${${_pbpst_opts_operations[(r)*$tmp\[*]%%\[*}#*\)}")
    done
    case $args in #$words[2] in
        h*) (( ${(c)#args} <= 1 && ${(w)#cmds} <= 1 )) && \
                          _pbpst_action_none           || \
                          _message "no more arguments" ;;
        *h*)              _message "no more arguments" ;;
        S*|*--sync*)      _pbpst_action_sync           ;;
        R*|*--remove*)    _pbpst_action_remove         ;;
        U*|*--update*)    _pbpst_action_update         ;;
        D*|*--database*)  _pbpst_action_database       ;;
        *)                _pbpst_action_none           ;;
    esac
}

_pbpst "$@"
