#!/bin/bash
#
# Guralp Configuration System
#   Copyright (c) 2009-2012 Guralp Systems Ltd. All rights reserved.
#
#   GSMS server output config

# Handle the navbar query without loading anything
if [ "X$1" == "X--navbar" ]
then
	echo "servicestop	Services"
	echo "servicessub/gsms-out	gsms-out"
	echo "gsms-out/$3	$3"
	exit 0
fi

# Load support functions
script_dir=$(dirname $0)
. $script_dir/functions.sh
. $script_dir/svc_funcs.sh
. $script_dir/gdi-base_link.sh


name="$2"
sel="$3"

CFGFILE="$CONFIGDIR/$name/${sel}.local"
CTLFILE="$CONFIGDIR/$name/${sel}.ctl.local"
SRVBASE="$SERVDIR/$name"


do_read() {
	local i entry line 
	local mapnum have_channel_map src dest

	# Standard control info
	gcs_svc_read || return 1

	# Now the service type dependant variables

	# Global defaults
	gcs_var d_logname		""
	gcs_var d_bind_host		""
	gcs_var d_bind_service		9001
	gcs_var d_channel_map_mode	automatic

	have_channel_map=0

	if [ -r "$CFGFILE" ]
	then
	    # Convert the config file into variable decls

	    # Handle the simple vars
	    gcs_var_o2 logname		""
	    gcs_var_o2 bind_host	""
	    gcs_var_o2 bind_service	""
	    gcs_var_o2 channel_map_mode	""

	    # Convert UDP and TCP push hosts into table
	    i=0
	    line="$(gcs_get_varcf2 tcp-push "$CFGFILE" "")"
	    for entry in $line
	    do
		gcs_var "o_push_host${i}" "${entry/,*}"
		gcs_var "o_push_port${i}" "${entry/*,}"
		gcs_var "o_push_proto${i}" TCP
		((i++))
	    done
	    line="$(gcs_get_varcf2 udp-push "$CFGFILE" "")"
	    for entry in $line
	    do
		gcs_var "o_push_host${i}" "${entry/,*}"
		gcs_var "o_push_port${i}" "${entry/*,}"
		gcs_var "o_push_proto${i}" UDP
		((i++))
	    done

	    # Channel mapping
	    for entry in $(gcs_list_varcf2_sections "$CFGFILE")
	    do
		if [ "$entry" == "channel_map" ]
		then
		    have_channel_map=1
		    break
		fi
	    done

	    gcs_gdi_base_iselect "$(gcs_get_varcf2 gdi_socket "$CFGFILE" "")" "sink"
	else
	    gcs_gdi_base_iselect "" "sink"
	fi

	mapnum=0
	if [ "$have_channel_map" -eq 0 ]
	then
	    gcs_var o_channel_map_mode automatic
	else
	    entry="$(gcs_get_varcf2 reject_unfiltered_channels "$CFGFILE" "")"
	    case "$entry" in
	    [Tt][Rr][Uu][Ee]|1)
		gcs_var o_channel_map_mode manual
		;;
	    *)
		gcs_var o_channel_map_mode semi
		;;
	    esac

	    # Source command after done to maintain loop body in this context
	    while read -r src dest
	    do
		gcs_var "o_channel_map_src$mapnum" "$src"
		gcs_var "o_channel_map_dest$mapnum" "$dest"
		((++mapnum))
	    done < <(gcs_list_varcf2 "$CFGFILE" channel_map)
	fi

	while read -r src dest
	do
	    [ -z "$src" -o -z "$dest" ] && continue

	    if [ -r "$CFGFILE" ]
	    then
		entry="$(gcs_get_varcf2 "${src}" "${CFGFILE}" "channel_map")"
		[ -z "${entry}" ] || continue
	    fi

	    gcs_var "o_channel_map_src$mapnum" "$src"
	    gcs_var "o_channel_map_dest$mapnum" "$dest"

	    ((++mapnum))
	done < <(seedmap)
}


do_check() {

	gcs_read_vars

	# Standard service control/info vars
	gcs_svc_check

	# Service dependant variables
	# Checks are done by the main engine so nothing to do here

	gcs_gdi_base_dereference "sink"

	if [ "$new_channel_map_mode" = "manual" ]
	then
	    check_table_not_empty "channel_map" "channel_map_src" \
			"No channels have been mapped."
	fi
}


do_write_channel_map() {
	local -i i
	local src dest

	for (( i = 0 ; i < $new_channel_map_rows ; i++ ))
	do
	    eval src="\${new_channel_map_src${i}}"
	    [ -z "$src" ] && continue

	    eval dest="\${new_channel_map_dest${i}}"

	    gcs_set_varcf2 "$src" "$CFGFILE" "$dest" channel_map
	done
}


do_write() {
	local -i i
	local got_one
	local host
	local port
	local udp_push
	local tcp_push


	do_check
	if (( gcs_errors > 0 ))
	then
	    return
	fi

	if gcs_truefalse "${new_delete:-false}"
	then
	    gcs_svc_delete "$name" "$sel"
	fi

	# Standard service controls
	gcs_ensure_cfgfile_exists $CTLFILE
	gcs_set_varf DESC $CTLFILE "$desc"

	# Now the service type dependant variables
	gcs_ensure_cfgfile_exists "$CFGFILE"

	# Do the simple keywords in place
	gcs_set_varcf2 logname		"$CFGFILE" "$new_logname" ""
	gcs_set_varcf2 bind_host	"$CFGFILE" "$new_bind_host" ""
	gcs_set_varcf2 bind_service	"$CFGFILE" "$new_bind_service" ""
	gcs_set_varcf2 gdi_socket	"$CFGFILE" "$new_gdi_socket" ""

	# Channel map
	gcs_clear_varcf2_section "$CFGFILE" channel_map

	case "$new_channel_map_mode" in
	automatic)
	    gcs_set_varcf2 reject_unfiltered_channels "$CFGFILE" "" ""
	    ;;
	semi)
	    gcs_set_varcf2 reject_unfiltered_channels "$CFGFILE" False ""
	    do_write_channel_map
	    ;;
	manual)
	    gcs_set_varcf2 reject_unfiltered_channels "$CFGFILE" True ""
	    do_write_channel_map
	    ;;
	esac

	# Push targets
	udp_push=""
	tcp_push=""
	for (( i = 0 ; i < $new_channel_map_rows ; i++ ))
	do
	    host=$(gcs_get_var new_push_host$i)
	    [ -z "$host" ] && continue

	    port=$(gcs_get_var new_push_port$i)
	    [ -z "$port" ] && port=9001


	    case "X$(gcs_get_var new_push_proto$i)" in
	    X[Tt][Cc][Pp])
		    tcp_push="$tcp_push $host,$port"
		    ;;
	    *)
		    udp_push="$udp_push $host,$port"
		    ;;
	    esac
	done
	gcs_set_varcf2 tcp-push "$CFGFILE" "$tcp_push" ""
	gcs_set_varcf2 udp-push "$CFGFILE" "$udp_push" ""


	# Update the service script
	gcs_update_svc "$name" "$sel" "$enable" "$desc" "$CFGFILE" "$CTLFILE" \
			"$SRVBASE"
	
	gcs_svc_reload "$name" "$sel"
}


case "X$1" in
X--check)	do_check	;;
X--write)	do_write	;;
X--read)	do_read		;;
*)		exit 1		;;
esac

gcs_cleanup
exit 0
