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

_vstorage_get_cluster_name()
{
	local cluster_name=""
	local idx=0
        while [ $idx -lt $COMP_CWORD ] ; do
                if [ "x${COMP_WORDS[idx]}" == "x-c" -o "x${COMP_WORDS[idx]}" == "x--cluster" ]; then
			idx=$[$idx+1]
			cluster_name="${COMP_WORDS[idx]}"
                        break
                fi
                idx=$[$idx+1]
        done
	echo "$cluster_name"
}

_vstorage_getputevt_cmd()
{
	local cur prev
        cur="${COMP_WORDS[COMP_CWORD]}"
        prev="${COMP_WORDS[COMP_CWORD-1]}"

	vstorage_getevt_opts="--dbg --info --warn --err --sub --tail --last-day \
		--last-week --last-month --server-time --src-addr --both-time"

	COMPREPLY=()
	case "$prev" in
		-s|--sub)
			COMPREPLY=( $( compgen -W "journal mds cs fuse clnt monitor tools test admin" -- "$cur" ) )
			;;
		*)
			COMPREPLY=( $( compgen -W "$vstorage_getevt_opts" -- "$cur" ) )
			;;
	esac
	return 0
}

_vstorage_setattr_cmd()
{
	local cur prev
	local attr="failure-domain replicas tier mds-storage raid0 client-ssd-cache"
	COMPREPLY=()
	_get_comp_words_by_ref cur prev
	case "$prev" in
		set-attr|-p|-R)
			COMPREPLY=(  $( compgen -f -d -- "$cur" ) )
			;;
		*)
			COMPREPLY=( $( compgen -W "$attr" -- "$cur" ) )
			;;
	esac
	return 0
}

_vstorage_getattr_cmd()
{
	local cur prev
	COMPREPLY=()
	_get_comp_words_by_ref cur prev
	case "$prev" in
		-p|get-attr)
		COMPREPLY=(  $( compgen -f -d -- "$cur" ) )
		;;
	esac
	return 0
}

_vstorage_fileinfo_cmd()
{
	local cur prev
	COMPREPLY=()
	_get_comp_words_by_ref cur prev
	case "$prev" in
		-p|file-info)
			COMPREPLY=(  $( compgen -f -d -- "$cur" ) )
			;;
	esac
	return 0
}

_vstorage_ls_cmd()
{
	local cur prev
	COMPREPLY=()
	_get_comp_words_by_ref cur prev
	case "$prev" in
		-p|ls)
		COMPREPLY=(  $( compgen  -f -d -- "$cur" ) )
		;;
		-X|--xml)
		;;
	esac
	return 0
}

_vstorage_mnttop_cmd()
{
	local cur prev idx cl_id vstorage_mounts once refresh
	cl_id="--client-id"
	vstorage_mounts=""
	once="--once"
	refresh="--refresh-time"
	COMPREPLY=()
	idx=0
	while [ $idx -lt $COMP_CWORD ] ; do
		if [ "x${COMP_WORDS[idx]}" == "x-i" -o "x${COMP_WORDS[idx]}" == "x--client-id" ]; then
			cl_id=""
		fi
		if [ "x${COMP_WORDS[idx]}" == "x-1" -o "x${COMP_WORDS[idx]}" == "x--once" ]; then
			once=""
		fi
		if [ "x${COMP_WORDS[idx]}" == "x-T" -o "x${COMP_WORDS[idx]}" == "x--refresh-time" ]; then
			refresh=""
		fi
		idx=$[$idx+1]
	done
	[ -n "$cl_id" ] && vstorage_mounts=`/bin/mount -t fuse.vstorage | awk '{ print $3 }' 2>/dev/null | tr '\n' ' '`
	vstorage_mnttop_opts="$cl_id $once $refresh"
	_get_comp_words_by_ref cur prev
	case "$prev" in
		-l|--latency-sort|-C|--cache-fstat-sort|-f|--fstat-sort)
		;;
		-T|--refresh-time|-i|--client-id)
		;;
		*)
		COMPREPLY=(  $( compgen -W "$vstorage_mnttop_opts $vstorage_mounts" -- "$cur" ) )
		;;
	esac
	return 0
}

_vstorage_get_ip_addrs() {
	local netdev="$1"
	for d in $netdev; do
		ip addr show dev $d | grep inet | tr '/' ' ' | awk '{ print $2 }' | tr '\n' ' '
	done
}

