# **** License ****
# Version: VPL 1.0
# 
# The contents of this file are subject to the Vyatta Public License
# Version 1.0 ("License"); you may not use this file except in
# compliance with the License. You may obtain a copy of the License at
# http://www.vyatta.com/vpl
# 
# Software distributed under the License is distributed on an "AS IS"
# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
# the License for the specific language governing rights and limitations
# under the License.
# 
# This code was originally developed by Vyatta, Inc.
# Portions created by Vyatta are Copyright (C) 2006, 2007 Vyatta, Inc.
# All Rights Reserved.
# 
# Author: Tom Grennan
# Date: 2007
# Description: setup bash completion for Vyatta operational commands
# 
# **** End License ****

test -f /etc/default/vyatta && \
    source /etc/default/vyatta

test ! -d "$vyatta_op_templates" && \
    return 0

declare _vyatta_op_last_comp

# $1: label
# #2...: strings
_vyatta_op_debug ()
{
    echo -ne \\n$1:
    shift
    for s ; do
	echo -ne " \"$s\""
    done
}

_vyatta_op_init ()
{
    for xd in $vyatta_op_templates/* ; do
	if [ -d $xd ] ; then
	    cmd=${xd##*/}
	    complete -F _vyatta_op_expand $cmd
	    eval alias $cmd=\'_vyatta_op_run $cmd\'
	fi
    done

    bind 'set show-all-if-ambiguous on'
    shopt -s histverify
}

_vyatta_op_get_node_def_field ()
{
    local file=$1 field=$2

    sed -n '/^'"$field"':/,$ {
# strip field name and hold rest of line
    s/[a-z]*: *//
    h
    :b
# at EOF, print hold buffer and quit
    $ { x; p; q }
# input next line
    n
# if start of another field def, print hold buf and quit
    /^[a-z]*:/ { x; p; q }
# add to hold buf and branch to input next line
    H
    bb
    }' $file
}

# $1: label
# $2...: help
_vyatta_op_print_help ()
{
    local label=$1 ; shift
    local -i len=12

    if [ ${#label} -lt $len ] ; then
	printf "\n  %-${len}s\t%b" "$label" "$*"
    else
	printf "\n  %s\n\t\t%b" "$label" "$*"
    fi
}

# $1: $cur
# $2: $node_path
# $3...: possible completions
_vyatta_op_help ()
{
    local cur=$1; shift
    local node_path=$1; shift
    local ndef node_tag_help help

    ndef=$node_path/node.tag/node.def
    [ -f $ndef ] && \
	node_tag_help=$( _vyatta_op_get_node_def_field $ndef help )

    echo -en "\nPossible completions:"
    for comp ; do
	if [ -z "$comp" ] ; then
	    _vyatta_op_print_help '*' "$node_tag_help"
	elif [[ -z "$cur" || $comp == ${cur}* ]] ; then
	    ndef=$node_path/$comp/node.def
	    if [ -f $ndef ] ; then
		help=$( _vyatta_op_get_node_def_field $ndef help )
	    else
		help=$node_tag_help
	    fi
	    _vyatta_op_print_help "$comp" "$help"
	fi
    done
}

# $1: cur
# $2...: comps
_vyatta_op_compreply ()
{
    local cur=$1; shift

    COMPREPLY=($( compgen -W "$*" -- $cur ))

    # if the last command line arg is empty and we have
    # an empty completion option (meaning wild card),
    # append a blank(s) to the completion array to force ambiguity
    if [ -z "$cur" ] ; then
	for comp ; do
	    if [ -z "$comp" ] ; then
		if [ ${#COMPREPLY[@]} -eq 0 ] ; then
		    COMPREPLY+=( " " "" )
		else
		    COMPREPLY+=( " " )
		fi
	    fi
	done
    fi

    if [ "${COMP_WORDS[*]}" == "$_vyatta_op_last_comp" ] ; then
	_vyatta_op_help "$cur" "$node_path" "${comps[@]}"
	COMPREPLY=( "" " " )
	_vyatta_op_last_comp=""
    else
	_vyatta_op_last_comp="${COMP_WORDS[*]}"
    fi
}

_vyatta_op_expand ()
{
    local cur=${COMP_WORDS[COMP_CWORD]}
    local node_path=$vyatta_op_templates
    local -a comps
    local restore_shopts=$( shopt -p extglob nullglob | tr \\n \; )
    shopt -s extglob nullglob

    for (( i=0 ; i<COMP_CWORD ; i++ )) ; do
	if [ -f "$node_path/${COMP_WORDS[i]}/node.def" ] ; then
	    node_path+=/${COMP_WORDS[i]}
	elif [ -f $node_path/node.tag/node.def ] ; then
	    node_path+=/node.tag
	else
	    echo -e \\a
	    COMPREPLY=( "" " " )
	    return 1
	fi
    done

    for ndef in $node_path/*/node.def ; do
	if [[ $ndef == */node.tag/node.def ]] ; then
	    local acmd=$( _vyatta_op_get_node_def_field $ndef allowed )
	    local -a a=($( eval "$acmd" ))
	    if [ ${#a[@]} -ne 0 ] ; then
		comps+=( "${a[@]}" )
	    else
		comps+=( "" )
	    fi
	else
	    local sdir=${ndef%/*}
	    comps+=( ${sdir##*/} )
	fi
    done

    _vyatta_op_compreply "$cur" "${comps[@]}"

    eval $restore_shopts
}

_vyatta_op_run ()
{
    local -i estat
    local tpath=$vyatta_op_templates
    local restore_shopts=$( shopt -p extglob nullglob | tr \\n \; )
    shopt -s extglob nullglob

    _vyatta_op_last_comp=""
    false; estat=$?
    for arg ; do
	if [ -f "$tpath/$arg/node.def" ] ; then
	    tpath+=/$arg
	elif [ -f $tpath/node.tag/node.def ] ; then
	    tpath+=/node.tag
	else
	    echo "Invalid command" >&2
	    return 1
	fi
    done
    eval "$(_vyatta_op_get_node_def_field $tpath/node.def run)"
    eval $restore_shopts
}

# don't initialize if we are in configure mode
if [ "$_OFR_CONFIGURE" == "ok" ]; then
  return 0
fi

_vyatta_op_init $@

###  Local Variables:
###  mode: shell-script
###  End: