#!/bin/bash

myname=`basename $0`
longname=$0
opts="v"

channel_present()
{
	if smart channel --show $1 2>&1 | grep -q baseurl >/dev/null; then
		return 0
	fi
	return 1
}

usage()
{
cat << EOT

  $myname [global options] command [options] [package ...]

  command is one of

    help:                 show this help screen
    init:                 initialize
    uninit:               undo initialization
    install:              install packages in [arguments]
    update:               update all jannet software on the system
    restore:              restore a previous jannet software version state
    info:                 query information about installed software packages
    info-projects:        query information about installed software projects
    checklog:             update the installation log file if necessary
    rpmnew:               remove superfluous rpmnew files and show conflicts
                          for others
    build-date:           show installed jannet packages along with build date
    built-today:          show installed jannet packages that were built today
    compile-templates:    compile templates

  global options are

   -v              be verbose

  package

    optional whitespace-separated list of package names, generally limiting the
    scope of the command to the specified packages, defaults to all installed
    janware packages

EOT
	if [ "$1" ]; then
		exit $1
	fi
}

get_opts()
{
    set -- `getopt $opts $*`
    while [ "$1" != -- ] ; do
	case "$1" in
	    -v)
		opt_verbose=true
		;;
	    *)
		eusage
		;;
	esac
	shift
    done
    shift
}

create_ldconfig_state()
{
	echo "=== automatically created by $myname update script"
	echo "--- files"
	ls /etc/ld.so.conf.d
	echo "--- directories"
	find /etc/ld.so.conf.d -type f | xargs cat | sort -u
}

check_ldconfig()
{
	local state=/var/log/jw-build-ldconf.state
	[ -f $state ] && create_ldconfig_state | diff $state - >/dev/null 2>&1 && return
	echo -n "running ldconfig ... "
	/sbin/ldconfig
	create_ldconfig_state > $state
	echo "done."
}

list_packages()
{
	local names="$1"
	local rpm_args
	if [ -n "$names" ]; then
		rpm_args="$rpm_args $names"
	else
		rpm_args="$rpm_args -a"
	fi
	rpm -q --queryformat '%{NAME}: %{URL}\n' $rpm_args | \
		grep -i '^[^ ]\+:.*\(jannet\.de\|janware\.com\)' | \
		sed 's/\(^[^ ]\+\) *:.*/\1/; s/[	 ]*$//' |\
		sort -u
}

list_projects()
{
	list_packages "$@" | xargs -r rpm -q --queryformat '%{SOURCERPM}: %{URL}\n' | \
		sed 's/\(^[^ ]\+\) *:.*/\1/; s/[	 ]*$//; s/-[0-9]\+.*//' |\
		sort -u
}

cmd_rpmnew()
{
	local file

	list_packages "$@" |
	xargs -r rpm -ql |
	while read file; do
		if [ -e "$file.rpmnew" ]; then
			if diff -q $file $file.rpmnew; then
				if [ -L "$file" ]; then
					echo ========== skipping link $file
					diff $file.rpmnew $file
					continue
				fi
				echo mv $file.rpmnew $file
				sudo mv $file.rpmnew $file
			else
				echo =========== $file
				diff $file.rpmnew $file
			fi
		fi
	done
}

cmd_diff()
{
	local file

	list_packages "$@" |
	xargs -r rpm -qV |
	sed '/^....L\|^..5/ !d; s%[^/]*/%/%' |
	while read file; do
		if diff -q $file $file.rpmnew; then
			if [ -L "$file" ]; then
				echo ========== skipping link $file
				diff $file.rpmnew $file
				continue
			fi
			echo mv $file.rpmnew $file
			sudo mv $file.rpmnew $file
		else
			echo =========== $file
			diff $file.rpmnew $file
		fi
	done
}

cmd_build_date()
{
	list_packages "$@" |
		xargs -r rpm -q --queryformat '%{BUILDTIME} %{NAME}\n' |
		sort -n |
		sed 's/-run\|-devel//' |
		sort -u |
		while read t p; do
			echo `date --date=@$t --rfc-3339=seconds` $p
		done
}

cmd_compile_templates()
{
	local ext_from=".jw-tmpl"
	local ext_to=""
	local ext_tables=".jw-secret .jw-vars"
	local group=root
	local owner=root
	local mode=600
	local ext_from_re=`echo $ext_from | sed 's/\./\\./g'`

	# TODO: allow target file attributes to be specified in options
	umask 0077

	local f
	list_packages "$@" | xargs -r rpm -ql | while read f; do
		echo searching $ext_from_re in $f
		echo $f | grep -q "$ext_from_re$" || continue
		local base=`echo $f | sed "s/$ext_from_re$//"`
		local to=$base$ext_to
		local table="" ext
		for ext in $ext_tables; do
			table=$base$ext
			[ -f "$table" ] && break
		done
		[ -f $table ] || {
			echo "WARNING: No key-value table found for template $f, not compiling." >&2
			continue
		}
		# TODO: use mktemp -d and keep temporary files in read-only dir
		local tmp=$to.tmp
		echo "Applying macros in $table to $f."
		sed 's|\([^ ]\+\) \(.*\)|s/\1/\2/g|' $table | sed -f - $f > $tmp
		chmod $mode $tmp
		chown $owner $tmp
		chgrp $owner $tmp
		mv $tmp $to
	done
}

cmd_built_today()
{
	local today=`date +'%Y-%m-%d'`
	cmd_build_date | grep $today | cut -d' ' -f3
}

cmd="$1"
shift
get_opts $*

case $cmd in

init)
	if ! channel_present ftp.jannet.de; then
		echo -n "adding installation source ... "
		sudo smart channel -y --add ftp.jannet.de \
			type=yast2 \
			baseurl=ftp://dspadm:dspasswd@ftp.jannet.de/pub/packages/linux/suse/10.1/inst-source \
			>/dev/null 2>&1
		if channel_present; then echo done; else echo failed; fi
	fi
	;;

uninit)
	if channel_present ftp.jannet.de; then
		echo -n "removing installation source ... "
		sudo smart channel -y --remove ftp.jannet.de >/dev/null 2>&1
		echo done
	fi
	;;

update)
	sudo smart update ftp.jannet.de
	sudo smart upgrade -y
	check_ldconfig
	;;

install)
	sudo smart update ftp.jannet.de
	if [ -f $1 ]; then
		sudo smart install -y `cat $1`
	else
		sudo smart install -y $*
	fi
	check_ldconfig
	;;
restore)
	echo "not yet implemented, sorry" >&2
	;;
checklog)
	line=`jannet info | tr -s " "`
	echo $line
	;;
info)
	if [ "$opt_verbose" = true ]; then
		list_packages "$@" | xargs -r rpm -qi
	else
		list_packages "$@" | xargs -r rpm -q
	fi
	;;
info-projects)
	list_projects "$@"
	;;
cpp-glib)
	sudo rpm -U --replacefiles --replacepkgs --oldpackage \
		ftp://dspadm@ftp.jannet.de/pub/packages/linux/suse/10.1/inst-source/rpm/i586/glib2-2.8.5-19.i586.rpm
	check_ldconfig "$@"
	;;
rpmnew)
	cmd_rpmnew "$@"
	;;
compile-templates)
	cmd_compile_templates "$@"
	;;
diff)
	cmd_diff "$@"
	;;
build-date)
	cmd_build_date "$@"
	;;
built-today)
	cmd_built_today "$@"
	;;
help)
	usage 0
	;;
*)
	usage 1
	;;

esac