_vstorage_make_mds_cmd()
{
	local cur prev netdev addr_list
	COMPREPLY=()
	_get_comp_words_by_ref cur prev
	vstorage_make_mds_opts="--init-cluster --repo-dir --id --address --mds-node \
	--bs-list --no-auto-start --user --manual"
	case "$prev" in
		-r|--repo-dir)
			COMPREPLY=( $(compgen -d -S /  -- "$cur" ) )
			;;
		-u|--user)
			COMPREPLY=( $(compgen -u  -- "$cur" ) )
			;;
		-i|--id|-n|--mds-node|-b|--bs-list)
			;;
		-a|--address)
			netdev=`ip route | awk '/default/{print $5}' | tr '\n' ' '`
			[ $? -ne 0 -o -z "$netdev" ] && return 0
			addr_list=$(_vstorage_get_ip_addrs "$netdev" 2>/dev/null)
			[ $? -ne 0 -o -z "$netdev" ] && return 0
			COMPREPLY=( $( compgen -W "$addr_list" -- "$cur" ) )
			;;
		*)
			COMPREPLY=( $( compgen -W "$vstorage_make_mds_opts" -- "$cur" ) )
			;;
	esac
	return 0
}

_vstorage_configure_mds_cmd()
{
	local cur prev netdev addr_list srv_list cluster_name
	COMPREPLY=()

	_get_comp_words_by_ref cur prev

	vstorage_make_mds_opts="--repo-dir --mds-node --drop-node --compact"
	case "$prev" in
		-r|--repo-dir)
                        srv_list=""
                        cluster_name=`_vstorage_get_cluster_name`
                        [ -n "$cluster_name" ] && srv_list=`cat /etc/vstorage/clusters/$cluster_name/mds.list 2>/dev/null | grep -e "^\/"`
                        if [ -n "$srv_list" ] ; then
                                COMPREPLY=( $( compgen -W "$srv_list" -- "$cur" ) )
                        else
                                COMPREPLY=( $(compgen -d -S /  -- "$cur" ) )
                        fi
			;;
		-C|--compact)
			;;
		-d|--drop-node)
			;;
		-n|--mds-node)
			;;
		*)
			COMPREPLY=( $( compgen -W "$vstorage_make_mds_opts" -- "$cur" ) )
			;;
	esac
	return 0
}


_vstorage_make_cs_cmd()
{
	local cur prev
	COMPREPLY=()
	_get_comp_words_by_ref cur prev


	vstorage_make_cs_opts="--repo-dir --journal --journal-size --no-checksums --bs-list \
		--user --no-auto-start --tier --address"
	case "$prev" in
                -r|--repo-dir)
                        COMPREPLY=( $(compgen -d -S /  -- "$cur" ) )
                        ;;
                -u|--user)
                        COMPREPLY=( $(compgen -u  -- "$cur" ) )
                        ;;
		-j|--journal|-s|--journal-size)
			;;
		-t|--tier)
			;;
		-b|--bs-list)
			;;
		-a|--address)
			netdev=`ip route | awk '/default/{print $5}'`
			[ $? -ne 0 -o -z "$netdev" ] && return 0
			addr_list=`ip addr show dev $netdev | grep inet | tr '/' ' ' | awk '{ print $2 }' | tr '\n' ' '`
			[ $? -ne 0 -o -z "$netdev" ] && return 0
			COMPREPLY=( $( compgen -W "$addr_list" -- "$cur" ) )
			;;

		*)
			COMPREPLY=( $( compgen -W "$vstorage_make_cs_opts" -- "$cur" ) )
			;;
	esac
	return 0
}

