#!/hint/bash
#
# SPDX-License-Identifier: GPL-3.0-or-later

_DEVTOOLS_LIBRARY_DIR=${_DEVTOOLS_LIBRARY_DIR:-/usr/share/devtools}
# shellcheck source=src/lib/valid-build-install.sh
source "${_DEVTOOLS_LIBRARY_DIR}"/lib/valid-build-install.sh
# shellcheck source=src/lib/valid-tags.sh
source "${_DEVTOOLS_LIBRARY_DIR}"/lib/valid-tags.sh
# shellcheck source=src/lib/valid-repos.sh
source "${_DEVTOOLS_LIBRARY_DIR}"/lib/valid-repos.sh
# shellcheck source=src/lib/valid-inspect.sh
source "${_DEVTOOLS_LIBRARY_DIR}"/lib/valid-inspect.sh
# shellcheck source=src/lib/valid-search.sh
source "${_DEVTOOLS_LIBRARY_DIR}"/lib/valid-search.sh
# shellcheck source=src/lib/valid-version.sh
source "${_DEVTOOLS_LIBRARY_DIR}"/lib/valid-version.sh
# shellcheck source=src/lib/valid-issue.sh
source "${_DEVTOOLS_LIBRARY_DIR}"/lib/valid-issue.sh

_colors=(never always auto)


_makechrootpkg_args=(
	-h
	-c
	-d
	-D
	-u
	-r
	-I
	-l
	-n
	-t
	-T
	-U
	-x
)
_makechrootpkg_args_d_opts() { _filedir -d; }
_makechrootpkg_args_D_opts() { _filedir -d; }
_makechrootpkg_args_r_opts() { _filedir -d; }
_makechrootpkg_args_I_opts() { _filedir '*.pkg.tar.*'; }
_makechrootpkg_args_l_opts() { _filedir -d; }
_makechrootpkg_args_t_opts() { _filedir -d; }
_makechrootpkg_args_U_opts() { :; }
_makechrootpkg_args_x_opts() { _devtools_completions_inspect; }
_makechrootpkg() { __devtools_complete _makechrootpkg; }
complete -F _makechrootpkg makechrootpkg


_makerepropkg_args=(
	-h
	-d
	-n
	-c
	-M
)
_makerepropkg_args_c_opts() { _filedir -d; }
_makerepropkg_args_M_opts() { _filedir '*.conf'; }
_makerepropkg_opts() { _filedir '*.pkg.tar.*'; }
_makerepropkg() { __devtools_complete _makerepropkg; }
complete -F _makerepropkg makerepropkg


_mkarchroot_args=(
	-U
	-C
	-M
	-c
	-f
	-h
)
_mkarchroot_args_U_opts() { _filedir '*.pkg.tar.*'; }
_mkarchroot_args_C_opts() { _filedir '*.conf'; }
_mkarchroot_args_M_opts() { _filedir '*.conf'; }
_mkarchroot_args_c_opts() { _filedir -d; }
_mkarchroot_args_f_opts() { _filedir -d; }
_mkarchroot_opts() {
	local args
	args=$(__pkgctl_word_count_after_subcommand)
	if (( args == 0 )); then
		_filedir -d
	elif (( args >= 1 )); then
		_devtools_completions_all_packages
	fi
}
_mkarchroot() { __devtools_complete _mkarchroot; }
complete -F _mkarchroot mkarchroot


_arch_nspawn_args=(
	-C
	-M
	-c
	-f
	-s
	-h
)
_arch_nspawn_args_C_opts() { _filedir '*.conf'; }
_arch_nspawn_args_M_opts() { _filedir '*.conf'; }
_arch_nspawn_args_c_opts() { _filedir -d; }
_arch_nspawn_args_f_opts() { _filedir; }
_arch_nspawn_opts() {
	local args
	args=$(__pkgctl_word_count_after_subcommand)
	if (( args == 0 )); then
		_filedir -d
	fi
}
_arch_nspawn() { __devtools_complete _arch_nspawn; }
complete -F _arch_nspawn arch-nspawn


