#!/usr/local/bin/bash
#
# Copyright (c) 2008, Christopher Cowart and contributors
# All rights reserved.
# 
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions 
# are met:
# * Redistributions of source code must retain the above copyright 
#   notice, this list of conditions and the following disclaimer.
# * Redistributions in binary form must reproduce the above copyright 
#   notice, this list of conditions and the following disclaimer in the 
#   documentation and/or other materials provided with the distribution.
# 
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED 
# TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 
# PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 
# LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 
# NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 
# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#
# $Id: confman_completion.in 330 2009-05-07 03:54:38Z ccowart $
#
#						TODO
#
#		* Right now this won't update module listings until they
#		  get added to the recipe file.

_confman() 
{
	local cur prev cmds twoback cmds fd_cmds mod_cmds chkpt_cmds
	local CONFMAN CONFMAN_CONF CONFMAN_RC RECIPE_PATH WORK_PATH

	# Setup ConfMan specific vars
	CONFMAN="/usr/local/sbin/confman"
	CONFMAN_CONF="/usr/local/etc/confman.conf"
	CONFMAN_RC=~/.confmanrc
	if [ -e ${CONFMAN_RC} ] ; then
		RECIPE_PATH=$(grep '^RECIPE_PATH' ${CONFMAN_RC}|cut -d'"' -f2)
		WORK_PATH=$(grep '^WORK_PATH' ${CONFMAN_RC}|cut -d'"' -f2)
	elif [ -e ${CONFMAN_CONF} ] ; then
		RECIPE_PATH=$(grep '^RECIPE_PATH' ${CONFMAN_CONF}|cut -d'"' -f2)
		WORK_PATH=$(grep '^WORK_PATH' ${CONFMAN_CONF}|cut -d'"' -f2)
	fi
	RECIPE_PATH=$(eval echo $RECIPE_PATH)
	WORK_PATH=$(eval echo $WORK_PATH)

	# Setup Standard command completion vars
	COMPREPLY=()
	cur="${COMP_WORDS[COMP_CWORD]}"
	prev="${COMP_WORDS[COMP_CWORD-1]}"
	if [ ${#COMP_WORDS[*]} -gt 3 ] ; then
	    twoback="${COMP_WORDS[COMP_CWORD-2]}"
	fi
	if [ ${#COMP_WORDS[*]} -gt 4 ] ; then
	    threeback="${COMP_WORDS[COMP_CWORD-3]}"
	fi
	[ ! -x $CONFMAN ] && echo "confman support not available!!" && exit 1
	
	# These vars are to better organize things to complete to as well as 
	# provide loose documention about what this does.
	#
	#	fd_cmds:	commands that take files and directories as args
	#	mod_cmds:	commands that take modules as args
	#	chkpt_cmds:	commands that take modules that take checkpoints as args
	#				Ex. confman checknew MODULE CHECKPOINT
	#								/\ A chkpt_cmd
	#	cmds:		commands that confman can take as the first arg
	#
	fd_cmds="rm cp mv mkdir ls chown chgrp chmod chcom log install revert ln chln"
	mod_cmds="create rmmod import checklook checknew checkclear rollback"
	# 'rollback' is also a chkpt_cmd, but needs to be handled separately
	# because it's the only one that handles dated checkpoints.
	chkpt_cmds="checklook checknew checkclear"
	cmds="help setup update commit diff status rollback $fd_cmds $mod_cmds"
	
	if [ "${prev}" == "confman" -o "${prev}" == "help" ] ; then
		COMPREPLY=($(compgen -W "${cmds}" -- ${cur}))  
		return 0
	elif [ `expr "${fd_cmds}" : ".*\(${prev}\).*"` ] ; then
		COMPREPLY=( $(compgen -A directory -A file ${cur}) )
		return 0
	elif [ `expr "${mod_cmds}" : ".*\(${prev}\).*"` ] ; then
		local modules=$(confman recipe print $(confman recipe get) | \
            grep -vE '^#|^$' $RECIPE_PATH | tr '\n' ' ')
		COMPREPLY=($(compgen -W "${modules}" -- ${cur}))
		return 0
	elif [ `expr "import ${fd_cmds}" : ".*\(${twoback}\).*"` ] ; then
		COMPREPLY=($(compgen -A directory -A file ${cur}))
		return 0
	elif [ `expr "${chkpt_cmds}" : ".*\(${twoback}\).*"` ] ; then
		local module=${prev}
		local checkpoints=$(confman checklook ${module}|tr '\n' ' ')
		COMPREPLY=($(compgen -W "${checkpoints}" -- ${cur}))
		return 0
	elif [ "rollback" == "${twoback}" ] ; then
		local module=${prev}
		local module_path="${WORK_PATH}/${module}"
		local named_checkpoints=$(confman checklook ${module}|\
						tr '\n' ' '
					)
		local numbered_checkpoints=$(confman log $module_path|grep '^r[0-9][0-9]*' |\
			sed 's/.*\(20[0-9][0-9]\)-\([0-9][0-9]\)-\([0-9][0-9]\).*/"\1\2\3"/'|\
			tr '\n' ' ')
		checkpoints="${named_checkpoints} ${numbered_checkpoints}"
		COMPREPLY=($(compgen -W "${checkpoints}" -- ${cur}))
		return 0
	elif [ "rollback" == "${threeback}" ] ; then
		local module=${twoback}
		local module_path="${WORK_PATH}/${module}"
		local day=${prev:0:4}-${prev:4:2}-${prev:6:2}
		local hoursmins=$(confman log $module_path|grep '^r[0-9][0-9]*' |\
					grep 2006-04-06|\
					sed 's/.*20[0-9][0-9]-[0-9][0-9]-[0-9][0-9] \([0-9][0-9]\):\([0-9][0-9]\).*/"\1\2"/'|\
					tr '\n' ' '
				)
		COMPREPLY=($(compgen -W "${hoursmins}" -- ${cur}))
		return 0
	fi

	return 0
}

# It's necessary to not define a catch-all completion above so that we 
# can use the '-o filenames' switch to best handle {file,dir}name
# completions.
complete -F _confman -o filenames confman

# vim:ts=4
