#!/usr/bin/awk -f

BEGIN {
	# split input fields by a colon
	FS=":"
	# set default language
	LANGUAGE="en_US.UTF8"
	# set translation domain
	TEXTDOMAIN = "alterator-lightsquid"
	readmsg=0
	LOGFILE="/var/log/configd.log"
	LIGHTDIR="/var/lib/lightsquid/"

}

# error reporting function
function debug(text, errno) {
	printf "%s " TEXTDOMAIN ": %s: %s\n", strftime("%B %d %H:%M:%S"), text, errno >> LOGFILE
	fflush(LOGFILE)
}

# insertional sorting of an associated array
# returns number of records and key/value in dest separated by SUBSEP
function assorti(src, dest,		i, n, j, val, idx) {
	i = 1
	for (n in src) {
		for (j = i; j > 1; j--)
			if (src[n] >= val[j - 1])
				break
			else {
				val[j] = val[j - 1]
				idx[j] = idx[j-1]
			}
		val[j] = src[n]
		idx[j] = n
		i++
	}
	for (j = 1; j < i; j++)
		dest[j] = idx[j] SUBSEP val[j]
	return i-1
}

function ls_total(from, to,		cmd1, error1, dir, cmd2, error2, ip, file, line, total, n, idx, i, list) {
	if (from >=0 && split(from, list, /-/) > 0)
		from = list[1] list[2] list[3]
	if (to >=0 && split(to, list, /-/) > 0)
		to = list[1] list[2] list[3]

	cmd1 = "ls -1 " LIGHTDIR
	while ((error1 = cmd1 | getline dir) > 0) {
		if (from >= 0 && dir < from)
			continue
		if (to >= 0 && dir > to)
			continue
		cmd2 = "ls -1 " LIGHTDIR "/" dir
		while ((error2 = cmd2 | getline ip) > 0) {
			file = LIGHTDIR "/" dir "/" ip
			getline line < file
			close(file)
			if (sub(/^total:[[:space:]]+/, "", line))
				total[ip] += line
		}
		if (error2 == -1)
			debug("Error running command '" cmd2 "'", ERRNO)
		close(cmd2)
	}
	if (error1 == -1)
		debug("Error running command '" cmd1 "'", ERRNO)
	close(cmd1)

	n = assorti(total, idx)
	for (i = n; i >= 1; i--)
		if (split(idx[i], list, SUBSEP) > 0)
			printf "(\"%s\" rcvd \"%0.1f\")", list[1], list[2]/1024.0
}

function ls_sites(from, to, ip,		list, cmd1, error1, dir, error2, file, line, site, bytes, total, idx, i, n) {
	if (from >=0 && split(from, list, /-/) > 0)
		from = list[1] list[2] list[3]
	if (to >=0 && split(to, list, /-/) > 0)
		to = list[1] list[2] list[3]

	cmd1 = "ls -1 " LIGHTDIR
#	debug("from", from)
#	debug("to", to)
	while ((error1 = cmd1 | getline dir) > 0) {
		if (from >= 0 && dir < from)
			continue
		if (to >= 0 && dir > to)
			continue

		file = LIGHTDIR "/" dir "/" ip
		# missing or empty file
		if ((error2 = getline < file) <= 0)
			continue
		while ((error2 = getline line < file) > 0)
			if (split(line, list, /[[:space:]]+/) > 0) {
				site = list[1]
				bytes = list[2]

				if (match(site, /^([^:]+):/, list) > 0)
					site = list[1]

				total[site] += bytes
			}
		if (error2 == -1)
			debug("Error reading file '" file "'", ERRNO)
		close(file)
	}
	if (error1 == -1)
		debug("Error running command '" cmd1 "'", ERRNO)
	close(cmd1)

	n = assorti(total, idx)
	for (i = n; i >= 1; i--)
		if (split(idx[i], list, SUBSEP) > 0)
			printf "(\"%s\" rcvd \"%0.1f\")", list[1], list[2]/1024.0
}

# show translation
# overwriting locale settings
function N_(text, domain,			list, cmd, line) {
	if (!domain)
		domain = TEXTDOMAIN
	split(LANGUAGE, list, /:/)
	cmd = "LANGUAGE=\"" LANGUAGE "\" LANG=\"" list[1] ".UTF8\" gettext " domain " \"" text "\""
	cmd | getline line
	close(cmd)
	return line
}

# start message reading
/^_message:begin$/ {
	readmsg=1
	next
}

# stop message reading
/^_message:end$/ {
	readmsg=0
#	debug("==========", "==========")
#	for (attribute in params)
#		debug("params[" attribute "]", params[attribute])
	# overwrite current language
	if (params["language"] != "")
		LANGUAGE = gensub(/;/, ":", "g", params["language"])

	switch (params["action"]) {
		case "constraints":
			print "("
			printf " name (label \"%s\")", N_("Address")
			printf " rcvd (label \"%s\")", N_("Received")
			if (split(params["_objects"], list, /\//) > 0 && list[3])
				printf " ip (label \"%s\")", list[3]
			print ")"
			break
		case "list":
			print "("
			if (split(params["_objects"], list, /\//) > 0)
				if (list[3])
					ls_sites(list[1], list[2], list[3])
				else if (list[1] && list[2])
					ls_total(list[1], list[2])
			print ")"
			break
		case "read":
			print "("
			if (split(params["_objects"], list, /\//) > 0) {
				if (list[1] && list[1] != -1)
					printf " from \"%s\"", list[1]
				if (list[2] && list[2] != -1)
					printf " to \"%s\"", list[2]
			}
			print ")"
			break
		case "write":
		case "new":
		case "delete":
			print "()"
			break
		default:
			print "#f"
	}
	fflush()
	# delete attribute/value pairs before next cycle
	delete params
	#exit
	next
}

# save attribute/value pairs
{
	if (! readmsg)
		next
	attribute=$1
	value=$2
	# join the rest of fields with a colon
	for (n = 3; n <= NF; n++)
		value=value ":" $n
	value = gensub(/([^\\])\\n/, "\\1\n", "g", value)
	params[attribute]=value
}