_sogrep_args=(
	-v --verbose
	-r --refresh
	-h --help
)
_sogrep_opts() {
	local args
	args=$(__pkgctl_word_count_after_subcommand)
	if (( args == 0 )); then
		_devtools_completions_repo all
	fi
}
_sogrep() { __devtools_complete _sogrep; }
complete -F _sogrep sogrep


_offload_build_args=(
	-r --repo
	-a --arch
	-s --server
	-h --help
)
_offload_build_args__repo_opts() { _devtools_completions_build_repo; }
_offload_build_args_r_opts() { _offload_build_args__repo_opts; }
_offload_build_args__arch_opts() { _devtools_completions_binary_arch; }
_offload_build_args_a_opts() { _offload_build_args__arch_opts; }
_offload_build_args__server_opts() { :; }
_offload_build_args_s_opts() { _offload_build_args__server_opts; }
_offload_build() { __devtools_complete _offload_build; }
complete -F _offload_build offload-build


_pkgctl_cmds=(
	aur
	auth
	build
	db
	diff
	issue
	release
	repo
	search
	version
)
_pkgctl_args=(
	-V --version
	-h --help
)


_pkgctl_auth_cmds=(
	login
	status
)


_pkgctl_auth_login_args=(
	-g --gen-access-token
	-h --help
)


_pkgctl_auth_status_args=(
	-t --show-token
	-h --help
)


_pkgctl_build_args=(
	--arch
	--repo

	-s --staging
	-t --testing
	-o --offload
	-c --clean
	-w --worker
	--inspect
	-I --install-to-chroot
	-i --install-to-host

	--pkgver
	--pkgrel
	--rebuild
	--update-checksums
	-e --edit

	-r --release
	-m --message
	-u --db-update

	-h --help
)
_pkgctl_build_args__arch_opts() { _devtools_completions_binary_arch; }
_pkgctl_build_args__repo_opts() { _devtools_completions_repo; }
_pkgctl_build_args__worker_opts() { :; }
_pkgctl_build_args_w_opts() { _pkgctl_build_args__worker_opts; }
_pkgctl_build_args__inspect_opts() { _devtools_completions_inspect; }
_pkgctl_build_args__pkgver_opts() { :; }
_pkgctl_build_args__pkgrel_opts() { :; }
_pkgctl_build_args__install_to_host_opts() { _pkgctl_build_completions_install_mode; }
_pkgctl_build_args_i_opts() { _pkgctl_build_args__install_to_host_opts; }
_pkgctl_build_args__install_to_chroot_opts() { _makechrootpkg_args_I_opts; }
_pkgctl_build_args_I_opts() { _pkgctl_build_args__install_to_chroot_opts; }
_pkgctl_build_args__message_opts() { :; }
_pkgctl_build_args_m_opts() { _pkgctl_build_args__message_opts; }
_pkgctl_build_opts() { _filedir -d; }
_pkgctl_build_completions_install_mode() {
	mapfile -t COMPREPLY < <(compgen -W "${DEVTOOLS_VALID_BUILD_INSTALL[*]}" -- "$cur")
}


_pkgctl_db_cmds=(
	move
	remove
	update
)


_pkgctl_db_move_args=(
	-h --help
)
_pkgctl_db_move_opts() {
	local subcommand args
	subcommand=(db move)
	args=$(__pkgctl_word_count_after_subcommand "${subcommand[@]}")

	if (( args == 0 )); then
		_devtools_completions_repo
	elif (( args == 1 )); then
		_devtools_completions_repo
	elif (( args >= 2 )); then
		_devtools_completions_all_packages
	fi
}


