#!/bin/sh -ef

#TEMPFILE=`mktemp /var/lib/alterator/ltsconf.XXXXXXXX`
#TEMPFILE=`mktemp /tmp/alterator/ltsconf.XXXXXXXX`
# FIXME: should probably use our own subdir
NMAP_OUT=`mktemp ${TMPDIR:-/tmp/alterator}/ltsconf-nmap.XXXXXXXX`
SCANLIST=`mktemp ${TMPDIR:-/tmp/alterator}/ltsconf-list.XXXXXXXX`

SUBNET="192.168.0.0/24"
PORT=9200

chroot=/var/lib/ltsp/i586
ltsconf=/usr/sbin/ltsconf

#keylist="sound localdev power_button"
keylist="sound localdev x_mode_0"

################### helpers

start() { echo '('; }
stop() { echo ')'; }
nop() { echo '()'; }

uppercase() { echo -n $@ | tr [:lower:] [:upper:]; }
lowercase() { echo -n $@ | tr [:upper:] [:lower:]; }

parenthesize() { while read i; do echo "(\"$i\")"; done; }

ltsconf()
{
	#echo "debug: ltsconf $@" >&2
	# TODO: check for in-system ltsconf, don't chroot then
	[ -x ~/bin/ltsconf ] \
	&& ~/bin/ltsconf $@ \
	|| chroot "$chroot" "$ltsconf" $@ #2>/tmp/alterator/ltsconf.log
}

nmap_subnet()
{
	#echo 172.16.1.201
	#echo 172.16.1.202
	#return
	[ -s "$SCANLIST" ] || {
		nmap -T5 -p "T:$PORT" \
			-oG "$NMAP_OUT" \
			"$SUBNET" \
			>&/dev/null &&
		grep "$PORT/open" "$NMAP_OUT" \
		| sed 's,^Host: \([^ ]*\) .*$,\1,' \
		> "$SCANLIST"
	}
	[ -s "$SCANLIST" ] && cat "$SCANLIST"
}

################### interface modificators

list_everything()
{
	# TODO: remove hosts already in lts.conf from scan results,
	# then append `nmap_subnet` _after_ `ltsconf list`
	start
	( ltsconf list; nmap_subnet) | sort -n | uniq | parenthesize
	stop
}

# should be list_section?
read_section()
{
	start
	(
		echo "name \"$1\""
		IFS="="
		ltsconf list "$1" | while read option value; do
			case "$value" in
			Y|y)
				value="#t";;
			N|n)
				value="#f";;
			[0-9]*)
				;;
			default)
				value="\"$value\"";;
			esac
			lowercase "$option "
			echo "$value"
		done
	)
	stop
	read_keys $1 > ~/tmp/read_keys.log
}

# should be read_section?
read_keys()
{
	start
	for key in $keylist; do
		KEY="`uppercase $key`"
		# map: "Key LOCALDEV in section [default] is Y"
		# to:  "Y . default"
		# ignore warnings about falling back to default value
		ltsconf get "$KEY" "$1" 2>/dev/null \
		| sed 's/^Key \(.*\) in section \[\(.*\)\] is \(.*\)$/\1 (\3 "\2")/'
	done
	stop
}

write_section()
{
	[ "$1" = "/" ] && return

	local DELETE_KEYS=""

	for key in $keylist; do
		KEY="`uppercase $key`"
		invar="in_$key"
		value="${!invar}"	# get value of variable with name $invar
		case "$value" in
		"")			# FIXME: ltsconf del "$key" "$1" ?
			DELETE_KEYS="$DELETE_KEYS $KEY"
			continue;;
		\#t)
			value="Y";;
		\#f)
			value="N";;
		[a-zA-Z0-9_]*)
			value="\"$value\"";;
		[0-9]*)
			;;
		*)
			value="\"$value\"";;
		esac
		KEY="`uppercase $key`"
		#echo "debug: [$1] $KEY: $value" >&2
		# ltsconf set KEY VALUE SECTION
		ltsconf set "$KEY" "$value" "$1"
	done

	# OK, now remove what's set to default
	#echo "debug: REMOVING keys: $DELETE_KEYS" >&2
	for KEY in $DELETE_KEYS; do
		#echo "debug: ltsconf del [$KEY] [$1]" >&2
		ltsconf del "$KEY" "$1"
	done
}

new_key()
{
	# NB: we need to be able to set several keys	
	return
}

delete_section()
{
	[ "$1" = "/" ] && return
	ltsconf del "$1"
}

delete_key()
{
	[ -n "$1" ] || return
	[ "$2" = "/" ] && return
	ltsconf del "`uppercase "$1"`" "$2"
}

_()
{
LANG=${in_language%%;*}.utf8 gettext "alterator-ltsconf" "$1"
}

cleanup()
{
	rm -f "$NMAP_OUT" "$SCANLIST"
}

trap cleanup EXIT PIPE HUP INT

. /usr/share/alterator/build/backend3.sh

on_message()
{
	case "$in_action" in
		list)
			if [ "$in__objects" = "/" ];then
				list_everything
			else
				start
				echo 'sound #t'
				stop
			fi
			;;
		read) 
			if [ "$in__objects" = "/" ];then
				echo '()'
			else
				read_section "$in__objects"
			fi
			;;
		write)
			write_section "$in__objects"
			echo '()'
			;;
		new) 
			if new_section "$in_name"; then
				echo '()'
			else
				printf '(error "%s")' "`_ "same SOMETHING already exists"`"
			fi
			;;
		delete)
			if [ -n "$in_name" ]; then
				delete_key "$in_name" "$in__objects"
			else
				delete_section "$in__objects"
			fi
			echo '()'
			;;
		*)
			echo '#f'
			;;
	esac
}

message_loop

