#!/bin/sh

. /lib/functions.sh

GPS_CONF="gps"
IOMAN_CONF="ioman"
AVL_CONF="avl"

GSM_TYPE="mobile"
GPIO_TYPE="gpio"
ANALOG_TYPE="adc"

handle_io_tavl() {
	local section="$1"
	local type="$2"
	local migrate_sec="$3"

	config_get direction "$section" "direction"

	[ "$type" = "$GPIO_TYPE" ] && [ -z "$direction" ] || [ "$direction" = "out" ] && return

	uci_add "$GPS_CONF" "$migrate_sec"
	case "$section" in
		din1 | dio0)
			uci_set "$GPS_CONF" "$CONFIG_SECTION" "enabled" "$send_digital_input1"
		;;
		din2 | dio1)
			uci_set "$GPS_CONF" "$CONFIG_SECTION" "enabled" "$send_digital_input2"
		;;
		din3 | dio2 | iio)
			uci_set "$GPS_CONF" "$CONFIG_SECTION" "enabled" "$send_digital_input3"
		;;
		adc0)
			uci_set "$GPS_CONF" "$CONFIG_SECTION" "enabled" "$send_analog_input"
		;;
		acl0)
			uci_set "$GPS_CONF" "$CONFIG_SECTION" "enabled" "0"
			uci_set "$GPS_CONF" "$CONFIG_SECTION" "acl" "current"
		;;
		*)
			uci_set "$GPS_CONF" "$CONFIG_SECTION" "enabled" "0"
	esac
	uci_set "$GPS_CONF" "$CONFIG_SECTION" "type" "$type"
	uci_set "$GPS_CONF" "$CONFIG_SECTION" "name" "$section"
}

convert_tavl() {
	local section="$1"
	local migrate_sec="$2"

	config_get send_gsm_signal "$section" "send_gsm_signal" "0"
	config_get send_digital_input1 "$section" "send_digital_input1" "0"
	config_get send_digital_input2 "$section" "send_digital_input2" "0"
	config_get send_digital_input3 "$section" "send_digital_input3" "0"
	config_get send_analog_input "$section" "send_analog_input" "0"

	uci_add "$GPS_CONF" "$migrate_sec"
	uci_set "$GPS_CONF" "$CONFIG_SECTION" "enabled" "$send_gsm_signal"
	uci_set "$GPS_CONF" "$CONFIG_SECTION" "type" "$GSM_TYPE"
	uci_set "$GPS_CONF" "$CONFIG_SECTION" "name" "signal"

	config_load "$IOMAN_CONF" || exit 0
	config_foreach handle_io_tavl "$GPIO_TYPE" "$GPIO_TYPE" "$migrate_sec"
	config_foreach handle_io_tavl "$ANALOG_TYPE" "$ANALOG_TYPE" "$migrate_sec"

	uci_remove "$GPS_CONF" "$section"
}