_pkgctl_db_remove_args=(
	--partial
	--noconfirm
	-a --arch
	-h --help
)
_pkgctl_db_remove_args__arch_opts() { _devtools_completions_binary_arch; }
_pkgctl_db_remove_args_a_opts() { _pkgctl_db_remove_args__arch_opts; }
_pkgctl_db_remove_opts() {
	local subcommand args
	subcommand=(db remove)
	args=$(__pkgctl_word_count_after_subcommand "${subcommand[@]}")

	if (( args == 0 )); then
		_devtools_completions_repo
	elif (( args >= 1 )); then
		_devtools_completions_all_packages
	fi
}


_pkgctl_db_update_args=(
	-h --help
)


_pkgctl_release_args=(
	-m --message
	-r --repo
	-s --staging
	-t --testing
	-u --db-update
	-h --help
)
_pkgctl_release_args__message_opts() { :; }
_pkgctl_release_args_m_opts() { _pkgctl_release_args__message_opts; }
_pkgctl_release_args__repo_opts() { _devtools_completions_repo; }
_pkgctl_release_args_r_opts() { _pkgctl_release_args__repo_opts; }
_pkgctl_release_opts() { _filedir -d; }

_pkgctl_aur_cmds=(
	drop-from-repo
)

_pkgctl_aur_drop_from_repo_args=(
	--no-disown
	-f --force
	-h --help
)
_pkgctl_aur_drop_from_repo_opts() { _filedir -d; }


_pkgctl_repo_cmds=(
	clean
	clone
	configure
	create
	switch
	web
)


_pkgctl_repo_clone_args=(
	-m --maintainer
	--protocol
	--switch
	-u --unprivileged
	--universe
	-j --jobs
	-h --help
)
_pkgctl_repo_clone_args__maintainer_opts() { :; }
_pkgctl_repo_clone_args_m_opts() { _pkgctl_repo_clone_args__maintainer_opts; }
_pkgctl_repo_clone_args__protocol_opts() { _devtools_completions_protocol; }
_pkgctl_repo_clone_args__switch_opts() { :; }
_pkgctl_repo_clone_args__jobs_opts() { :; }
_pkgctl_repo_clone_args_j_opts() { _pkgctl_repo_clone_args__jobs_opts; }
_pkgctl_repo_clone_opts() { _devtools_completions_all_packages; }

_pkgctl_repo_clean_args=(
	-i --interactive
	-n --dry-run
	-h --help
)
_pkgctl_repo_clean_opts() { _filedir -d; }

_pkgctl_repo_configure_args=(
	--protocol
	-j --jobs
	-h --help
)
_pkgctl_repo_configure_args__protocol_opts() { _devtools_completions_protocol; }
_pkgctl_repo_configure_args__jobs_opts() { :; }
_pkgctl_repo_configure_args_j_opts() { _pkgctl_repo_clone_args__jobs_opts; }
_pkgctl_repo_configure_opts() { _filedir -d; }


_pkgctl_repo_create_args=(
	-c --clone
	-h --help
)

_pkgctl_repo_switch_args=(
	--discard-changes
	-f --force
	-h --help
)
_pkgctl_repo_switch_opts() {
	local subcommand args
	subcommand=(repo switch)
	args=$(__pkgctl_word_count_after_subcommand "${subcommand[@]}")

	if (( args == 0 )); then
		:
	elif (( args >= 1 )); then
		_filedir -d;
	fi
}

_pkgctl_license_cmds=(
	check
	setup
)

_pkgctl_license_check_args=(
	-h --help
)

_pkgctl_license_check_opts() { _filedir -d; }

_pkgctl_license_setup_args=(
	--no-check
	-f --force
	-h --help
)

_pkgctl_license_setup_opts() { _filedir -d; }

_pkgctl_version_cmds=(
	check
	setup
	upgrade
)

_pkgctl_version_check_args=(
	-v --verbose
	-h --help
	--json
	-F --format
)

_pkgctl_version_check_opts() { _filedir -d; }
_pkgctl_version_check_args__format_opts() { _devtools_completions_version_output_format; }
_pkgctl_version_check_args_F_opts() { _devtools_completions_version_output_format; }

