#!/bin/bash
#
# ::copy::
# ::maintainer::
#
# run across trac cache (bzr checkouts) dir, and update each project
# checkout inside
#
#
CMD=`basename $0`
VERBOSE=false
DEBUG=false


# get library functions
#
export TOOLKIT="::env.TOOLKIT::"
export LOGFILE="/var/log/$CMD.log"
export KU_LOCKFILE="/var/lock/$CMD.lock"
export PID=$$	# add pid in log entry

. /lib/ku-base/log.sh
. /lib/ku-base/lock.sh
. /lib/ku-base/libfiles.sh




# (FUNCTIONS)

usage()
{
	echo "
usage: $CMD [options]

options:
  -v|--verbose		be verbose
  -q|--quiet		be quiet (default)
  -D|--debug		activate debug
" >&2
	exit 1
}

flush_errfile()
{
	if [ `wc -c $errfile | sed -e 's/ .*//'` == 1 ]
	then
		ku_log " error: `cat $errfile`"
	else
		ku_log " errors occurred, stderr dump follows:"
		ku_loglines <$errfile
	fi
	return 1
}

exit_err()
{
	local status=$1
	flush_errfile
	cleanup
	ku_log "exited with errors, status=$status"
	exit $status
}

cleanup()
{
	$DEBUG && mv $tmpdir /tmp/$CMD-debug || rm -rf $tmpdir
	ku_lock_remove
}

# ritorna elenco sorted di directories + descrizione categoria
# se esiste file trac_datadir/etc/categorysort, altrimenti solo
# elenco dirs
#
get_sorted_projects()
{
	local categorysort=$trac_datadir/etc/categorysort
	local dir=
	local projects=
	local match=
	local sortval=
	local desc=
	local found=
	local line=

	for dir in `ls`
	do
		[ -d $dir/.bzr ] && projects="$projects $dir"
	done

	[ -f $categorysort ] || {	# no sorting
		categorysort=$tmpdir/default_categorysort
		echo '99 .* Projects' >$categorysort
	}

	cp /dev/null $tmpfile
	for dir in $projects
	do
		found=false

		exec 9<&0 <$categorysort
		while read sortval match desc
		do
			echo "$sortval" | egrep -q "^#|^$" && continue	# skip comments & empty lines

			echo "$dir" | egrep -q "$match" && {
				echo "$sortval|$dir|$desc" >>$tmpfile
				found=true
				break
			}
		done
		exec 0<&9 9<&-
		$found || echo "9999|$dir|" >>$tmpfile
	done

	sort -g $tmpfile | while read line
	do
		dir=`echo "$line" | cut -d'|' -f2`
		desc=`echo "$line" | cut -d'|' -f3`
		echo "$dir|$desc"
	done
	rm -f $tmpfile
	return 0
}



# (MAIN)

# sanity checks
#
[ "`id -u`" != 0 ] && {
	echo "error: this command must be run by 'root' user only" >&2
	exit 1
}


# parse parms
#
while [ $# != 0 ]
do
    case $1 in
    	-v|--verbose)	VERBOSE="true" ;;
	-q|--quiet)	VERBOSE="false" ;;
	-D|--debug)	DEBUG="true" ;;
	#-n|--dry-run)	TEST_ONLY="true" ;;
	--)		break ;;
	-*|"")		usage ;;
	*)		usage ;;
    esac
    shift
done

