#compdef emerge rc-update rc-status ebuild opengl-update rc quickpkg

# $Id: _portage,v 1.2 2005/02/22 14:22:54 usata Exp $

# ZSH completion function for Portage
# Author: baptux <bapt@ifrance.com>
# Author: Mamoru KOMACHI <usata@gentoo.org>
# Author: oberyno <oberyno@gmail.com>

# Already done:
#
# emerge (fully done)
# rc-update (fully done)
# rc-status (fully done)
# ebuild (fully done)
# opengl-update (fully done)
# rc (fully done)

# Stuff for rc
_rc () {
	if (( CURRENT == 2 ));then
	    _values "runlevels" $gentoo_runlevels
	fi
}

# Stuff for opengl-update (the easiest to do :) )

_opengl-update () {
	if (( CURRENT == 2 ));then
		_values "opengl-update options" \
		'xorg-x11[Use libGL.so from X.Org]' \
		'xfree[Use libGL.so from XFree86]' \
		'nvidia[Use libGL.so from the NVidia drivers.]'
	fi
}

# Stuff for ebuild
_ebuild () {
	if (( CURRENT == 2 ));then
		       _files -g \*.ebuild
	elif (( CURRENT > 2 ));then
		_values "ebuild command" \
		'clean[Cleans the temporary build directory]' \
		'help[Show help]' \
		'setup[Run all package specific setup actions and exotic system checks.]' \
		'fetch[Fetch all necessary files]' \
		'digest[Creates a digest file for the package]' \
		'unpack[Extracts the sources to a subdirectory in the build directory]' \
		'compile[Compiles the extracted sources by running the src_compile()]' \
		'preinst[Run specific actions that need to be done before installation]' \
		'install[Installs the package to the temporary install directory]' \
		'postinst[Run specific actions that need to be done after installation]' \
		'qmerge[Installs the package de the filesystem]' \
		'merge[perform the following actions: fetch, unpack, compile, install and qmerge.]' \
		'unmerge[Remove the installed files of the packages]' \
		'prerm[Run specific actions that need to be executed before unmerge]' \
		'postrm[Run specific actions that need to be executed after unmerge]' \
		'config[Run specific actions needed to be executed after the emerge process has completed.]' \
		'package[This command is a lot like the merge command, but create a .tbz2 package]' \
		'rpm[Builds a RedHat RPM package]'
	fi

}

# Stuff for rc-status
_rc-status () {
    if (( CURRENT == 2 ));then
    _values "rc-status options" \
	'-a[Show services at all run levels]' \
	'--all[Show services at all run levels]' \
	'-l[Show list of run levels]' \
	'--list[Show list of run levels]' \
	'-u[Show services not assigned to any run level]' \
	'--unused[Show services not assigned to any run level]' \
	$gentoo_runlevels
    fi
}

# Stuff for rc-update

