#!/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/iscsi_functions ] && source /usr/libexec/vstorage-iscsi/iscsi_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' ' '
}

_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/iscsi_functions ] && source /usr/libexec/vstorage-iscsi/iscsi_functions
	
	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 ""
}

_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 cur prev
	start_opts="--target"
	case "$prev" in
		-t|--target)
			tlist=`_get_target_list 1`
			COMPREPLY=( $( compgen -W "$tlist" -- "$cur" ) )
			;;
                *)
                        COMPREPLY=( $( compgen -W "$start_opts" -- "$cur" ) )
                        ;;
	esac
	return 0
}

_list_target_cmd()
{
	local cur prev tlist
	COMPREPLY=()
	_get_comp_words_by_ref cur prev
	cmd_opts="--all --target --no-header --xml"
	case "$prev" in
		-t|--target)
			tlist=`_get_target_list 1`
			COMPREPLY=( $( compgen -W "$tlist" -- "$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 cur prev
	delete_stop_opts="--target --force"
	case "$prev" in
		-t|--target)
			tlist=`_get_target_list 1`
			COMPREPLY=( $( compgen -W "$tlist" -- "$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 cur prev
	set_cmd_opts="--target --address --user"

	case "$prev" in
		-t|--target)
			tlist=`_get_target_list 1`
			COMPREPLY=( $( compgen -W "$tlist" -- "$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" ) )
			;;
                *)
                        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 cur prev
	lun_add_opts="--target --lun --size --serial"

	case "$prev" in
		-t|--target)
			tlist=`_get_target_list 1`
			COMPREPLY=( $( compgen -W "$tlist" -- "$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 cur prev
	lun_grow_opts="--target --lun --size"

	case "$prev" in
		-t|--target)
			tlist=`_get_target_list 1`
			COMPREPLY=( $( compgen -W "$tlist" -- "$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 cur prev
	lun_del_opts="--target --lun"

	case "$prev" in
		-t|--target)
			tlist=`_get_target_list 1`
			COMPREPLY=( $( compgen -W "$tlist" -- "$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
}

_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
			;;
	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 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
