#!/bin/bash
# completion for some pstorage's commands
_pstorage_getputevt_cmd()
{
	local cur prev
        cur="${COMP_WORDS[COMP_CWORD]}"
        prev="${COMP_WORDS[COMP_CWORD-1]}"

	pstorage_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 "$pstorage_getevt_opts" -- "$cur" ) )
			;;
	esac
	return 0
}

_pstorage_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
}

_pstorage_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
}

_pstorage_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
}

_pstorage_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
}

_pstorage_mnttop_cmd()
{
	local cur prev idx cl_id pstorage_mounts once refresh
	cl_id="--client-id"
	pstorage_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" ] && pstorage_mounts=`/bin/mount -t fuse.pstorage | awk '{ print $3 }' 2>/dev/null | tr '\n' ' '`
	pstorage_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 "$pstorage_mnttop_opts $pstorage_mounts" -- "$cur" ) )
		;;
	esac
	return 0
}

_pstorage_make_mds_cmd()
{
	local cur prev netdev addr_list
	COMPREPLY=()
	_get_comp_words_by_ref cur prev
	pstorage_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}'`
			[ $? -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 "$pstorage_make_mds_opts" -- "$cur" ) )
			;;
	esac
	return 0
}

_pstorage_configure_mds_cmd()
{
	local cur prev netdev addr_list
	COMPREPLY=()
	_get_comp_words_by_ref cur prev
	pstorage_make_mds_opts="--set-nodes --repo-dir --mds-node"
	case "$prev" in
		-r|--repo-dir)
			COMPREPLY=( $(compgen -d -S /  -- "$cur" ) )
			;;
		-n|--mds-node)
			;;
		*)
			COMPREPLY=( $( compgen -W "$pstorage_make_mds_opts" -- "$cur" ) )
			;;
	esac
	return 0
}


_pstorage_make_cs_cmd()
{
	local cur prev
	COMPREPLY=()
	_get_comp_words_by_ref cur prev
	pstorage_make_cs_opts="--repo-dir --journal --journal-size --no-checksums --bs-list \
		--user --no-auto-start --tier"
	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)
			;;
		*)
			COMPREPLY=( $( compgen -W "$pstorage_make_cs_opts" -- "$cur" ) )
			;;
	esac
	return 0
}

_pstorage_configure_cs_cmd()
{
	local cur prev
	COMPREPLY=()
	_get_comp_words_by_ref cur prev
	pstorage_tune_cs_opts="--repo-dir --journal-size"
	case "$prev" in
                -r|--repo-dir)
                        COMPREPLY=( $(compgen -d -S /  -- "$cur" ) )
                        ;;
		-s|--journal-size)
			;;
		*)
			COMPREPLY=( $( compgen -W "$pstorage_tune_cs_opts" -- "$cur" ) )
			;;
	esac
	return 0
}


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

_pstorage_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
}

_pstorage_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
}

_pstorage_load_license_cmd()
{
	local cur prev
	COMPREPLY=()
	_get_comp_words_by_ref cur prev
	pstorage_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 "$pstorage_ld_lic_opts" -- "$cur" ) )
	esac
	return 0
}

_pstorage_view_license_cmd()
{
	local cur prev
	COMPREPLY=()
	_get_comp_words_by_ref cur prev
	pstorage_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
			pstorage_view_lic_opts="$pstorage_view_lic_opts --active --check-status"
			break
		fi
		idx=$[$idx+1]
	done
	case "$prev" in
		view-license)
		COMPREPLY=( $( compgen -W "$pstorage_view_lic_opts" -- "$cur" ) )
		;;
		-f|--license-file)
		COMPREPLY=( $( compgen -d -f -- "$cur" ) )
		;;
	esac
	return 0
}

_pstorage_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
}

_pstorage_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_commands()
{
	local cmd=$1
	shift 1
	case $cmd in
	rm-cs)
		_pstorage_rm_cs_cmd
		;;
	make-cs)
		_pstorage_make_cs_cmd
		;;
	configure-cs)
		_pstorage_configure_cs_cmd
		;;
	make-mds)
		_pstorage_make_mds_cmd
		;;
	configure-mds)
		_pstorage_configure_mds_cmd
		;;
	get-event|put-event)
		_pstorage_getputevt_cmd
		;;
	get-attr)
		_pstorage_getattr_cmd
		;;
	set-attr)
		_pstorage_setattr_cmd
		;;
	file-info)
		_pstorage_fileinfo_cmd
		;;
	ls)
		_pstorage_ls_cmd
		;;
	mnt-top)
		_pstorage_mnttop_cmd
		;;
	load-license)
		_pstorage_load_license_cmd
		;;
	view-license)
		_pstorage_view_license_cmd
		;;
	revoke)
		_pstorage_revoke_cmd
		;;
	auth-node)
		_pstorage_authnode_cmd
		;;
	update-license)
		_pstorage_up_lic_cmd
		;;
	list-services)
		_pstorage_list_services
	esac
}

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


_pstorage()
{
	local cur prev
	COMPREPLY=()

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

	pstorage_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 "$pstorage_no_cname_cmds $pstorage_common_opts"  -- "$cur" ) )
		;;
	2)
		case "$prev" in
		discover)
			;;
		get-attr)
			_pstorage_getattr_cmd
			;;
		set-attr)
			_pstorage_setattr_cmd
			;;
		mnt-top)
			_pstorage_mnttop_cmd
			;;
	       view-license)
	                _pstorage_view_license_cmd
			;;
		help)
			COMPREPLY=(  $( compgen -W "$pstorage_cmds" -- "$cur" ) )
			;;
		-c|--cluster)
			clusters=`ls /etc/pstorage/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 $pstorage_cmds; do
			if [ "$cmd" == "$prev" ] ; then
				_handle_commands $cmd
				return 0
			fi
		done
		case "$prev" in
		-c|--cluster)
			clusters=`ls /etc/pstorage/clusters`
			COMPREPLY=( $( compgen -W "$clusters" -- "$cur" ) )
			return 0
			;;
		-q|--silent|-f|--force|-v|--verbose)
			COMPREPLY=(  $( compgen -W "$pstorage_cmds" -- "$cur" ) )
			return 0
			;;
		-t|--timeout)
			return 0
			;;
		*)
			idx=1
			__check_command "${COMP_WORDS[idx]}"
			[ $? -eq 0 ] && return 0
			
			idx=$[COMP_CWORD-1]
			while [ $idx -ge 3 ] ; do
				__check_command "${COMP_WORDS[idx]}"
				[ $? -eq 0 ] && return 0
				idx=$[$idx-1]
			done
			COMPREPLY=(  $( compgen -W "$pstorage_cmds" -- "$cur" ) )
			;;
		esac

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

	esac

	return 0
}

complete -F _pstorage -o nospace pstorage