move_avl_rules_to_avl_config() {
	local section="$1"
	local section_name="$2"

	if [ "$section" = "avl" ]; then
		config_get enabled "$section" "enabled" "0"
		config_get hostname "$section" "hostname" ""
		config_get port "$section" "port" "0"
		config_get proto "$section" "proto" "tcp"
		config_get con_cont "$section" "con_cont" "0"
		config_get send_retry "$section" "send_retry" "0"

		uci_set "$AVL_CONF" "avl" "enabled" "$enabled"
		uci_set "$AVL_CONF" "avl" "hostname" "$hostname"
		uci_set "$AVL_CONF" "avl" "port" "$port"
		uci_set "$AVL_CONF" "avl" "proto" "$proto"
		uci_set "$AVL_CONF" "avl" "con_cont" "$con_cont"
		uci_set "$AVL_CONF" "avl" "send_retry" "$send_retry"

		uci_remove "$GPS_CONF" "$section"

	elif [ "$section" = "avl_rule_main" ]; then
		config_get enabled "$section" "enabled" "0"
		config_get priority "$section" "priority" "low"
		config_get distance "$section" "distance" "1"
		config_get collect_period "$section" "collect_period" "1"
		config_get angle "$section" "angle" "1"
		config_get saved_records "$section" "saved_records" "1"
		config_get send_period "$section" "send_period" "1"

		uci_set "$AVL_CONF" "avl_rule_main" "enabled" "$enabled"
		uci_set "$AVL_CONF" "avl_rule_main" "priority" "$priority"
		uci_set "$AVL_CONF" "avl_rule_main" "distance" "$distance"
		uci_set "$AVL_CONF" "avl_rule_main" "collect_period" "$collect_period"
		uci_set "$AVL_CONF" "avl_rule_main" "angle" "$angle"
		uci_set "$AVL_CONF" "avl_rule_main" "saved_records" "$saved_records"
		uci_set "$AVL_CONF" "avl_rule_main" "send_period" "$send_period"

		uci_remove "$GPS_CONF" "$section"

	elif [ "$section_name" = "avl_rule" ]; then
		config_get enabled "$section" "enabled" "0"
		config_get priority "$section" "priority" "low"
		config_get name "$section" "name" ""
		config_get distance "$section" "distance" "1"
		config_get collect_period "$section" "collect_period" "1"
		config_get angle "$section" "angle" "1"
		config_get saved_records "$section" "saved_records" "1"
		config_get send_period "$section" "send_period" "1"
		config_get wan_status "$section" "wan_status" ""
		config_get din_status "$section" "din_status" ""
		config_get io_type "$section" "io_type" ""
		config_get io_name "$section" "io_name" ""

		uci_add "$AVL_CONF" "avl_rule"
		uci_set "$AVL_CONF" "$CONFIG_SECTION" "enabled" "$enabled"
		uci_set "$AVL_CONF" "$CONFIG_SECTION" "priority" "$priority"
		uci_set "$AVL_CONF" "$CONFIG_SECTION" "distance" "$distance"
		uci_set "$AVL_CONF" "$CONFIG_SECTION" "collect_period" "$collect_period"
		uci_set "$AVL_CONF" "$CONFIG_SECTION" "angle" "$angle"
		uci_set "$AVL_CONF" "$CONFIG_SECTION" "saved_records" "$saved_records"
		uci_set "$AVL_CONF" "$CONFIG_SECTION" "send_period" "$send_period"
		uci_set "$AVL_CONF" "$CONFIG_SECTION" "wan_status" "$wan_status"
		uci_set "$AVL_CONF" "$CONFIG_SECTION" "din_status" "$din_status"
		uci_set "$AVL_CONF" "$CONFIG_SECTION" "io_type" "$io_type"
		uci_set "$AVL_CONF" "$CONFIG_SECTION" "io_name" "$io_name"

		uci_remove "$GPS_CONF" "$section"

	elif [ "$section_name" = "tavl_rule" ]; then
		config_get enabled "$section" "enabled" "0"
		config_get type "$section" "type" ""
		config_get name "$section" "name" ""

		uci_add "$AVL_CONF" "tavl_rule"
		uci_set "$AVL_CONF" "$CONFIG_SECTION" "enabled" "$enabled"
		uci_set "$AVL_CONF" "$CONFIG_SECTION" "type" "$type"
		uci_set "$AVL_CONF" "$CONFIG_SECTION" "name" "$name"

		if [ "$type" = "acl" ]; then
			uci_set "$AVL_CONF" "$CONFIG_SECTION" "acl" "current"
		fi

		uci_remove "$GPS_CONF" "$section"

	elif [ "$section_name" = "input" ]; then
		config_get "enabled" "$section" "enabled" "0"
		config_get "priority" "$section" "priority" "low"
		config_get "event" "$section" "event" ""
		config_get "io_type" "$section" "io_type" ""
		config_get "io_name" "$section" "io_name" ""
		config_get "min" "$section" "min" ""
		config_get "max" "$section" "max" ""

		uci_add "$AVL_CONF" "input"
		uci_set "$AVL_CONF" "$CONFIG_SECTION" "enabled" "$enabled"
		uci_set "$AVL_CONF" "$CONFIG_SECTION" "priority" "$priority"
		uci_set "$AVL_CONF" "$CONFIG_SECTION" "event" "$event"
		uci_set "$AVL_CONF" "$CONFIG_SECTION" "io_type" "$io_type"
		uci_set "$AVL_CONF" "$CONFIG_SECTION" "io_name" "$io_name"

		[ -n "$min" ] && uci_set "$AVL_CONF" "$CONFIG_SECTION" "min" "$min"
		[ -n "$max" ] && uci_set "$AVL_CONF" "$CONFIG_SECTION" "max" "$max"

		uci_remove "$GPS_CONF" "$section"
	fi
}

remove_from_avl_conf() {
	local sec="$1"

	uci_remove "$AVL_CONF" "$sec"
}

retain_https_rules() {
	local HTTPS_SEC="https"

	config_get enabled "$HTTPS_SEC" "enabled" "0"
	config_get hostname "$HTTPS_SEC" "hostname"
	config_get interval "$HTTPS_SEC" "interval" "0"
	config_get delay "$HTTPS_SEC" "delay" "0"

	if [ "$interval" != 0 ]; then
		uci_set "$GPS_CONF" "$HTTPS_SEC" "interval" "$interval"
	elif [ "$delay" != 0 ]; then
		uci_set "$GPS_CONF" "$HTTPS_SEC" "interval" "$delay"
		uci_remove "$GPS_CONF" "$HTTPS_SEC" "delay"
	fi

	uci_set "$GPS_CONF" "$HTTPS_SEC" "enabled" "$enabled"
	uci_set "$GPS_CONF" "$HTTPS_SEC" "hostname" "$hostname"
}

add_new_nmea_rules() {
	local RULE_SEC="nmea_rule"
	local sentences="GARMC GAGGA GAGSA GAVTG GBGSV GQGSV GBGSA GQGSA"

	for sentence in $sentences
	do
		if uci_get "$GPS_CONF" "$sentence"; then
			continue
		fi
		uci_add "$GPS_CONF" "$RULE_SEC"
		uci_set "$GPS_CONF" "$CONFIG_SECTION" "forwarding_enabled" "0"
		uci_set "$GPS_CONF" "$CONFIG_SECTION" "forwarding_interval" "5"
		uci_set "$GPS_CONF" "$CONFIG_SECTION" "collecting_enabled" "0"
		uci_set "$GPS_CONF" "$CONFIG_SECTION" "collecting_interval" "5"
		uci_rename "$GPS_CONF" "$CONFIG_SECTION" "$sentence"
	done
}

ACL_RULE_EXIST=0
add_acl_routine() {
	ubus list ioman.acl* > /dev/null 2>&1 || return

	add_acl_rule_if_missing "$AVL_CONF" "tavl_rule"
	add_acl_rule_if_missing "$GPS_CONF" "https_tavl_rule"
}

add_acl_rule_if_missing() {
	local conf=$1
	local section_type=$2
	ACL_RULE_EXIST=0

	config_load "$conf" || return
	config_foreach check_if_acl_rule_exists
	[ "$ACL_RULE_EXIST" = "0" ] && add_acl_rule "$conf" "$section_type"
}

check_if_acl_rule_exists() {
	[ "$ACL_RULE_EXIST" = "0" ] || return
	local section="$1"

	config_get type "$section" "type" "0"
	if [ "$type" = "acl" ]; then
		ACL_RULE_EXIST=1
	fi
}

add_acl_rule() {
	local conf="$1"
	local sec_type="$2"

	uci_add "$conf" "$sec_type"
	uci_set "$conf" "$CONFIG_SECTION" "enabled" "0"
	uci_set "$conf" "$CONFIG_SECTION" "type" "acl"
	uci_set "$conf" "$CONFIG_SECTION" "name" "acl0"
	uci_set "$conf" "$CONFIG_SECTION" "acl" "current"
}

config_load "$GPS_CONF" || exit 0
config_foreach convert_tavl "tavl" "tavl_rule"
config_load "$GPS_CONF" || exit 0
config_foreach convert_tavl "https_tavl" "https_tavl_rule"
uci_commit "$GPS_CONF"

config_load "$GPS_CONF" || exit 0
config_foreach move_avl_rules_to_avl_config "section"

if uci_get "$GPS_CONF" "@avl_rule[0]"; then
	config_load "$AVL_CONF" || exit 0
	config_foreach remove_from_avl_conf "avl_rule"
	config_load "$GPS_CONF" || exit 0
	config_foreach move_avl_rules_to_avl_config "avl_rule" "avl_rule"
fi

if uci_get "$GPS_CONF" "@tavl_rule[0]"; then
	config_load "$AVL_CONF" || exit 0
	config_foreach remove_from_avl_conf "tavl_rule"
	config_load "$GPS_CONF" || exit 0
	config_foreach move_avl_rules_to_avl_config "tavl_rule" "tavl_rule"
fi

if uci_get "$GPS_CONF" "@input[0]"; then
	config_load "$AVL_CONF" || exit 0
	config_foreach remove_from_avl_conf "input"
	config_load "$GPS_CONF" || exit 0
	config_foreach move_avl_rules_to_avl_config "input" "input"
fi

if ! uci_get "$AVL_CONF" "avl" "static_navigation"; then
	uci_set "$AVL_CONF" "avl" "static_navigation" "0"
fi

retain_https_rules
add_new_nmea_rules
add_acl_routine

uci_commit $GPS_CONF
uci_commit $AVL_CONF

exit 0
