#compdef pamac
# ------------------------------------------------------------------------------
# Description
# -----------
#
#  Completion script for the pamac command
#  (https://gitlab.manjaro.org/applications/pamac).
#
# ------------------------------------------------------------------------------
# Authors
# -------
#
#  * Anton Palgunov <toxblh@gmail.com>
#
# ------------------------------------------------------------------------------
# How to use
# -------
#
# Copy this file to /usr/share/zsh/site-functions/_pamac
#

# Common functions

_pamac_completions_installed_packages() {
	local -a cmd packages
	packages=($(pamac list -q -i))
	compadd "$@" -a packages
}

_pamac_completions_all_packages() {
	local -a cmd packages
  packages=($(pamac list -qr $(pamac list -qr)))
	compadd "$@" -a packages
}

# Build 

_pamac_opts_build=(
 "--builddir[build directory (use with --devel), if no directory is given the one specified in pamac.conf is used]:dir:_files"
 {-k,--keep}'[keep built packages in cache after installation]'
 "--no-keep[do not keep built packages in cache after installation]"
 {-d,--dry-run}'[only print what would be done but do not run the transaction]'
 "--no-clone[do not clone build files from AUR, only use local files]"
 "--no-confirm[bypass any and all confirmation messages]"
)

_pamac_build() {
  _arguments -s : \
  "$_pamac_opts_build[@]" \
  '*:package:_pamac_completions_all_packages'
}

# Checkupdates 

_pamac_opts_checkupdates=(
  "--builddir[build directory (use with --devel), if no directory is given the one specified in pamac.conf is used]:dir:_files"
  {-a,--aur}'[also check updates in AUR]'
  "--no-aur[do not check updates in AUR]"
  {-q,--quiet}'[only print one line per update]'
  "--devel[also check development packages updates (use with --aur)]"
  "--no-devel[do not check development packages updates]"
)

_pamac_checkupdates() {
  _arguments -s : \
  "$_pamac_opts_checkupdates[@]"
}

# Clean

_pamac_opts_clean=(
  {-k,--keep}'[specify how many versions of each package are kept in the cache directory]'
  {-u,--uninstalled}'[only target uninstalled packages]'
  {-b,--build-files}'[remove all build files, the build directory is the one specified in pamac.conf]'
  {-d,--dry-run}'[do not remove files, only find candidate packages]'
  {-v,--verbose}'[also display all files names]'
  "--no-confirm[bypass any and all confirmation messages]"
)

_pamac_clean() {
  _arguments -s : \
  "$_pamac_opts_clean[@]"
}

# Clone

_pamac_opts_clone=(
  "--builddir[build directory, if no directory is given the one specified in pamac.conf file is used]:dir:_files"
  {-r,--recurse}'[also clone needed dependencies]'
  {-q,--quiet}'[do not print any output]'
  "--overwrite[overwrite existing files]"
)

_pamac_clone() {
  _arguments -s : \
  "$_pamac_opts_clone[@]" \
  '*:package:_pamac_completions_all_packages'
}

# Info 

_pamac_opts_info=(
  {-a,--aur}'[also search in AUR]'
  "--no-aur[do not search in AUR]"
)

_pamac_info() {
  _arguments -s : \
  "$_pamac_opts_info[@]" \
  '*:package:_pamac_completions_all_packages'
}

# Install 

_pamac_opts_install=(
  "--ignore[ignore a package upgrade, multiple packages can be specified by separating them with a comma]"
  "--overwrite[overwrite conflicting files, multiple patterns can be specified by separating them with a comma]:files:_files"
  {-w,--download-only}'[download all packages but do not install/upgrade anything]'
  {-d,--dry-run}'[only print what would be done but do not run the transaction]'
  "--as-deps[mark all packages installed as a dependency]"
  "--as-explicit[mark all packages explicitly installed]"
  "--upgrade[check for updates]"
  "--no-upgrade[do not check for updates]"
  "--no-confirm[bypass any and all confirmation messages]"
)

_pamac_install() {
  _arguments -s : \
  "$_pamac_opts_install[@]" \
  '*:package:_pamac_completions_all_packages'
}

# List 


_pamac_opts_list=(
  {-i,--installed}'[list installed packages]'
  {-e,--explicitly-installed}'[list explicitly installed packages]'
  {-o,--orphans}'[list packages that were installed as dependencies but are no longer required by any installed package]'
  {-m,--foreign}'[list packages that were not found in the repositories]'
  {-g,--groups}'[list all packages that are members of the given groups, if no group is given list all groups]'
  {-r,--repos}'[list all packages available in the given repos, if no repo is given list all repos]'
  {-f,--files}'[list files owned by the given packages]'
  {-q,--quiet}'[only print names]'
)
_pamac_list() {
  _arguments -s : \
  "$_pamac_opts_list[@]"
}

# Reinstall