_vstorage_configure_cs_cmd()
{
	local cur prev netdev addr_list cluster_name srv_list
	COMPREPLY=()
	_get_comp_words_by_ref cur prev

	vstorage_tune_cs_opts="--repo-dir --journal-size --unlink-journal --destroy-journal --add-journal --set-address"
	case "$prev" in
                -r|--repo-dir)
			srv_list=""
			cluster_name=`_vstorage_get_cluster_name`
			[ -n "$cluster_name" ] && srv_list=`cat /etc/vstorage/clusters/$cluster_name/cs.list 2>/dev/null | grep -e "^\/"`
			if [ -n "$srv_list" ] ; then
				COMPREPLY=( $( compgen -W "$srv_list" -- "$cur" ) )
			else	
	                        COMPREPLY=( $(compgen -d -S /  -- "$cur" ) )
			fi
                        ;;
		-s|--journal-size)
			;;
		-a|--add-journal)
			COMPREPLY=( $(compgen -d -S /  -- "$cur" ) )
			;;
		-u|--unlink-journal)
			;;
		-d|--destroy-journal)
			;;
		-L|--set-address)
                        netdev=`ip route | awk '/default/{print $5}'`
                        [ $? -ne 0 -o -z "$netdev" ] && return 0
                        addr_list=`ip addr show dev $netdev | grep inet | tr '/' ' ' | awk '{ print $2 }' | tr '\n' ' '`
                        [ $? -ne 0 -o -z "$netdev" ] && return 0
                        COMPREPLY=( $( compgen -W "$addr_list" -- "$cur" ) )
                        ;;
		*)
			COMPREPLY=( $( compgen -W "$vstorage_tune_cs_opts" -- "$cur" ) )
			;;
	esac
	return 0
}

_vstorage_rm_cs_cmd()
{
	local cur prev
	COMPREPLY=()
	_get_comp_words_by_ref cur prev
	vstorage_rm_cs_opts="--wait --cancel"
	[ "$prev" == "rm-cs" ] && COMPREPLY=( $( compgen -W "$vstorage_rm_cs_opts" -- "$cur" ) )
	return 0
}

_vstorage_up_lic_cmd()
{
	local cur prev
	COMPREPLY=()
	_get_comp_words_by_ref cur prev
	case "$prev" in
		-s|--server)
		;;
		*)
		COMPREPLY=( $( compgen -W "--server --no-check" -- "$cur" ) )
		;;
	esac
}

_vstorage_list_services() {
	local cur prev
	COMPREPLY=()
	_get_comp_words_by_ref cur prev
	local list_serv_opts="--mds-only --cs-only"
	case "$prev" in
		--mds-only|-M)
			;;
		--cs-only|-C)
			;;
		*)
		COMPREPLY=( $( compgen -W "$list_serv_opts" -- "$cur" ) )
	esac
}

_vstorage_load_license_cmd()
{
	local cur prev
	COMPREPLY=()
	_get_comp_words_by_ref cur prev
	vstorage_ld_lic_opts="--license-file --stdin --product-key"
	case "$prev" in
		-p|--product-key|-i|--stdin)
		;;
		-f|--license-file)
		COMPREPLY=( $( compgen -d -f -- "$cur" ) )
		;;
		*)
		COMPREPLY=( $( compgen -W "$vstorage_ld_lic_opts" -- "$cur" ) )
	esac
	return 0
}

_vstorage_view_license_cmd()
{
	local cur prev
	COMPREPLY=()
	_get_comp_words_by_ref cur prev
	vstorage_view_lic_opts="--license-file --product-key --stdin"
	idx=0
	while [ $idx -lt $COMP_CWORD ] ; do
		if [ "x${COMP_WORDS[idx]}" == "x-c" -o "x${COMP_WORDS[idx]}" == "x--cluster" ]; then
			vstorage_view_lic_opts="$vstorage_view_lic_opts --active --check-status"
			break
		fi
		idx=$[$idx+1]
	done
	case "$prev" in
		view-license)
		COMPREPLY=( $( compgen -W "$vstorage_view_lic_opts" -- "$cur" ) )
		;;
		-f|--license-file)
		COMPREPLY=( $( compgen -d -f -- "$cur" ) )
		;;
	esac
	return 0
}

_vstorage_revoke_cmd()
{
	local cur prev
	COMPREPLY=()
	_get_comp_words_by_ref cur prev
	case "$prev" in
		-I)
		;;
		*)
		COMPREPLY=( $( compgen -d -f -- "$cur" ) )
		;;
		
	esac
	return 0
}

_vstorage_authnode_cmd()
{
        local cur prev
        COMPREPLY=()
        _get_comp_words_by_ref cur prev
        local auth_opts="--change-password --stdin-password --bs-list"
        case "$prev" in
                --bs-list|-b)
                        ;;
                *)
                COMPREPLY=( $( compgen -W "$auth_opts" -- "$cur" ) )
        esac
}