_rc-update () {
local used_init
    used_init=(${=${(M)${(f)"$(rc-update show 2>/dev/null)"}:#*|*[a-z]*}% |*})
    if (( CURRENT == 2 ));then
       _values "rc-update actions" \
       'add[Add script to a runlevel]' \
       'del[Delete script from a runlevel]' \
       'show[Show scripts lanched at a runlevel]' \
       '-a[Add script to a runlevel]' \
       '-d[Delete script from a runlevel]' \
       '-s[Show scripts lanched at a runlevel]'
    elif (( CURRENT == 3 ));then
	case "$words[2]" in
		add|-a)
		 _values "scripts" /etc/init.d/*~*.sh(:t)
		;;
		del|-d)
		_values "scripts" $used_init
		;;
		show|-s)
		    _values "runlevels" $gentoo_runlevels
		;;
	esac
    elif (( CURRENT == 4 ));then
        case "$words[2]" in
		add|-a|del|-d)
		    _values "runlevels" $gentoo_runlevels
		;;
	esac
    fi
}

# Stuff for quickpkg

_quickpkg () {
	if compset -P '(\\|)(>=|<=|<|>|=)'; then
	_arguments -s \
    	    '*:installed package:_gentoo_packages installed_versions'
	  elif compset -P '(\\|)[/]'; then
		_path_files -W / -/
	  else
    		_arguments \
		    '*:installed package:_gentoo_packages installed'
	  fi
}

# Stuff for emerge

_emerge () {
    local nopkg_opts all noask_opts bopts install_args common_args profiles

  noask_opts=(-p -a --pretend --ask --regen --info --search -s --searchdesc \
  -S --version -V --help -h --metadata)

  nopkg_opts=(--resume --skipfirst -c --clean -h --help --depclean --info \
  --metadata -P --prune --regen -s --search -S --searchdesc --sync -C \
  --unmerge -V --version -i --inject)

  bopts=($nopkg_opts -b --buildpkg -B --buildpkgonly -G --getbinpkgonly -g \
  --getbinpkg -k --usepkg -K --usepkgonly --fetch-all-uri -f -F --fetchonly)

  all=($bopts -l --changelog --columns --deep -D --emptytree -e --newuse \
  --noconfmem --nodeps -O --noreplace -n --oneshot -1 -o --onlydeps --tree -t \
  -u --update -U --upgradeonly)

  common_args=(
    "($noask_opts --sync)"{-p,--pretend}"[Simply  display  what would be done]"
    "($noask_opts)"{-a,--ask}"[Ask what would be done]"
    '(-d --debug --help -h --version -V)'{-d,--debug}'[Tells emerge to run the emerge command in debug mode]'
    '(--quiet -q --verbose -v)'{-q,--quiet}'[General outcome is a reduced or condensed output]'
    '(--verbose -v --quiet -q)'{-v,--verbose}'[Tell emerge to run in verbose mode]'
    '--nospinner[Disables the spinner for the session]'
  )
  install_args=(
    "($bopts)"{-b,--buildpkg}"[Tells emerge to build binary packages]"
    "($bopts)"{-B,--buildpkgonly}"[Tells emerge to only build binary packages]"
    "($nopkg_opts --emptytree -e -l --changelog --usepkgonly -K)"{-l,--changelog}"[This will show the ChangeLog]"
    "($nopkg_opts -t --tree)--columns[Displays versions in aligned format]"
    "($nopkg_opts -D --deep)"{-D,--deep}"[Consider the entire dependency tree of packages]"
    "($nopkg_opts -e -l --changelog --emptytree)"{-e,--emptytree}"[Only consider glibc as installed packages]"
    "($all --nospinner --pretend -p)"{-i,--inject}"[Portage thinks that this package is installed]"
    "($nopkg_opts $bopts)"{-f,--fetchonly}"[Just perform fetches for all packages]"
    "($nopkg_opts $bopts)"{-F,--fetch-all-uri}"[Fetch all possible files for all packages]"
    "($bopts)"{-g,--getbinpkg}"[Tells emerge to download binary package]"
    "($bopts)"{-G,--getbinpkgonly}"[As --getbinpkg, but does not use local info]"
    "($nopkg_opts)--noconfmem[Causes portage to disregard merge records]"
    "($nopkg_opts -O --nodeps)"{-O,--nodeps}"[Merges specified packages without merging dependencies]"
    "($nopkg_opts -n --noreplace)"{-n,--noreplace}"[Skip packages already installed]"
    "($nopkg_opts)"{-1,--oneshot}"[Do not add package to the world profile]"
    "($nopkg_opts --onlydeps -o)"{-o,--onlydeps}"[Only merge (or pretend to merge) the dependencies]"
    "($nopkg_opts --columns -t --tree)"{-t,--tree}"[Show dependency tree]"
    "($nopkg_opts --update -u)"{-u,--update}"[Updates packages to the most recent version available]"
    "($nopkg_opts --upgradeonly -U)"{-U,--upgradeonly}"[Do not update packages to a lower version]"
    "($bopts)"{-k,--usepkg}"[Tells emerge to use binary packages if available]"
    "($bopts --changelog -l)"{-K,--usepkgonly}"[Tells emerge to use binary packages only]"
    "($all)"{-c,--clean}"[Cleans the system by removing packages]"
    '(: -)'{-h,--help}'[Displays help]:subject:(sync config system)'
    "(: $all)--depclean[Clean all packages that have no reason for being installed]"
    "(: $all $noask_opts --nospinner --quiet -q)--info[This is a list of information to include in bug reports]"
    "(: -)--metadata[Generate metadata]"
    "($nopkg_opts --usepkgonly -K)--newuse[Include installed packages which have changed USE flags]"
    "($all)"{-P,--prune}"[Removes all but the latest versions of matching packages]"
    "(: $all $noask_opts --verbose -v)--regen[Causes portage to check and update the dependency cache]"
    "(: $all $noask_opts --verbose -v)"{-s,--search}"[Searches for matches]"
    "(: $all $noask_opts --verbose -v)"{-S,--searchdesc}"[Matches the seachdesc string against the description field]"
    "(: $all --pretend -p)--sync[Initiates a portage tree update]"
    "($all)"{-C,--unmerge}"[Removes all matching packages]"
    '(: -)'{-V,--version}'[Display version info]'
    "(: $all[3,-1])--resume[Resumes the last merge operation]"
    "(: $all[3,-1])--skipfirst[Removes the first package in the resume list]"
  )
  profiles=(
    'world[All packages in the world profile]'
    'system[All packages in the system profile]'
  )


  # Dispatch
  if (( $words[(I)(--(unmerge|clean|prune)|-[[:alpha:]]#(C|c|P)[[:alpha:]]#)] )) ; then
	if compset -P '(\\|)(>=|<=|<|>|=)'; then
	    _arguments -s \
		'*:installed package:_gentoo_packages installed_versions' && return 0
	else
	    _arguments -s \
		"$common_args[@]" "$install_args[@]" \
		"*:installed package:_gentoo_packages installed" && return 0
	fi

  elif (( $words[(I)(world|system)] )) ; then
    _arguments -s \
	"$common_args[@]" "$install_args[@]" \
	"($nopkg_opts[1,-2] --inject -i --oneshot -1):" && return 0

  elif (( $words[(I)(--usepkgonly|-[[:alnum:]]#K[[:alnum:]]#)] )) ; then
    _arguments -s \
	"$common_args[@]" "$install_args[@]" \
	'*:binary package:_gentoo_packages binary' && return 0

  elif [[ $words[-3] == (--help|-h) ]] ; then
      _message "No more arguments" && return 0

  else
	if compset -P '(\\|)(>=|<=|<|>|=)'; then
	    _arguments \
		"*:portage:_gentoo_packages available_versions" && return 0

	elif (( $words[(I)(--inject|-i)] )) ; then
	    _arguments -s \
		"$common_args[@]" "$install_args[@]" \
		"*:portage:_gentoo_packages available_versions" && return 0
	else
	    _arguments -s \
		"$common_args[@]" "$install_args[@]" \
		"($nopkg_opts)::portage: _values 'profile' \$profiles[@] " \
		"($nopkg_opts)*:portage:_gentoo_packages available" && return 0
	fi
  fi
}



local gentoo_runlevels
gentoo_runlevels=(/etc/runlevels/*(:t))

case "$service" in
	emerge)
		_emerge "$@" && return 0
		;;
	rc-update)
		_rc-update "$@" && return 0
		;;
	rc-status)
		_rc-status "$@" && return 0
		;;
	ebuild)
		_ebuild "$@" && return 0
		;;
	opengl-update)
		_opengl-update "$@" && return 0
		;;
	rc)
		_rc "$@" && return 0
		;;
	quickpkg)
		_quickpkg "$@" && return 0
		;;

esac
