#!/bin/bash
# completion for vgt

_vgt() {
	local cur prev cmd_name
	COMPREPLY=()
	cur="${COMP_WORDS[COMP_CWORD]}"
	prev="${COMP_WORDS[COMP_CWORD-1]}"
	cmd_name="${COMP_WORDS[1]}"

	opts="validate-compute validate-cleanup project-suspend project-unsuspend project-purge image-distro-list image-suite-list image-download image-upload image-update"

	opt_list="--host --flavor-name --network-name --image-name --ssh-username --keep-enabled --hosts-to-validate-aggregate --custom-trait-name --project-name --user-name --volume-name --server-name --keypair-name --security-group-name --jump-host --jump-username --jump-port --jump-key-file"

	# The directory holding the image configuration, possibly
	# overridden on the command line being completed.
	local glance_dir
	glance_dir="/etc/vigietools/glance-public-images.d"
	local word
	for word in "${COMP_WORDS[@]}"; do
		case "${word}" in
		"--glance-public-images-dir="*)
			glance_dir="${word#*=}"
		;;
		esac
	done

	# The distribution and the suite given earlier on the command
	# line being completed.
	local distro_name suite_name
	local i
	for ((i = 2; i < COMP_CWORD; i++)); do
		case "${COMP_WORDS[i]}" in
		"--distro="*)
			distro_name="${COMP_WORDS[i]#*=}"
		;;
		"--suite="*)
			suite_name="${COMP_WORDS[i]#*=}"
		;;
		"--distro")
			if ((i + 1 < COMP_CWORD)); then
				distro_name="${COMP_WORDS[i + 1]}"
			fi
		;;
		"--suite")
			if ((i + 1 < COMP_CWORD)); then
				suite_name="${COMP_WORDS[i + 1]}"
			fi
		;;
		esac
	done

	local distro_list suite_list
	if [[ -d "${glance_dir}" ]]; then
		distro_list=$(ls -1 "${glance_dir}" 2>/dev/null)
		if [[ -n "${distro_name}" ]]; then
			# The suites are declared inside the YAML files, not
			# named after them: ask vgt for them.
			suite_list=$(vgt image-suite-list --distro \
				"${distro_name}" \
				--glance-public-images-dir "${glance_dir}" \
				2>/dev/null)
		fi
	fi

	case "${cmd_name}" in
	"validate-compute")
		case ${COMP_CWORD} in
		2|4|6|8|10|12|14|16|18|20)
			COMPREPLY=( $(compgen -W "${opt_list}" -- "${cur}") )
			return 0
		;;
		*)
			case "${prev}" in
			"--image-name")
				local image_list
				mapfile -t image_list < <(
					openstack image list --public --format value -c Name
				)
				local escaped=()
				for img in "${image_list[@]}"; do
					escaped+=( "$(printf '%q' "$img")" )
				done
				COMPREPLY=( $(compgen -W "${escaped[*]}" -- "$cur") )
				return 0
			;;
			"--network-name")
				local network_list
				mapfile -t network_list < <(
					openstack network list --share --format value -c Name
				)
				local escaped=()
				for net in "${network_list[@]}"; do
					escaped+=( "$(printf '%q' "$net")" )
				done
				COMPREPLY=( $(compgen -W "${escaped[*]}" -- "$cur") )
				return 0
			;;
			"--flavor-name")
				local flavor_list
				mapfile -t flavor_list < <(
					openstack flavor list --format value -c Name
				)
				local escaped=()
				for fla in "${flavor_list[@]}"; do
					escaped+=( "$(printf '%q' "$fla")" )
				done
				COMPREPLY=( $(compgen -W "${escaped[*]}" -- "$cur") )
				return 0
			;;
			"--host")
				local host_list
				mapfile -t host_list < <(
					openstack compute service list --format csv | q -H -d, "SELECT Host from - WHERE Binary='nova-compute' AND Status='disabled'"
				)
				local escaped=()
				for comp in "${host_list[@]}"; do
					escaped+=( "$(printf '%q' "$comp")" )
				done
				COMPREPLY=( $(compgen -W "${escaped[*]}" -- "$cur") )
				return 0
			;;
			*)
			;;
			esac
		;;
		esac
	;;
	"validate-cleanup")
		return 0
	;;
	"project-suspend")
		case "${prev}" in
		"--target-project")
			local project_list
			mapfile -t project_list < <(
				openstack project list --format value -c Name
			)
			local escaped=()
			for proj in "${project_list[@]}"; do
				escaped+=( "$(printf '%q' "$proj")" )
			done
			COMPREPLY=( $(compgen -W "${escaped[*]}" -- "$cur") )
			return 0
		;;
		"--tmp-user-role")
			local role_list
			mapfile -t role_list < <(
				openstack role list --format value -c Name
			)
			local escaped=()
			for role in "${role_list[@]}"; do
				escaped+=( "$(printf '%q' "$role")" )
			done
			COMPREPLY=( $(compgen -W "${escaped[*]}" -- "$cur") )
			return 0
		;;
		esac
		COMPREPLY=( $(compgen -W "--target-project --tmp-user-role" -- "${cur}") )
		return 0
	;;
	"project-unsuspend")
		case "${prev}" in
		"--target-project")
			local project_list
			mapfile -t project_list < <(
				openstack project list --format value -c Name
			)
			local escaped=()
			for proj in "${project_list[@]}"; do
				escaped+=( "$(printf '%q' "$proj")" )
			done
			COMPREPLY=( $(compgen -W "${escaped[*]}" -- "$cur") )
			return 0
		;;
		"--tmp-user-role")
			local role_list
			mapfile -t role_list < <(
				openstack role list --format value -c Name
			)
			local escaped=()
			for role in "${role_list[@]}"; do
				escaped+=( "$(printf '%q' "$role")" )
			done
			COMPREPLY=( $(compgen -W "${escaped[*]}" -- "$cur") )
			return 0
		;;
		esac
		COMPREPLY=( $(compgen -W "--target-project --tmp-user-role" -- "${cur}") )
		return 0
	;;
	"project-purge")
		case "${prev}" in
		"--target-project")
			local project_list
			mapfile -t project_list < <(
				openstack project list --format value -c Name
			)
			local escaped=()
			for proj in "${project_list[@]}"; do
				escaped+=( "$(printf '%q' "$proj")" )
			done
			COMPREPLY=( $(compgen -W "${escaped[*]}" -- "$cur") )
			return 0
		;;
		"--tmp-user-role")
			local role_list
			mapfile -t role_list < <(
				openstack role list --format value -c Name
			)
			local escaped=()
			for role in "${role_list[@]}"; do
				escaped+=( "$(printf '%q' "$role")" )
			done
			COMPREPLY=( $(compgen -W "${escaped[*]}" -- "$cur") )
			return 0
		;;
		esac
		COMPREPLY=( $(compgen -W "--target-project --delete-project --tmp-user-role" -- "${cur}") )
		return 0
	;;
	"image-distro-list")
		return 0
	;;
	"image-suite-list")
		case "${prev}" in
		"--distro")
			COMPREPLY=( $(compgen -W "${distro_list}" -- "${cur}") )
			return 0
		;;
		esac
		COMPREPLY=( $(compgen -W "--distro" -- "${cur}") )
		return 0
	;;
	"image-download")
		case "${prev}" in
		"--distro")
			COMPREPLY=( $(compgen -W "${distro_list}" -- "${cur}") )
			return 0
		;;
		"--suite")
			COMPREPLY=( $(compgen -W "${suite_list}" -- "${cur}") )
			return 0
		;;
		"--arch")
			COMPREPLY=( $(compgen -W "amd64 arm64" -- "${cur}") )
			return 0
		;;
		esac
		COMPREPLY=( $(compgen -W "--distro --suite --arch --output --proxy --glance-public-images-dir" -- "${cur}") )
		return 0
	;;
	"image-upload")
		case "${prev}" in
		"--distro")
			COMPREPLY=( $(compgen -W "${distro_list}" -- "${cur}") )
			return 0
		;;
		"--suite")
			COMPREPLY=( $(compgen -W "${suite_list}" -- "${cur}") )
			return 0
		;;
		"--arch")
			COMPREPLY=( $(compgen -W "amd64 arm64" -- "${cur}") )
			return 0
		;;
		esac
		COMPREPLY=( $(compgen -W "--distro --suite --arch --visibility --tag --web-download --proxy --glance-public-images-dir" -- "${cur}") )
		return 0
	;;
	"image-update")
		case "${prev}" in
		"--arch")
			COMPREPLY=( $(compgen -W "amd64 arm64" -- "${cur}") )
			return 0
		;;
		"--stale-method")
			COMPREPLY=( $(compgen -W "hide deactivate both none" -- "${cur}") )
			return 0
		;;
		esac
		COMPREPLY=( $(compgen -W "--arch --visibility --tag --stale-tag --stale-method --delete-stale --web-download --proxy --glance-public-images-dir" -- "${cur}") )
		return 0
	;;
	*)
	;;
	esac

	COMPREPLY=($(compgen -W "${opts}" -- "${cur}"))
}

complete -F _vgt vgt
