#!/usr/bin/env bash
# scripts/opnsense-render-config.sh <output-config.xml>
#
# Renders opentofu/templates/opnsense-config.xml.tmpl into a real config.xml
# by substituting {{TOKEN}} markers (this repo's existing clientdocs
# convention, reused here) from required environment variables -- no
# invented defaults except NTP_UPSTREAM_SERVERS/NTP_PREFER_SERVER, which
# default to the SAME public pool OPNsense's own shipped config.xml.sample
# uses (a real, confirmed default, not an invention -- see
# opentofu/templates/README.md). Everything else fails loud if unset.
#
# Feed the result to scripts/opnsense-build-config-iso.sh next.
# Exit: 0 rendered | 1 required token/template missing.
set -euo pipefail
HERE="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
TEMPLATE="$HERE/../opentofu/templates/opnsense-config.xml.tmpl"
OUT="${1:?usage: opnsense-render-config.sh <output-config.xml>}"

: "${NTP_UPSTREAM_SERVERS:=0.opnsense.pool.ntp.org 1.opnsense.pool.ntp.org 2.opnsense.pool.ntp.org 3.opnsense.pool.ntp.org}"
: "${NTP_PREFER_SERVER:=0.opnsense.pool.ntp.org}"

req() { # req VARNAME -- fail loud if unset, no inferred fallback
  local name="$1"
  [ -n "${!name:-}" ] || { echo "FAIL: \$$name not set -- see opentofu/templates/README.md"; exit 1; }
}

REQUIRED_VARS=(
  OPNSENSE_HOSTNAME DOMAIN ROOT_PASSWORD_HASH
  WAN_IF WAN_IPADDR WAN_SUBNET_BITS WAN_GATEWAY
  LAN_IF LAN_IPADDR LAN_SUBNET_BITS
  MIRROR_SYNC_PROTOCOL MIRROR_UPSTREAM_NET MIRROR_SYNC_PORT
)
for v in "${REQUIRED_VARS[@]}"; do
  req "$v"
done

[ -r "$TEMPLATE" ] || { echo "FAIL: template not found: $TEMPLATE"; exit 1; }

route_block() { # route_block <network-var-name> <gateway-var-name> <descr-var-name>
  local net="${!1:-}" gw="${!2:-}" descr="${!3:-}"
  if [ -z "$net" ]; then
    return 0 # no route needed at this site -- emit nothing, not a placeholder
  fi
  [ -n "$gw" ] || { echo "FAIL: \$$1 is set but \$$2 is not"; exit 1; }
  printf '    <route>\n      <network>%s</network>\n      <gateway>%s</gateway>\n      <descr>%s</descr>\n      <enabled>1</enabled>\n    </route>\n' \
    "$net" "$gw" "${descr:-static route}"
}

ROUTE1_BLOCK="$(route_block ROUTE1_NETWORK ROUTE1_GATEWAY ROUTE1_DESCR)"
ROUTE2_BLOCK="$(route_block ROUTE2_NETWORK ROUTE2_GATEWAY ROUTE2_DESCR)"

content="$(cat "$TEMPLATE")"
for v in "${REQUIRED_VARS[@]}" NTP_UPSTREAM_SERVERS NTP_PREFER_SERVER; do
  content="${content//"{{$v}}"/${!v}}"
done
content="${content//"{{ROUTE1_BLOCK}}"/$ROUTE1_BLOCK}"
content="${content//"{{ROUTE2_BLOCK}}"/$ROUTE2_BLOCK}"

if grep -qE '\{\{[A-Z0-9_]+\}\}' <<<"$content"; then
  echo "FAIL: unresolved {{TOKEN}} remains in rendered output -- template/script token lists are out of sync:"
  grep -oE '\{\{[A-Z0-9_]+\}\}' <<<"$content" | sort -u
  exit 1
fi

printf '%s' "$content" > "$OUT"
echo "PASS: rendered $OUT"
