_stratis()
{
	local cur prev x2prev opts root_subcommands pool_subcommands fs_subcommands blockdev_subcommands daemon_subcommands complete_pools blockdevs first second third

	COMPREPLY=()

	cur="${COMP_WORDS[COMP_CWORD]}"
	prev="${COMP_WORDS[COMP_CWORD-1]}"
	x2prev="${COMP_WORDS[COMP_CWORD-2]}"
	first="${COMP_WORDS[1]}"
	second="${COMP_WORDS[2]}"
	third="${COMP_WORDS[3]}"
	opts="-h --help"
	global_opts="--version --propagate ${opts}"
	listing_opts="--unhyphenated-uuids"
	root_subcommands="daemon pool blockdev filesystem key report"
	pool_subcommands="add-cache add-data bind create destroy init-cache list rename unbind unlock"
	pool_create_opts="--redundancy --key-desc"
	pool_bind_opts="--thumbprint --trust-url"
	pool_bind_subcommands="nbde tang tpm2"
	pool_unlock_subcommands="clevis keyring"
	fs_subcommands="create snapshot list rename destroy"
	blockdev_subcommands="list"
	daemon_subcommands="redundancy version"
	key_subcommands="set unset reset list"
	key_set_reset_opts="--keyfile-path --capture-key"
	blockdevs="$(echo /dev/disk/*/*) $(lsblk -n -o name -p -l)"

	if [[ ${prev} == "--redundancy" ]]; then
		COMPREPLY=( $(compgen -W "none" -- ${cur}) )
		return 0
	elif [[ ${prev} == "--key-desc" ]]; then
		return 0
	elif [[ ${cur} == -* ]] ; then
        if [[ ${COMP_CWORD} -eq 1 ]]; then
            COMPREPLY=( $(compgen -W "${global_opts} ${opts}" -- ${cur}) )
	elif [[ ${second} == "list" ]]; then
	    COMPREPLY=( $(compgen -W "${opts} ${listing_opts}" -- ${cur}) )
        elif [[ ${first} == "pool" ]]; then
			if [[ ${second} == "create" ]]; then
				COMPREPLY=( $(compgen -W "${pool_create_opts} ${opts}" -- ${cur}) )
			elif [[ ${second} == "bind" ]] && [[ ${third} != "tpm2" ]]; then
				COMPREPLY=( $(compgen -W "${pool_bind_opts} ${opts}" -- ${cur}) )
			else
				COMPREPLY=( $(compgen -W "${opts}" -- ${cur}) )
			fi
			
			return 0
        	
        elif [[ ${first} == "key" ]]; then
        	case ${second} in
        		set|reset)
					COMPREPLY=( $(compgen -W "${key_set_reset_opts} ${opts}" -- ${cur}) )
					return 0
					;;
				unset)
					COMPREPLY=( $(compgen -W "${opts}" -- ${cur}) )
					return 0
					;;
        	esac
        	
        else
            COMPREPLY=( $(compgen -W "${opts}" -- ${cur}) )
        fi
		return 0
	elif [[ ${COMP_CWORD} -eq 2 ]]; then
		case ${prev} in
			-h|--help|--version|report)
				return 0
				;;
			filesystem|fs)
				COMPREPLY=( $(compgen -W "${fs_subcommands}" -- ${cur}) )
				return 0
				;;
			blockdev)
				COMPREPLY=( $(compgen -W "${blockdev_subcommands}" -- ${cur}) )
				return 0
				;;
			daemon)
				COMPREPLY=( $(compgen -W "${daemon_subcommands}" -- ${cur}) )
				return 0
				;;
			pool)
				COMPREPLY=( $(compgen -W "${pool_subcommands}" -- ${cur}) )
				return 0
				;;
			key)
				COMPREPLY=( $(compgen -W "${key_subcommands}" -- ${cur}) )
				return 0
				;;
		esac
	elif [[ ${COMP_CWORD} -eq 3 ]]; then
		case ${x2prev} in
			filesystem|fs)
				case ${prev} in
					create|snapshot|list|destroy|rename)
						COMPREPLY=( $(compgen -W  "$(stratis pool list | awk '{if (NR!=1) {print $1}}')" -- ${cur}) )
						return 0
						;;
					-h|--help)
						return 0;
				esac
				;;
			blockdev)
				case ${prev} in
					-h|--help)
						return 0
						;;
					list)
						COMPREPLY=( $(compgen -W  "$(stratis pool list | awk '{if (NR!=1) {print $1}}')" -- ${cur}) )
						return 0
						;;
				esac
				;;
			daemon)
				return 0
				;;
			pool)
				case ${prev} in
					unlock)
						COMPREPLY=( $(compgen -W "${pool_unlock_subcommands}" -- ${cur}) )
						return 0
						;;
					bind)
						COMPREPLY=( $(compgen -W "${pool_bind_subcommands}" -- ${cur}) )
						;;
					-h|--help|create|list|unlock)
						return 0
						;;
					rename|destroy|add-data|add-cache|init-cache|unbind)
						COMPREPLY=( $(compgen -W  "$(stratis pool list | awk '{if (NR!=1) {print $1}}')" -- ${cur}) )
						return 0
						;;
				esac
				;;
			key)
				case ${prev} in
					unset|list)
						return 0
						;;
					set|reset)
						COMPREPLY=( $(compgen -W "${key_set_reset_opts}" -- ${cur}) )
						return 0
						;;
				esac
				;;
		esac
	elif [[ ${COMP_CWORD} -eq 4 ]]; then
		case ${first} in
			filesystem|fs)
				case ${second} in
					list|create|-h|--help)
						return 0;
						;;
					snapshot|destroy|rename)
						COMPREPLY=( $(compgen -W  "$(stratis filesystem list ${third} | awk '{if (NR!=1) {print $2}}')" -- ${cur}) )
						return 0
						;;
				esac
				;;
			blockdev)
				return 0
				;;
			daemon)
				return 0
				;;
			pool)
				case ${second} in
					-h|--help|list|rename|destroy|unbind|unlock)
						return 0
						;;
					create|add-data|add-cache|init-cache)
						COMPREPLY=( $(compgen -W  "${blockdevs}" -- ${cur}) )
						return 0
						;;
					bind)
						COMPREPLY=( $(compgen -W  "$(stratis pool list | awk '{if (NR!=1) {print $1}}')" -- ${cur}) )
						return 0
						;;
				esac
				;;
			key)
				case ${second} in
					unset|list)
						return 0
						;;
					set|reset)
						case ${third} in
							--capture-key)
								return 0
								;;
							--keyfile-path)
								COMPREPLY=( $(compgen -f -- ${cur}) )
								return 0
								;;
						esac
						;;
				esac
				;;
		esac