_pkgctl_version_setup_args=(
	--prefer-platform-api
	--url
	--no-check
	--no-upstream
	-f --force
	-h --help
)

_pkgctl_version_setup_opts() { _filedir -d; }
_pkgctl_version_setup_args__url_opts() { :; }

_pkgctl_version_upgrade_args=(
	--no-update-checksums
	-v --verbose
	-h --help
)

_pkgctl_version_upgrade_opts() { _filedir -d; }

_pkgctl_repo_web_args=(
	--print
	-h --help
)
_pkgctl_repo_web_opts() { _filedir -d; }


_pkgctl_search_args=(
	--no-default-filter
	--json
	-F --format
	-N --no-line-number
	-h --help
)
_pkgctl_search_opts() { :; }
_pkgctl_search_args__format_opts() { _devtools_completions_search_format; }
_pkgctl_search_args_F_opts() { _devtools_completions_search_format; }


_pkgctl_diff_args=(
	-l --list
	-d --diffoscope
	-p --pkginfo
	-b --buildinfo
	-m --makepkg-config
	-u -U --unified
	-y --side-by-side
	--color
	-W --width
	-P --pool
	-v --verbose
	-h --help
)
_pkgctl_diff_args__makepkg_config_opts() { _filedir '*.conf'; }
_pkgctl_diff_args_m_opts() { _pkgctl_diff_args__makepkg_config_opts; }
_pkgctl_diff_args__width_opts() { :; }
_pkgctl_diff_args_W_opts() { _pkgctl_diff_args__width_opts; }
_pkgctl_diff_args__color_opts() { _devtools_completions_color; }
_pkgctl_diff_args__pool_opts() { _filedir -d; }
_pkgctl_diff_args_P_opts() { _pkgctl_diff_args__pool_opts; }
_pkgctl_diff_opts() { _devtools_completions_all_packages; }

_pkgctl_issue_cmds=(
	close
	comment
	create
	edit
	list
	move
	reopen
	view
)

_pkgctl_issue_args=(
	-h --help
)

_pkgctl_issue_close_args=(
	-p --package
	-m --message
	-e --edit
	-r --resolution
	-h --help
)

_pkgctl_issue_close_opts() { :; }
_pkgctl_issue_close_args__package_opts() { _devtools_completions_all_packages; }
_pkgctl_issue_close_args_p_opts() { _pkgctl_issue_close_args__package_opts; }
_pkgctl_issue_close_args__message_opts() { :; }
_pkgctl_issue_close_args_m_opts() { _pkgctl_issue_close_args__message_opts; }
_pkgctl_issue_close_args__resolution_opts() { _devtools_completions_issue_resolution; }
_pkgctl_issue_close_args_r_opts() { _pkgctl_issue_close_args__resolution_opts; }

_pkgctl_issue_comment_args=(
	-p --package
	-m --message
	-e --edit
	-h --help
)

_pkgctl_issue_comment_opts() { :; }
_pkgctl_issue_comment_args__package_opts() { _devtools_completions_all_packages; }
_pkgctl_issue_comment_args_p_opts() { _pkgctl_issue_comment_args__package_opts; }
_pkgctl_issue_comment_args__message_opts() { :; }
_pkgctl_issue_comment_args_m_opts() { _pkgctl_issue_comment_args__message_opts; }

_pkgctl_issue_create_args=(
	-p --package
	-t --title
	-F --file
	-e --edit
	-w --web
	--recover
	--confidentiality
	--priority
	--scope
	--severity
	--status
	-h --help
)

