#!/bin/bash
# completion for some vstorage-iscsi's commands

_get_iscsi_option()
{
	local short_opt="$1"
	local long_opt="$2"
	local idx=0
	while [ $idx -lt $COMP_CWORD ] ; do
		if [ "x${COMP_WORDS[idx]}" == "x$short_opt" -o "x${COMP_WORDS[idx]}" == "x$long_opt" ]; then
			idx=$[$idx+1]
			echo "${COMP_WORDS[idx]}"
			return
		fi
		idx=$[$idx+1]
	done
}

_get_iscsi_root()
{
	local root=""
	root=`_get_iscsi_option "-r" "--root"`

	if [ -z "$root" ] ; then
		[ -x /usr/libexec/vstorage-iscsi/vstorage_functions ] && source /usr/libexec/vstorage-iscsi/vstorage_functions
		[ -f $ISCSI_ETC/config ] && source $ISCSI_ETC/config
		echo "$ISCSI_ROOT"
		return
	fi

	echo "$root"
}

_get_addr_list()
{
	local netdev=`ip route 2>/dev/null | awk '/default/{print $5}'`
	if [ $? -ne 0 -o -z "$netdev" ]; then
		return 0
	fi

	ip addr show dev $netdev 2>/dev/null | grep inet 2>/dev/null | tr '/' ' ' | awk '{ print $2 }' | tr '\n' ' '
	[ -x /usr/libexec/vstorage-iscsi/fc_functions ] && source /usr/libexec/vstorage-iscsi/fc_functions && fc_hba_wwpn 2>/dev/null
}

_get_target_list() {
	local local_only="$1"
	local root=`_get_iscsi_root`
	local targets=""
	[ -z "$root" ] && return

	ISCSI_ROOT="$root"
	[ -n "$local_only" -a -x /usr/libexec/vstorage-iscsi/vstorage_functions ] && source /usr/libexec/vstorage-iscsi/vstorage_functions
	
	targets="$(ls $root | grep "^iqn*" 2>/dev/null | \
		while read target ; do
			[ ! -d  "$root/$target/control" ] && continue

			if [ -n "$local_only" ]; then
				pcs_iscsi_is_registered_local $target >/dev/null 2>&1
				[ $? -ne 0 ] && continue
			fi

			echo -n "${target} "
		done)"

	echo "${targets}"
}

_get_accounts_list() {
	local root=`_get_iscsi_root`
	local accounts=""
	[ -n "$root" ] && ls "$root/accounts" 2>/dev/null
}

_start_cmd()
{
	local cur prev tlist
	COMPREPLY=()
	_get_comp_words_by_ref -n : cur prev
	start_opts="--target"
	case "$prev" in
		-t|--target)
			tlist=`_get_target_list 1`
			COMPREPLY=( $( compgen -W "$tlist" -- "$cur" ) )
			 __ltrim_colon_completions "$cur"
			;;
		*)
			COMPREPLY=( $( compgen -W "$start_opts" -- "$cur" ) )
			;;
	esac
	return 0
}

_list_target_cmd()
{
	local cur prev tlist
	COMPREPLY=()
	_get_comp_words_by_ref -n : cur prev
	cmd_opts="--all --target --no-header --xml"

	case "${prev}" in
		-t|--target)
			tlist=`_get_target_list 1`
			COMPREPLY=( $( compgen -W "${tlist}" -- "${cur}" ) )
			__ltrim_colon_completions "$cur"
			;;
		-a|--all)
			;;
		-H|--no-header)
			;;
		-X|--xml)
			;;
		*)
			COMPREPLY=( $( compgen -W "$cmd_opts" -- "$cur" ) )
			;;
	esac
	return 0
}

