#!/bin/sh
set -eu
. /usr/libexec/haproxy-manager/common.sh

migrate_firewall_markers() {
	local section marker name changed
	changed=0

	for section in $(uci -q show firewall | sed -n 's/^firewall\.\(@redirect\[[0-9][0-9]*\]\)=redirect/\1/p'); do
		marker="$(uci -q get "firewall.$section.hm_disabled_by_haproxy_manager" 2>/dev/null || true)"
		[ -n "$marker" ] || continue
		if [ "$marker" = 1 ]; then
			name="$(uci -q get "firewall.$section.name" 2>/dev/null || true)"
			case "$name" in
				"$FIREWALL_DISABLED_PREFIX"*) ;;
				*) uci set "firewall.$section.name=$FIREWALL_DISABLED_PREFIX$name" ;;
			esac
		fi
		uci -q delete "firewall.$section.hm_disabled_by_haproxy_manager" || true
		changed=1
	done

	for section in $(uci -q show firewall | sed -n 's/^firewall\.\(@rule\[[0-9][0-9]*\]\)=rule/\1/p'); do
		marker="$(uci -q get "firewall.$section.hm_managed" 2>/dev/null || true)"
		[ -n "$marker" ] || continue
		[ "$marker" != 1 ] || uci set "firewall.$section.name=$FIREWALL_RULE_NAME"
		uci -q delete "firewall.$section.hm_managed" || true
		changed=1
	done

	[ "$changed" != 1 ] || uci commit firewall
}

migrate_firewall_markers

SCHEMA_VERSION="$(uci_get main schema_version 1)"
MIGRATED=0
if [ "$SCHEMA_VERSION" -lt 2 ] 2>/dev/null; then

SECTIONS="$(route_sections)"
[ -z "$SECTIONS" ] || /usr/libexec/haproxy-manager/backup >/dev/null

CONSUMED=/tmp/haproxy-manager-migrate-consumed.$$
: > "$CONSUMED"
trap 'rm -f "$CONSUMED"' EXIT

is_consumed() {
	grep -qx "$1" "$CONSUMED"
}

to_web() {
	local section="$1" http_enabled="$2" https_enabled="$3" http_backend="$4" https_backend="$5"

	uci set "$CONFIG.$section.kind=web"
	uci set "$CONFIG.$section.web_http=$http_enabled"
	uci set "$CONFIG.$section.web_https=$https_enabled"
	[ "$http_enabled" != 1 ] || uci set "$CONFIG.$section.backend_http_port=$http_backend"
	[ "$https_enabled" != 1 ] || uci set "$CONFIG.$section.backend_https_port=$https_backend"
	uci -q delete "$CONFIG.$section.protocol" || true
	uci -q delete "$CONFIG.$section.listen_port" || true
	uci -q delete "$CONFIG.$section.backend_port" || true
}

clean_web_name() {
	local section="$1" host="$2" name clean
	name="$(uci_get "$section" name)"
	clean="$name"

	case "$name" in
		"$host 80"|"$host:80"|"$host HTTP"|"$host http") clean="$host" ;;
		*" HTTP") clean="${name% HTTP}" ;;
		*" http") clean="${name% http}" ;;
	esac

	[ -z "$clean" ] || [ "$clean" = "$name" ] || uci set "$CONFIG.$section.name=$clean"
}

for section in $SECTIONS; do
	protocol="$(uci_get "$section" protocol)"
	case "$protocol" in
		http)
			host="$(uci_get "$section" host)"
			backend_host="$(uci_get "$section" backend_host)"
			enabled="$(uci_get "$section" enabled 1)"
			http_backend="$(uci_get "$section" backend_port 80)"
			match=""

			for candidate in $SECTIONS; do
				is_consumed "$candidate" && continue
				[ "$(uci_get "$candidate" protocol)" = https ] || continue
				[ "$(uci_get "$candidate" host)" = "$host" ] || continue
				[ "$(uci_get "$candidate" backend_host)" = "$backend_host" ] || continue
				[ "$(uci_get "$candidate" enabled 1)" = "$enabled" ] || continue
				match="$candidate"
				break
			done

			if [ -n "$match" ]; then
				clean_web_name "$section" "$host"
				to_web "$section" 1 1 "$http_backend" "$(uci_get "$match" backend_port 443)"
				printf '%s\n' "$match" >> "$CONSUMED"
			else
				clean_web_name "$section" "$host"
				to_web "$section" 1 0 "$http_backend" 443
			fi
		;;
		both)
			backend="$(uci_get "$section" backend_port 80)"
			clean_web_name "$section" "$(uci_get "$section" host)"
			to_web "$section" 1 1 "$backend" "$backend"
		;;
		tcp)
			public_port="$(uci_get "$section" listen_port "$(uci_get "$section" backend_port)")"
			backend_port="$(uci_get "$section" backend_port)"
			uci set "$CONFIG.$section.kind=custom"
			uci -q delete "$CONFIG.$section.port_map" || true
			uci add_list "$CONFIG.$section.port_map=$public_port:$backend_port"
			uci -q delete "$CONFIG.$section.protocol" || true
			uci -q delete "$CONFIG.$section.listen_port" || true
			uci -q delete "$CONFIG.$section.backend_port" || true
		;;
	esac
done

for section in $SECTIONS; do
	is_consumed "$section" && continue
	[ "$(uci_get "$section" protocol)" = https ] || continue
	to_web "$section" 0 1 80 "$(uci_get "$section" backend_port 443)"
done

sed -n 's/^@route\[\([0-9][0-9]*\)\]$/\1/p' "$CONSUMED" | sort -rn | while read -r index; do
	uci -q delete "$CONFIG.@route[$index]" || true
done
	MIGRATED=1

fi

if [ "$SCHEMA_VERSION" -lt 3 ] 2>/dev/null; then
	if [ "$(uci_get main enabled 0)" = 1 ] &&
		grep -q '^# Generated by luci-app-haproxy-manager\.' "$HAPROXY_CFG" 2>/dev/null; then
		uci set "$CONFIG.main.active_mode=generated"
	else
		uci set "$CONFIG.main.active_mode=none"
	fi
	uci set "$CONFIG.main.schema_version=3"
	uci commit "$CONFIG"
	MIGRATED=1
fi

[ "$MIGRATED" != 1 ] || echo "Configuration schema upgraded to version 3"