_pamac_opts_reinstall=(
  "--overwrite[overwrite conflicting files, multiple patterns can be specified by separating them with a comma]:files:_files"
  {-w,--download-only}'[download all packages but do not install/upgrade anything]'
  "--as-deps[mark all packages installed as a dependency]"
  "--as-explicit[mark all packages explicitly installed]"
  "--no-confirm[bypass any and all confirmation messages]"
)

_pamac_reinstall() {
  _arguments -s : \
  "$_pamac_opts_reinstall[@]" \
  '*:package:_pamac_completions_installed_packages'
}

# Remove

_pamac_opts_remove=(
  {-u,--unneeded}'[remove packages only if they are not required by any other packages]'
  {-o,--orphans}'[remove dependencies that are not required by other packages, if this option is used without package name remove all orphans]'
  "--no-orphans[do not remove dependencies that are not required by other packages]"
  {-n,--no-save}'[ignore files backup]'
  {-c,--cascade}'[remove all target packages, as well as all packages that depend on one or more target packages]'
  {-d,--dry-run}'[only print what would be done but do not run the transaction]'
  "--no-confirm[bypass any and all confirmation messages]"
)

_pamac_remove() {
  _arguments -s : \
  "$_pamac_opts_remove[@]" \
  '*:package:_pamac_completions_installed_packages'
}

# Search

_pamac_opts_search=(
  {-i,--installed}'[only search for installed packages]'
  {-r,--repos}'[only search for packages in repositories]'
  {-a,--aur}'[also search in AUR]'
  "--no-aur[do not search in AUR]"
  {-f,--files}'[search for packages which own the given filenames (filenames can be partial)]'
  {-q,--quiet}'[only print names]'
)

_pamac_search() {
  _arguments -s : \
  "$_pamac_opts_search[@]"
}

# Update|grade

_pamac_opts_updategrade=(
  "--force-refresh[force the refresh of the databases]"
  "--enable-downgrade[enable package downgrades]"
  "--disable-downgrade[disable package downgrades]"
  {-w,--download-only}'[download all packages but do not install/upgrade anything]'
  {-d,--dry-run}'[only print what would be done but do not run the transaction]'
  "--ignore[ignore a package upgrade, multiple packages can be specified by separating them with comma]:package:_pamac_completions_installed_packages"
  "--overwrite[overwrite conflicting files, multiple patterns can be specified by separating them with comma]"
  "--no-confirm[bypass any and all confirmation messages]"
  {-a,--aur}'[also upgrade packages installed from AUR]'
  "--no-aur[do not upgrade packages installed from AUR]"
  "--devel[also upgrade development packages (use with --aur)]"
  "--no-devel[do not upgrade development packages]"
  "--builddir[build directory (use with --aur), if no directory is given the one specified in pamac.conf file is used]:dir:_files"
)

_pamac_updategrade() {
  _arguments -s : \
  "$_pamac_opts_updategrade[@]"
}


# Main handle
_pamac() {
  local curcontext="$curcontext" ret=1
  local -a state line commands

  commands=(
    "build:Build packages from AUR and install them with their dependencies"
    "checkupdates:Safely check for updates without modifiying the databases"
    "clean:Clean packages cache or build files"
    "clone:Clone or sync packages build files from AUR"
    "info:Display package details, multiple packages can be specified"
    "install:Install packages from repositories, path or url"
    "list:List packages, groups, repositories or files"
    "reinstall:Reinstall packages"
    "remove:Remove packages"
    "search:Search for packages or files, multiple search terms can be specified"
    "update:Update your system"
    "upgrade:Upgrade your system"
  )

  _arguments -C -s -S -n \
    '(- 1 *)'--version"[display version information]: :->full" \
    '(- 1 *)'{-h,--help}'[display usage information]: :->full' \
    '1:cmd:->cmds' \
    '*:: :->args' && ret=0

  case "$state" in
    (cmds)
      _describe -t commands 'commands' commands
    ;;
    (args)
      local cmd
      cmd=$words[1]
      case "$cmd" in
        (build)
            _pamac_build && ret=0
        ;;

        (checkupdates)
            _pamac_checkupdates && ret=0
        ;;

        (clean)
            _pamac_clean && ret=0
        ;;

        (clone)
            _pamac_clone && ret=0
        ;;
        
        (info)
            _pamac_info && ret=0
        ;;

        (install)
            _pamac_install && ret=0
        ;;
        
        (list)
            _pamac_list && ret=0
        ;;

        (reinstall)
            _pamac_reinstall && ret=0
        ;;

        (remove)
            _pamac_remove && ret=0
        ;;

        (search)
            _pamac_search && ret=0
        ;;

        (update|upgrade)
            _pamac_updategrade && ret=0
        ;;

        (*)
            _default && ret=0
        ;;
      esac
    ;;
    (*)
    ;;
  esac

  return ret
}

_pamac