[ $# != 0 ] && usage


# init logging
#
ku_cap_logfile

# check if another instance is running
# if not, try to obtain a lock
#
ku_lock_is_active && {
	ku_log "another process is running, quit"
	exit 0
}
err=`ku_lock` || {
	ku_log "$err"
	exit 1
}
ku_log "started"


tmpdir=`mktemp -d /tmp/$CMD-XXXXXXXXXX`	|| exit $?
errfile="$tmpdir/err"
outfile="$tmpdir/out"
tmpfile="$tmpdir/tmp"
htmfile="$tmpdir/htm"

$VERBOSE || exec 2>$errfile
trap "cleanup; exit 255" 1 2 3

trac_datadir=`kusa-conf trac-server.datadir`	|| exit_err $?
trac_usrgrp=`kusa-conf trac-server.user-group`	|| exit_err $?

cd $trac_datadir/cache				|| exit_err $?

# start index page buffer
#
template=`ku_get_template trac-index-html-head`	|| exit_err $?
kusa-conf-parse $template >$htmfile			|| exit_err $?


# process all projects dirs
#
template=`ku_get_template trac-index-html-entry`	|| exit_err $?
categtpl=`ku_get_template trac-index-html-category`	|| exit_err $?


# elenco projects (dir contenenti .bzr), eventualemte sorted
# per categoria, se sorted ogni riga contiene "project + descrizione
# categoria" (separatore pipe)
#
# ad ogni nuova categoria viene generato opportuno codice html di break
#
# per ogni entry aggiunge opportuno codice html (elemento table)
#
get_sorted_projects >$tmpdir/projects

$DEBUG && echo ">> DUMP get_sorted_projects"
$DEBUG && cat $tmpdir/projects

prj=
categ=
prevcateg=

exec 9<&0 <$tmpdir/projects
while read line
do
	prj=`echo "$line" | cut -d'|' -f1`
	categ=`echo "$line" | cut -d'|' -f2`

	[ "$categ" != "$prevcateg" ] && {
		ku_log " new category: $categ"
		echo -e "[tmp-html]\n CATEGORY $categ" >$tmpfile
		$DEBUG && echo "DUMP $tmpfile"
		$DEBUG && cat $tmpfile
		kusa-conf-parse --include $tmpfile $categtpl >>$htmfile || exit_err $?
		prevcateg="$categ"
	}

	ku_log " updating checkout for $prj"
	cd $prj
	if $VERBOSE
	then
		bzr update || {
			ku_log " errors during checkout update on $prj:"
			ku_loglines <$errfile
		}
	else
		bzr update >$outfile || {
			ku_log " errors during checkout update on $prj:"
			ku_loglines <$errfile
			saved=/tmp/$CMD-$prj.out
			mv $outfile $saved
			ku_log " bzr command output saved in $saved"
		}
	fi
	chown -R $trac_usrgrp .				|| exit_err $?


	# create entry for main index page
	#
	cat <<END_ENTRY >$tmpfile
[tmp-html]
  PRJNAME	$prj
  PRJDESC	\::trac.$prj.desc\::
  URL		/\::trac.$prj.site_prefix\::$prj
  PRJVER
  PRJ_BZRVER
  PRJ_BZRDATE
END_ENTRY
	# try to get more infos from project (extract env vars from project)
	# we must run the task in a project clean envirnoment, using jtreset,
	# to avoid interferences if we already are under a project env
	#
	jtreset jtcj --batch . env 2>/dev/null | egrep "^PRJDESC|^PRJVER|^PRJ_BZR" | \
		sed -e '/=$/d' -e "s/=/ /" >>$tmpfile
	kusa-conf-parse --include $tmpfile $template >>$htmfile || exit_err $?
	$DEBUG && cp $tmpfile /tmp/debug.conf1

	cd ..
done
exec 0<&9 9<&-


# close index page
#
template=`ku_get_template trac-index-html-bottom`		|| exit_err $?
cat <<EOF >$tmpfile
[tmp-html]
  today		`date '+%Y.%m.%d %H:%M'`
  cmd		$CMD
EOF
kusa-conf-parse --include $tmpfile $template >>$htmfile		|| exit_err $?

target="$trac_datadir/htdocs/index.html"
ku_log " updating main trac-index page '$target'"
mv $htmfile $target						|| exit_err $?
chown $trac_usrgrp $target					|| exit_err $?


cleanup
ku_log "ended"
exit 0