_pkgctl_issue_create_opts() { :; }
_pkgctl_issue_create_args__package_opts() { _devtools_completions_all_packages; }
_pkgctl_issue_create_args_p_opts() { _pkgctl_issue_create_args__package_opts; }
_pkgctl_issue_create_args__title_opts() { :; }
_pkgctl_issue_create_args_t_opts() { _pkgctl_issue_create_args__title_opts; }
_pkgctl_issue_create_args__confidentiality_opts() { _devtools_completions_issue_confidentiality; }
_pkgctl_issue_create_args__priority_opts() { _devtools_completions_issue_priority; }
_pkgctl_issue_create_args__scope_opts() { _devtools_completions_issue_scope; }
_pkgctl_issue_create_args__severity_opts() { _devtools_completions_issue_severity; }
_pkgctl_issue_create_args__status_opts() { _devtools_completions_issue_status; }

_pkgctl_issue_edit_args=(
	-p --package
	-t --title
	-e --edit
	--recover
	--confidentiality
	--priority
	--resolution
	--scope
	--severity
	--status
	-h --help
)

_pkgctl_issue_edit_opts() { :; }
_pkgctl_issue_edit_args__package_opts() { _devtools_completions_all_packages; }
_pkgctl_issue_edit_args_p_opts() { _pkgctl_issue_edit_args__package_opts; }
_pkgctl_issue_edit_args__title_opts() { :; }
_pkgctl_issue_edit_args_t_opts() { _pkgctl_issue_edit_args__title_opts; }
_pkgctl_issue_edit_args__confidentiality_opts() { _devtools_completions_issue_confidentiality; }
_pkgctl_issue_edit_args__priority_opts() { _devtools_completions_issue_priority; }
_pkgctl_issue_edit_args__resolution_opts() { _devtools_completions_issue_resolution; }
_pkgctl_issue_edit_args__scope_opts() { _devtools_completions_issue_scope; }
_pkgctl_issue_edit_args__severity_opts() { _devtools_completions_issue_severity; }
_pkgctl_issue_edit_args__status_opts() { _devtools_completions_issue_status; }

_pkgctl_issue_list_args=(
	-g --group
	-w --web
	-A --all
	-c --closed
	-U --unconfirmed
	--search
	--in
	-l --label
	--confidentiality
	--priority
	--resolution
	--scope
	--severity
	--status
	--assignee
	--assigned-to-me
	--author
	--created-by-me
	-h --help
)

_pkgctl_issue_list_opts() { _devtools_completions_all_packages; }
_pkgctl_issue_list_args__search_opts() { :; }
_pkgctl_issue_list_args__in_opts() { _devtools_completions_issue_search_location; }
_pkgctl_issue_list_args__label_opts() { :; }
_pkgctl_issue_list_args_l_opts() { _pkgctl_issue_list_args__label_opts; }
_pkgctl_issue_list_args__confidentiality_opts() { _devtools_completions_issue_confidentiality; }
_pkgctl_issue_list_args__priority_opts() { _devtools_completions_issue_priority; }
_pkgctl_issue_list_args__resolution_opts() { _devtools_completions_issue_resolution; }
_pkgctl_issue_list_args__scope_opts() { _devtools_completions_issue_scope; }
_pkgctl_issue_list_args__severity_opts() { _devtools_completions_issue_severity; }
_pkgctl_issue_list_args__status_opts() { _devtools_completions_issue_status; }
_pkgctl_issue_list_args__assignee_opts() { :; }
_pkgctl_issue_list_args__author_opts() { :; }

_pkgctl_issue_move_args=(
	-p --package
	-m --message
	-e --edit
	-h --help
)

_pkgctl_issue_move_opts() {
	local subcommand args
	subcommand=(repo switch)
	args=$(__pkgctl_word_count_after_subcommand "${subcommand[@]}")

	if (( args == 0 )); then
		:
	elif (( args >= 1 )); then
		_devtools_completions_all_packages
	fi
}
_pkgctl_issue_move_args__package_opts() { _devtools_completions_all_packages; }
_pkgctl_issue_move_args_p_opts() { _pkgctl_issue_move_args__package_opts; }
_pkgctl_issue_move_args__message_opts() { :; }
_pkgctl_issue_move_args_m_opts() { _pkgctl_issue_move_args__message_opts; }

