#compdef eclectic

# vim: set et sw=2 sts=2 ts=2 ft=zsh :
# ZSH completion for `eclectic`
# Written by Ingmar Vanhassel <ingmar@exherbo.org>

_eclectic()
{
  setopt extendedglob
  local _module
  local -a _eclectic_modules

  _eclectic_modules=( ${(M)${(f)"$(_call_program modules eclectic print-modules --descriptions 2>/dev/null)"}:#^} )

  # Figure out what eclectic-module to complete for, if any
  for (( i=1; i <= ${CURRENT}; i++ )); do
    local a=${words[${i}]}
    _module=${_eclectic_modules[(r)${words[${i}]}:*]%%:*}
    (( ${#_module} )) && break
  done

  if (( ${#_module} )); then
    local curcontext="${curcontext%:*:*}:eclectic-${_module}:"

    while [[ ${words[1]} != ${_module} ]]; do
      (( CURRENT-- ))
      shift words
    done

    # Check if there's a function to complete this particular eclectic-module
    # This allows us to override the generic completion for modules that need something fancier
    _call_function ret _eclectic_get_${_module} && return ret
    # Dispatch to generic function to parse 'eclectic ${_module} usage' output
    _call_function ret _eclectic_get_actions && return ret
  else
    local -a _eclectic_global_options
    _eclectic_global_options=( ${(M)${(f)"$(_call_program modules eclectic print-options --descriptions 2>/dev/null)"}:#^} )
    _describe -O 'eclectic global options' \
      _eclectic_global_options
    _describe -t modules 'eclectic module' \
      _eclectic_modules
  fi
}

(( ${+functions[_eclectic_get_actions]} )) ||
_eclectic_get_actions()
{
  local -a _eclectic_module_actions
  _eclectic_module_actions=( ${(M)${(f)"$(_call_program modules eclectic print-actions ${_module} --descriptions 2>/dev/null)"}:#^} )

  for (( i=1; i <= ${CURRENT}; i++ )); do
    local a=${words[${i}]}
    _action=${_eclectic_module_actions[(r)${words[${i}]}:*]%%:*}
    (( ${#_action} )) && break
  done

  if (( ${#_action} )); then
    local curcontext="${curcontext%:*:*}:eclectic-${_module}-${_action}:"

    while [[ ${words[1]} != ${_module} ]]; do
      (( CURRENT-- ))
      shift words
    done

    _call_function ret _eclectic_get_${_action} && return ret
    _call_function ret _eclectic_get_options && return ret
  else
    _describe -t actions 'eclectic module action' \
      _eclectic_module_actions
  fi
}

(( ${+functions[_eclectic_get_options]} )) ||
_eclectic_get_options()
{
  local -a _eclectic_module_action_options opts

  for (( i=1; i <= ${CURRENT}; i++ )); do
    [[ ${words[${i}]} == -* ]] && opts+=( ${words[${i}]} )
  done

  _eclectic_module_action_options=( ${(M)${(f)"$(_call_program modules eclectic print-options ${_module} ${_action} --descriptions ${opts} 2>/dev/null)"}:#^} )

  _describe -O 'eclectic module action option' \
    _eclectic_module_action_options
}

_eclectic "${@}"