#	Code to handle multiple block device names or multiple filesystem names for filesystem destroy and pool create/add-data/add-cache
	elif [[ ${COMP_CWORD} > 4 ]]; then
		case ${first} in
			key|daemon|report|blockdev)
				return 0
				;;
			filesystem|fs)
				case ${second} in
					snapshot|list|create|rename|-h|--help)
						return 0
						;;
					destroy)
						COMPREPLY=( $(compgen -W  "$(stratis filesystem list ${third} | awk '{if (NR!=1) {print $2}}')" -- ${cur}) )
						return 0
						;;
				esac
				;;
			pool)
				case ${second} in
					-h|--help|list|rename|destroy|bind|unbind|unlock)
						return 0
						;;
					create|add-cache|add-data|init-cache)
						if [[ ${third} == "--redundancy" && ${COMP_CWORD} -eq 5 ]]; then
							return 0
						fi
						COMPREPLY=( $(compgen -W  "${blockdevs}" -- ${cur}) )
						return 0
						;;
				esac
				;;
		esac
	elif [[ ${COMP_CWORD} -eq 1 ]]; then
		COMPREPLY=( $(compgen -W "${root_subcommands} ${global_opts}" -- ${cur}) )
		return 0
	elif [[ ${prev} == "--propagate" ]]; then
		COMPREPLY=( $(compgen -W "${root_subcommands}" -- ${cur}) )
	fi
	return 0
}
complete -F _stratis stratis