_delete_stop_cmd()
{
	local cur prev
	COMPREPLY=()
	_get_comp_words_by_ref -n : cur prev
	delete_stop_opts="--target --force"
	case "$prev" in
		-t|--target)
			tlist=`_get_target_list 1`
			COMPREPLY=( $( compgen -W "$tlist" -- "$cur" ) )
			 __ltrim_colon_completions "$cur"
			;;
		--force)
			;;
		*)
			COMPREPLY=( $( compgen -W "$delete_stop_opts" -- "$cur" ) )
			;;
	esac
	return 0
}

_create_cmd()
{
	local cur prev addr_list users
	COMPREPLY=()
	_get_comp_words_by_ref cur prev
	create_cmd_opts="--name --address --user"

	case "$prev" in
		-n|--name)
			;;
		-a|--address)
			addr_list=`_get_addr_list`
			COMPREPLY=( $( compgen -W "$addr_list" -- "$cur" ) )
			;;
		-u|--user)
			users=`_get_accounts_list`
			COMPREPLY=( $( compgen -W "$users" -- "$cur" ) )
			;;
		*)
			COMPREPLY=( $( compgen -W "$create_cmd_opts" -- "$cur" ) )
			;;
	esac
	return 0
}

_set_target_cmd()
{
	local cur prev addr_list tlist users
	COMPREPLY=()
	_get_comp_words_by_ref -n : cur prev
	set_cmd_opts="--target --address --user --limit"

	case "$prev" in
		-t|--target)
			tlist=`_get_target_list 1`
			COMPREPLY=( $( compgen -W "$tlist" -- "$cur" ) )
			__ltrim_colon_completions "$cur"
			;;
		-a|--address)
			addr_list=`_get_addr_list`
			COMPREPLY=( $( compgen -W "$addr_list" -- "$cur" ) )
			;;
		-u|--user)
			users=`_get_accounts_list`
			COMPREPLY=( $( compgen -W "$users" -- "$cur" ) )
			;;
		-l|--limit)
			;;
		*)
			COMPREPLY=( $( compgen -W "$set_cmd_opts" -- "$cur" ) )
			;;
	esac
	return 0
}

_lun_add_cmd()
{
	local cur prev tlist lun_list
	COMPREPLY=()
	_get_comp_words_by_ref -n : cur prev
	lun_add_opts="--target --lun --size --serial"

	case "$prev" in
		-t|--target)
			tlist=`_get_target_list 1`
			COMPREPLY=( $( compgen -W "$tlist" -- "$cur" ) )
			__ltrim_colon_completions "$cur"
			;;
		-s|--size)
			;;
		-l|--lun)
			;;
		-N|--serial)
			;;
		*)
			COMPREPLY=( $( compgen -W "$lun_add_opts" -- "$cur" ) )
			;;
	esac
	return 0
}

_lun_grow_cmd()
{
	local cur prev tlist lun_list
	COMPREPLY=()
	_get_comp_words_by_ref -n : cur prev
	lun_grow_opts="--target --lun --size"

	case "$prev" in
		-t|--target)
			tlist=`_get_target_list 1`
			COMPREPLY=( $( compgen -W "$tlist" -- "$cur" ) )
			__ltrim_colon_completions "$cur"
			;;
		-s|--size)
			;;
		-l|--lun)
			;;
		*)
			COMPREPLY=( $( compgen -W "$lun_grow_opts" -- "$cur" ) )
			;;
	esac
	return 0
}


_lun_del_cmd()
{
	local cur prev tlist lun_list
	COMPREPLY=()
	_get_comp_words_by_ref -n : cur prev
	lun_del_opts="--target --lun"

	case "$prev" in
		-t|--target)
			tlist=`_get_target_list 1`
			COMPREPLY=( $( compgen -W "$tlist" -- "$cur" ) )
			__ltrim_colon_completions "$cur"
			;;
		-l|--lun)
			;;
		*)
			COMPREPLY=( $( compgen -W "$lun_del_opts" -- "$cur" ) )
			;;
	esac
	return 0
}