_pkgctl_issue_reopen_args=(
	-p --package
	-m --message
	-e --edit
	-h --help
)

_pkgctl_issue_reopen_opts() { :; }
_pkgctl_issue_reopen_args__package_opts() { _devtools_completions_all_packages; }
_pkgctl_issue_reopen_args_p_opts() { _pkgctl_issue_reopen_args__package_opts; }
_pkgctl_issue_reopen_args__message_opts() { :; }
_pkgctl_issue_reopen_args_m_opts() { _pkgctl_issue_reopen_args__message_opts; }

_pkgctl_issue_view_args=(
	-p --package
	-c --comments
	-w --web
	-h --help
)

_pkgctl_issue_view_opts() { :; }
_pkgctl_issue_view_args__package_opts() { _devtools_completions_all_packages; }
_pkgctl_issue_view_args_p_opts() { _pkgctl_issue_view_args__package_opts; }


_pkgctl_version_args=(
	-h --help
)


_devtools_completions_color() {
	mapfile -t COMPREPLY < <(compgen -W "${_colors[*]}" -- "$cur")
}
_devtools_completions_arch() {
	mapfile -t COMPREPLY < <(compgen -W "${DEVTOOLS_VALID_ARCHES[*]}" -- "$cur")
}
_devtools_completions_binary_arch() {
	mapfile -t COMPREPLY < <(compgen -W "${DEVTOOLS_VALID_BINARY_ARCHES[*]}" -- "$cur")
}
_devtools_completions_repo() {
	local optional=${1:-}
	mapfile -t COMPREPLY < <(compgen -W "${optional} ${DEVTOOLS_VALID_REPOS[*]}" -- "$cur")
}
_devtools_completions_build_repo() {
	mapfile -t COMPREPLY < <(compgen -W "${DEVTOOLS_VALID_BUILDREPOS[*]}" -- "$cur")
}
_devtools_completions_all_packages() {
	mapfile -t COMPREPLY < <(compgen -W "$(pacman -Sql)" -- "$cur")
}
_devtools_completions_protocol() {
	mapfile -t COMPREPLY < <(compgen -W "https" -- "$cur")
}
_devtools_completions_inspect() {
	mapfile -t COMPREPLY < <(compgen -W "${DEVTOOLS_VALID_INSPECT_MODES[*]}" -- "$cur")
}
_devtools_completions_search_format() {
	mapfile -t COMPREPLY < <(compgen -W "${valid_search_output_format[*]}" -- "$cur")
}
_devtools_completions_version_output_format() {
	mapfile -t COMPREPLY < <(compgen -W "${DEVTOOLS_VALID_VERSION_OUTPUT_FORMAT[*]}" -- "$cur")
}
_devtools_completions_issue_severity() {
	mapfile -t COMPREPLY < <(compgen -W "${DEVTOOLS_VALID_ISSUE_SEVERITY[*]}" -- "$cur")
}
_devtools_completions_issue_status() {
	mapfile -t COMPREPLY < <(compgen -W "${DEVTOOLS_VALID_ISSUE_STATUS[*]}" -- "$cur")
}
_devtools_completions_issue_scope() {
	mapfile -t COMPREPLY < <(compgen -W "${DEVTOOLS_VALID_ISSUE_SCOPE[*]}" -- "$cur")
}
_devtools_completions_issue_search_location() {
	mapfile -t COMPREPLY < <(compgen -W "${DEVTOOLS_VALID_ISSUE_SEARCH_LOCATION[*]}" -- "$cur")
}
_devtools_completions_issue_resolution() {
	mapfile -t COMPREPLY < <(compgen -W "${DEVTOOLS_VALID_ISSUE_RESOLUTION[*]}" -- "$cur")
}
_devtools_completions_issue_priority() {
	mapfile -t COMPREPLY < <(compgen -W "${DEVTOOLS_VALID_ISSUE_PRIORITY[*]}" -- "$cur")
}
_devtools_completions_issue_confidentiality() {
	mapfile -t COMPREPLY < <(compgen -W "${DEVTOOLS_VALID_ISSUE_CONFIDENTIALITY[*]}" -- "$cur")
}

