_stratis()
{
	local cur prev x2prev x3prev 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]}"
	x3prev="${COMP_WORDS[COMP_CWORD-3]}"
	first="${COMP_WORDS[1]}"
	second="${COMP_WORDS[2]}"
	third="${COMP_WORDS[3]}"
	opts="-h --help --version"
	root_subcommands="--help --version daemon pool blockdev filesystem"
	pool_subcommands="create list rename destroy"
	fs_subcommands="create snapshot list rename destroy"
	blockdev_subcommands="add list"
	daemon_subcommands="redundancy version"
	blockdevs="$(echo /dev/disk/*/*) $(lsblk -n -o name -p -l)"

	if [[ ${cur} == -* ]] ; then
		COMPREPLY=( $(compgen -W "${opts}" -- ${cur}) )
		return 0
	else
		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
		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}}' | tr '\n' ' ') -- ${cur}) )
						return 0
						;;
					-h|--help)
						return 0;
				esac
				;;
			blockdev)
				case ${prev} in
					-h|--help)
						return 0
						;;
					add|list)
						COMPREPLY=( $(compgen -W  $(stratis pool list | awk '{if (NR!=1) {print $1}}' | tr '\n' ' ') -- ${cur}) )
						return 0
						;;
				esac
				;;
			daemon)
				return 0
				;;
			pool)
				case ${prev} in
					-h|--help|create|list)
						return 0
						;;
					rename|destroy)
						COMPREPLY=( $(compgen -W  $(stratis pool list | awk '{if (NR!=1) {print $1}}' | tr '\n' ' ') -- ${cur}) )
						return 0
						;;
				esac
				;;
		esac
		case ${x3prev} in
			filesystem|fs)
				case ${x2prev} in
					list|create|-h|--help)
						return 0;
						;;
					snapshot|destroy|rename)
						COMPREPLY=( $(compgen -W  $(stratis filesystem list ${prev} | awk '{if (NR!=1) {print $1}}' ) -- ${cur}) )
						return 0
						;;
				esac
				;;
			blockdev)
				case ${x2prev} in
					-h|--help|list)
						return 0
						;;
					add)
						COMPREPLY=( $(compgen -W  "${blockdevs}" -- ${cur}) )
						return 0
						;;
				esac
				return 0
				;;
			daemon)
				return 0
				;;
			pool)
				case ${x2prev} in
					-h|--help|list|rename|destroy)
						return 0
						;;
					create)
						COMPREPLY=( $(compgen -W  "${blockdevs}" -- ${cur}) )
						return 0
						;;
				esac
		esac

#	Code to handle multiple block device names or multiple filesystem names for filesystem destroy, blockdev add and pool create
		if [[ ${COMP_CWORD} > 3 ]]; 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 $1}}') -- ${cur}) )
							return 0
							;;
					esac
					;;
				pool)
					case ${second} in
						-h|--help|list|rename|destroy)
							return 0
							;;
						create)
							COMPREPLY=( $(compgen -W  "${blockdevs}" -- ${cur}) )
							return 0
							;;
					esac
					;;
				blockdev)
					case ${second} in
						-h|--help|list)
							return 0
							;;
						add)
							COMPREPLY=( $(compgen -W  "${blockdevs}" -- ${cur}) )
							return 0
							;;
					esac
					;;
					
			esac
		fi
		if [[ ${COMP_CWORD} -eq 1 ]]; then
			COMPREPLY=( $(compgen -W "${root_subcommands}" -- ${cur}) )
			return 0
		fi
	fi
	return 0
}
complete -F _stratis stratis
