_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}"
	root_subcommands="daemon pool blockdev filesystem"
	pool_subcommands="create list add-data add-cache rename destroy"
	fs_subcommands="create snapshot list rename destroy"
	blockdev_subcommands="list"
	daemon_subcommands="redundancy version"
	blockdevs="$(echo /dev/disk/*/*) $(lsblk -n -o name -p -l)"

	if [[ ${cur} == -* ]] ; then
        if [[ ${COMP_CWORD} -eq 1 ]]; then
            COMPREPLY=( $(compgen -W "${global_opts}" -- ${cur}) )
        else
            COMPREPLY=( $(compgen -W "${opts}" -- ${cur}) )
        fi
		return 0
	elif [[ ${COMP_CWORD} -eq 2 ]]; then
		case ${prev} in
			-h|--help|--version)
				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
				;;
		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
					-h|--help|create|list)
						return 0
						;;
					rename|destroy|add-data|add-cache)
						COMPREPLY=( $(compgen -W  "$(stratis pool list | awk '{if (NR!=1) {print $1}}')" -- ${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)
						return 0
						;;
					create|add-data|add-cache)
						COMPREPLY=( $(compgen -W  "${blockdevs}" -- ${cur}) )
						return 0
						;;
				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
			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)
						return 0
						;;
					create|add-cache|add-data)
						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