__devtools_complete() {
	local service=$1
	local cur prev

	# Don't break words at : and =
	COMP_WORDBREAKS=${COMP_WORDBREAKS//[:=]}

	cur=$(_get_cword)
	prev=${COMP_WORDS[COMP_CWORD-1]}

	__pkgctl_handle_subcommands "${service}"
	return 0
}

__pkgctl_has_func() {
	declare -f -- "${1}" &>/dev/null
}

__pkgctl_has_array() {
	declare -p -- "${1}" &>/dev/null
}

__pkgctl_is_subcommand() {
	__pkgctl_has_array "${1}"_args || \
		__pkgctl_has_array "${1}"_cmds
}

__pkgctl_words_after_subcommand() {
	local subcommand=("$@")
	local subcommand_idx=0
	local word prev_word
	for ((i = 1; i < ${#COMP_WORDS[@]}; ++i)); do
		word=${COMP_WORDS[i]}
		prev_word=${COMP_WORDS[i-1]}
		# skip options and the current typing
		if [[ ${word} == -* ]] || [[ ${word} == "${cur}" ]]; then
			continue
		fi
		# skip until we resolved the passed subcommand
		if (( subcommand_idx < ${#subcommand[@]} )); then
			if [[ $word == "${subcommand[$subcommand_idx]}" ]]; then
				subcommand_idx=$(( subcommand_idx + 1 ))
			fi
			continue
		fi
		# skip previous options as they belong to the argument
		if [[ ${prev_word} == -* ]] && __pkgctl_has_func "${service_name}_args${prev_word//-/_}_opts"; then
			continue
		fi
		printf "%s\n" "${word}"
	done
}
__pkgctl_word_count_after_subcommand() {
	local subcommand=("$@")
	mapfile -t words < <(__pkgctl_words_after_subcommand "${subcommand[@]}")
	echo "${#words[@]}"
}

__pkgctl_handle_subcommands() {
	local service_name=${1}
	local index=${2:-0}
	local word ref

	# recurse into nested subcommands
	for ((i = index + 1; i < ${#COMP_WORDS[@]}; ++i)); do
		word=${COMP_WORDS[i]}
		if [[ ${word} == -* ]] || [[ ${word} == "${cur}" ]]; then
			continue
		fi
		if __pkgctl_is_subcommand "${service_name}_${word}"; then
			__pkgctl_handle_subcommands "${service_name}_${word}" "${i}"
			return
		fi
	done

	# dynamic argument options
	if [[ $prev == -* ]] && word=${prev//-/_} && __pkgctl_has_func "${service_name}_args${word}_opts"; then
		"${service_name}_args${word}_opts"
	# dynamic subcommand options
	elif [[ $cur != -* ]] && __pkgctl_has_func "${service_name}_opts"; then
		"${service_name}_opts"
	# subcommand argument array
	elif ( ! __pkgctl_has_array "${service_name}"_cmds || [[ $cur == -* ]] ) && __pkgctl_has_array "${service_name}_args"; then
		declare -n ref="${service_name}_args"
		mapfile -t COMPREPLY < <(compgen -W "${ref[*]}" -- "$cur")
	# subcommand array
	elif __pkgctl_has_array "${service_name}"_cmds; then
		declare -n ref="${service_name}_cmds"
		mapfile -t COMPREPLY < <(compgen -W "${ref[*]}" -- "$cur")
	fi
}


_pkgctl() { __devtools_complete _pkgctl; }
complete -F _pkgctl pkgctl
# ex:noet ts=4 sw=4 ft=sh
