#compdef pikaur

#
# /usr/share/zsh/site-functions/_pikaur
#
# Licensed under GPLv3, see https://www.gnu.org/licenses/
#

_dispatch pacman pacman

_pikaur_opts_commands=(
	'--pkgbuild	-P[build local PKGBUILDs with AUR deps]'
	'--getpkgbuild -G[download PKGBUILDs from AUR or ABS]'
)

_pikaur_opts_sync_modifiers=(
	'--aur[Query packages from AUR only]'
	'--repo[Query packages from repo only]'
	'--noedit[Bypass editing PKGBUILDs]'
	'--edit[Force editing PKGBUILDs]'
	{--k,--keepbuild}"[don't remove build dir after the build]"
	'--rebuild[always rebuild AUR packages]'
	'--mflags[cli args to pass to makepkg]'
	'--makepkg-config[path to custom makepkg config]'
	'--makepkg-path[override path to makepkg executable]'
	'--namesonly[search only in package names]'
	"--devel[always sysupgrade '-git', '-svn' and other dev packages]"
	"--nodiff[don't prompt to show the build files diff]"
)
_pikaur_opts_sync_search_modifiers=(
	'--namesonly[Search only in package names]'
)


# handles --help subcommand
_pikaur_action_help() {
	_arguments -s : \
		"$_pikaur_opts_commands[@]"
}

# handles cases where no subcommand has yet been given
_pikaur_action_none() {
	_arguments -s : \
		"$_pikaur_opts_commands[@]"
}


# builds command for invoking pacman in a _call_program command - extracts
# relevant options already specified (config file, etc)
# $cmd must be declared by calling function
_pikaur_get_command() {
	# this is mostly nicked from _perforce
	cmd=( "pikaur" "2>/dev/null")
	integer i
	for (( i = 2; i < CURRENT - 1; i++ )); do
		if [[ ${words[i]} = "--config" || ${words[i]} = "--root" ]]; then
			cmd+=( ${words[i,i+1]} )
		fi
	done
}


# provides completions for packages available from repositories
# these can be specified as either 'package' or 'repository/package'
_pikaur_completions_all_packages() {
	local -a seq sep cmd packages repositories packages_long
	_pikaur_get_command

	if [[ ${words[CURRENT-1]} == '--ignore' ]]; then
		seq='_sequence'
		sep=(-S ',')
	else
		seq=
		sep=()
	fi

	if compset -P1 '*/*'; then
		packages=( $(_call_program packages $cmd[@] -Ssq ${words[CURRENT]%/*}) )
		typeset -U packages
		${seq} _wanted repo_packages expl "repository/package" compadd ${sep[@]} ${(@)packages}
	else
		packages=( $(_call_program packages $cmd[@] --namesonly -Ssq ${words[CURRENT]}) )
		typeset -U packages
		${seq} _wanted packages expl "packages" compadd ${sep[@]} - "${(@)packages}"

		repositories=($(pacman-conf --repo-list))
		typeset -U repositories
		_wanted repo_packages expl "repository/package" compadd -S "/" $repositories
	fi
}


_pikaur_action_sync() {
	local context state line
	typeset -A opt_args
	if (( $+words[(r)-s] )); then
		state=sync_search
	elif (( $+words[(r)-Ss] )); then
		state=sync_search
	elif (( $+words[(r)--search] )); then
		state=sync_search
	elif [[ ${words[CURRENT][1]} == '-' ]]; then
		state=sync_opts
	fi

	case $state in
		sync_search)
			_arguments -s : \
				"$_pacman_opts_common[@]" \
				"$_pacman_opts_sync_modifiers[@]" \
				"$_pikaur_opts_sync_search_modifiers[@]" \
				'*:search text: '
			;;
		sync_opts)
			_arguments -s : \
				"$_pacman_opts_common[@]" \
				"$_pacman_opts_sync_actions[@]" \
				"$_pacman_opts_sync_modifiers[@]" \
				"$_pikaur_opts_sync_modifiers[@]"
			;;
		*)
			_arguments -s : \
				"$_pacman_opts_common[@]" \
				"$_pacman_opts_sync_actions[@]" \
				"$_pacman_opts_sync_modifiers[@]" \
				"$_pikaur_opts_sync_modifiers[@]" \
				'*:package:_pikaur_completions_all_packages'
			;;
	esac
}

_pikaur_zsh_comp() {
	local -a args cmds;
	local tmp
	args=( ${${${(M)words:#-*}#-}:#-*} )
	for tmp in $words; do
		cmds+=("${${_pikaur_opts_commands[(r)*$tmp\[*]%%\[*}#*\)}")
	done
	case $args in #$words[2] in
		h*)
			if (( ${(c)#args} <= 1 && ${(w)#cmds} <= 1 )); then
				_pikaur_action_help
			else
				_message "no more arguments"
			fi
			;;
		S*)
			_pikaur_action_sync
			;;
		*)

			case ${(M)words:#--*} in
				*--help*)
					if (( ${(w)#cmds} == 1 )); then
						_pikaur_action_help
					else
						return 0;
					fi
					;;
				*--sync*)
					_pikaur_action_sync
					;;
				*)
					_pikaur_action_none
					;;
			esac
			;;
	esac
}

_pikaur_zsh_comp "$@"