_handle_vstorage_commands()
{
	local cmd=$1
	shift 1
	case $cmd in
	rm-cs)
		_vstorage_rm_cs_cmd
		;;
	make-cs)
		_vstorage_make_cs_cmd
		;;
	configure-cs)
		_vstorage_configure_cs_cmd
		;;
	make-mds)
		_vstorage_make_mds_cmd
		;;
	configure-mds)
		_vstorage_configure_mds_cmd
		;;
	get-event|put-event)
		_vstorage_getputevt_cmd
		;;
	get-attr)
		_vstorage_getattr_cmd
		;;
	set-attr)
		_vstorage_setattr_cmd
		;;
	file-info)
		_vstorage_fileinfo_cmd
		;;
	ls)
		_vstorage_ls_cmd
		;;
	mnt-top)
		_vstorage_mnttop_cmd
		;;
	load-license)
		_vstorage_load_license_cmd
		;;
	view-license)
		_vstorage_view_license_cmd
		;;
	revoke)
		_vstorage_revoke_cmd
		;;
	auth-node)
		_vstorage_authnode_cmd
		;;
	update-license)
		_vstorage_up_lic_cmd
		;;
	list-services)
		_vstorage_list_services
	esac
}

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


_vstorage()
{
	local cur prev
	COMPREPLY=()

	vstorage_common_opts="--cluster --silent --force --verbose --timeout"
	vstorage_no_cname_cmds="discover get-attr set-attr revoke mnt-top view-license help"

	vstorage_cmds="make-mds make-cs rm-mds rm-cs advise-configuration \
		top stat get-event put-event get-attr mnt-top \
		set-attr file-info get-config set-config mds-log-tail \
		auth-node discover load-license view-license update-license revoke ls \
		configure-mds configure-cs list-services"

	cur="${COMP_WORDS[COMP_CWORD]}"
	prev="${COMP_WORDS[COMP_CWORD-1]}"
	
	case $COMP_CWORD in
	1)
		COMPREPLY=( $( compgen -W "$vstorage_no_cname_cmds $vstorage_common_opts"  -- "$cur" ) )
		;;
	2)
		case "$prev" in
		discover)
			;;
		get-attr)
			_vstorage_getattr_cmd
			;;
		set-attr)
			_vstorage_setattr_cmd
			;;
		mnt-top)
			_vstorage_mnttop_cmd
			;;
	       view-license)
	                _vstorage_view_license_cmd
			;;
		help)
			COMPREPLY=(  $( compgen -W "$vstorage_cmds" -- "$cur" ) )
			;;
		-c|--cluster)
			clusters=`ls /etc/vstorage/clusters`
			COMPREPLY=( $( compgen -W "$clusters" -- "$cur" ) )
			;;
		-v|--verbose)
			COMPREPLY=( $( compgen -W "discover help --cluster --force --verbose --timeout" -- "$cur" ) )
			;;
		-f|--force)
			COMPREPLY=( $( compgen -W "discover help --cluster --silent --verbose --timeout" -- "$cur" ) )
			;;
		-q|--silent)
			COMPREPLY=( $( compgen -W "discover help --cluster --force --timeout" -- "$cur" ) )
			;;
		esac
		;;
	*)
		for cmd in $vstorage_cmds; do
			if [ "$cmd" == "$prev" ] ; then
				_handle_vstorage_commands $cmd
				return 0
			fi
		done
		case "$prev" in
		-c|--cluster)
			clusters=`ls /etc/vstorage/clusters`
			COMPREPLY=( $( compgen -W "$clusters" -- "$cur" ) )
			return 0
			;;
		-q|--silent|-f|--force|-v|--verbose)
			COMPREPLY=(  $( compgen -W "$vstorage_cmds" -- "$cur" ) )
			return 0
			;;
		-t|--timeout)
			return 0
			;;
		*)
			idx=1
			__check_vstorage_command "${COMP_WORDS[idx]}"
			[ $? -eq 0 ] && return 0
			
			idx=$[COMP_CWORD-1]
			while [ $idx -ge 3 ] ; do
				__check_vstorage_command "${COMP_WORDS[idx]}"
				[ $? -eq 0 ] && return 0
				idx=$[$idx-1]
			done
			COMPREPLY=(  $( compgen -W "$vstorage_cmds" -- "$cur" ) )
			;;
		esac

		case ${COMP_WORDS[COMP_CWORD-2]} in
			-c|--cluster)
				COMPREPLY=(  $( compgen -W "$vstorage_cmds" -- "$cur" ) )
				;;
		esac

	esac

	return 0
}

complete -F _vstorage -o nospace vstorage pstorage