_account_create_cmd()
{
	local cur prev users
	COMPREPLY=()
	_get_comp_words_by_ref cur prev

	cmd_opts="--user --passw"

	case "$prev" in
		-p|--passw)
			;;
		-u|--user)
			;;
		*)
			COMPREPLY=( $( compgen -W "$cmd_opts" -- "$cur" ) )
			;;
	esac
	return 0
}

_account_del_cmd()
{
	local cur prev users
	COMPREPLY=()
	_get_comp_words_by_ref cur prev

	cmd_opts="--user"

	case "$prev" in
		-u|--user)
			users=`_get_accounts_list`
			COMPREPLY=( $( compgen -W "$users" -- "$cur" ) )
			;;
		*)
			COMPREPLY=( $( compgen -W "$cmd_opts" -- "$cur" ) )
			;;
	esac
	return 0
}

_fcoe_cmd()
{
	local cur prev users
	COMPREPLY=()
	_get_comp_words_by_ref cur prev

	cmd_opts="--netdev"

	case "$prev" in
		-n|--netdev)
			[ -x /usr/libexec/vstorage-iscsi/fcoe_functions ] && source /usr/libexec/vstorage-iscsi/fcoe_functions
			list_netdev=`fcoe_list_netdev`
			COMPREPLY=( $( compgen -W "$list_netdev" -- "$cur" ) )
			;;
		*)
			COMPREPLY=( $( compgen -W "$cmd_opts" -- "$cur" ) )
			;;
	esac
	return 0
}


_handle_iscsi_commands()
{
	local cmd=$1
	shift 1
	case $cmd in
		create)
			_create_cmd
			;;
		delete)
			_delete_stop_cmd
			;;
		start)
			_start_cmd
			;;
		stop)
			_delete_stop_cmd
			;;
		register)
			_delete_stop_cmd
			;;
		unregister)
			_start_cmd
			;;
		set)
			_set_target_cmd
			;;
		list)
			_list_target_cmd
			;;
		lun-add)
			_lun_add_cmd
			;;
		lun-del)
			_lun_del_cmd
			;;
		lun-grow)
			_lun_grow_cmd
			;;
		account-create)
			_account_create_cmd
			;;
		account-delete)
			_account_del_cmd
			;;
		account-list)
			_account_del_cmd
			;;
		account-set)
			_account_create_cmd
			;;
		fcoe-create|fcoe-destroy|fcoe-list)
			_fcoe_cmd
			;;
	esac
}

__check_iscsi_command()
{
	local word=$1
	shift 1
	for cmd in $pstorage_iscsi_commands; do
		if [ "$cmd" == "$word" ] ; then
			_handle_iscsi_commands $cmd
			return 0
		fi
	done
	return 1
}

_pstorage_iscsi()
{
	local cur prev
	COMPREPLY=()

	pstorage_iscsi_commands="create delete start stop register unregister set list lun-add lun-del lun-grow \
		snapshot-create snapshot-delete snapshot-list snapshot-switch snapshot-info \
		account-create account-delete account-set account-list fcoe-create fcoe-destroy fcoe-list help"

	cur="${COMP_WORDS[COMP_CWORD]}"
	prev="${COMP_WORDS[COMP_CWORD-1]}"

	if [ $COMP_CWORD -gt 1 ] ; then
		for cmd in $pstorage_iscsi_commands; do
			if [ "$cmd" == "$prev" ] ; then
				_handle_iscsi_commands $cmd
				return 0
			fi
		done

		idx=1
		__check_iscsi_command "${COMP_WORDS[idx]}"
		[ $? -eq 0 ] && return 0

		idx=$[COMP_CWORD-1]
		while [ $idx -ge 3 ] ; do
			__check_iscsi_command "${COMP_WORDS[idx]}"
			[ $? -eq 0 ] && return 0
			idx=$[$idx-1]
		done
	fi

	COMPREPLY=(  $( compgen -W "$pstorage_iscsi_commands" -- "$cur" ) )
	
	return 0
}

complete -F _pstorage_iscsi -o nospace pstorage-iscsi vstorage-iscsi
