#!/bin/sh
set -eu

ENV_FILE="${1:-/tmp/router.env}"

log() {
  echo
  echo "==> $1"
}

die() {
  echo "ERROR: $1"
  exit 1
}

require_var() {
  eval "v=\${$1:-}"
  [ -n "$v" ] || die "Missing variable: $1"
}

backup_configs() {
  mkdir -p /root/litoral-backups
  TS="$(date +%Y%m%d-%H%M%S || echo unknown)"
  cp /etc/config/network "/root/litoral-backups/network.$TS.bak" || true
  cp /etc/config/firewall "/root/litoral-backups/firewall.$TS.bak" || true
  cp /etc/config/system "/root/litoral-backups/system.$TS.bak" || true
  cp /etc/config/uhttpd "/root/litoral-backups/uhttpd.$TS.bak" || true
}

[ -f "$ENV_FILE" ] || die "Missing env file: $ENV_FILE"
. "$ENV_FILE"

require_var ROUTER_ID
require_var HOSTNAME
require_var LAN_IP
require_var LAN_NETMASK
require_var WG_IP
require_var WG_CIDR
require_var WG_SERVER_HOST
require_var WG_SERVER_PORT
require_var WG_SERVER_PUBLIC_KEY
require_var CONTROLLER_IP
require_var PLC_IP
require_var ROOT_PASSWORD

log "Starting Litoral_Regas production provisioning"

log "Verifying board and firmware"
BOARD="$(ubus call system board | jsonfilter -e '@.board_name')"
VERSION="$(ubus call system board | jsonfilter -e '@.release.version')"

[ "$BOARD" = "zbtlink,zbt-we826-16m" ] || die "Wrong board: $BOARD"

case "$VERSION" in
  23.05.*) echo "OpenWrt version OK: $VERSION" ;;
  *) die "Wrong OpenWrt version: $VERSION" ;;
esac

log "Creating config backups"
backup_configs

log "Setting hostname"
uci set system.@system[0].hostname="$HOSTNAME"
uci commit system

log "Setting root password"
printf "%s\n%s\n" "$ROOT_PASSWORD" "$ROOT_PASSWORD" | passwd root

log "Configuring LAN"
uci set network.lan.ipaddr="$LAN_IP"
uci set network.lan.netmask="$LAN_NETMASK"
uci commit network

log "Preparing WireGuard keys"
mkdir -p /etc/wireguard
chmod 700 /etc/wireguard

if [ ! -f /etc/wireguard/privatekey ]; then
  umask 077
  wg genkey > /etc/wireguard/privatekey
  cat /etc/wireguard/privatekey | wg pubkey > /etc/wireguard/publickey
fi

ROUTER_PRIVATE_KEY="$(cat /etc/wireguard/privatekey)"
ROUTER_PUBLIC_KEY="$(cat /etc/wireguard/publickey)"

log "Configuring WireGuard"
uci -q delete network.wg0 || true
uci -q delete network.wgserver || true

uci set network.wg0="interface"
uci set network.wg0.proto="wireguard"
uci set network.wg0.private_key="$ROUTER_PRIVATE_KEY"
uci add_list network.wg0.addresses="$WG_IP/$WG_CIDR"

uci set network.wgserver="wireguard_wg0"
uci set network.wgserver.description="Litoral_Regas_VPS"
uci set network.wgserver.public_key="$WG_SERVER_PUBLIC_KEY"
uci set network.wgserver.endpoint_host="$WG_SERVER_HOST"
uci set network.wgserver.endpoint_port="$WG_SERVER_PORT"
uci set network.wgserver.persistent_keepalive="25"
uci set network.wgserver.route_allowed_ips="1"
uci add_list network.wgserver.allowed_ips="198.19.0.0/16"

uci commit network

log "Configuring LuCI over WireGuard"
uci set uhttpd.main.rfc1918_filter="0"
uci commit uhttpd

log "Configuring firewall zones and forwarding"

uci -q delete firewall.vpn || true
uci -q delete firewall.vpn_lan || true
uci -q delete firewall.lan_vpn || true

uci set firewall.vpn="zone"
uci set firewall.vpn.name="vpn"
uci set firewall.vpn.input="ACCEPT"
uci set firewall.vpn.output="ACCEPT"
uci set firewall.vpn.forward="ACCEPT"
uci add_list firewall.vpn.network="wg0"

uci set firewall.vpn_lan="forwarding"
uci set firewall.vpn_lan.src="vpn"
uci set firewall.vpn_lan.dest="lan"

uci set firewall.lan_vpn="forwarding"
uci set firewall.lan_vpn.src="lan"
uci set firewall.lan_vpn.dest="vpn"

log "Configuring DNAT rules"

uci -q delete firewall.dnat_controller_vnc || true
uci -q delete firewall.dnat_controller_runtime || true
uci -q delete firewall.dnat_controller_http || true
uci -q delete firewall.dnat_plc_http || true

uci set firewall.dnat_controller_vnc="redirect"
uci set firewall.dnat_controller_vnc.name="DNAT_Controller_VNC_5900"
uci set firewall.dnat_controller_vnc.src="vpn"
uci set firewall.dnat_controller_vnc.dest="lan"
uci set firewall.dnat_controller_vnc.proto="tcp"
uci set firewall.dnat_controller_vnc.src_dport="5900"
uci set firewall.dnat_controller_vnc.dest_ip="$CONTROLLER_IP"
uci set firewall.dnat_controller_vnc.dest_port="5900"
uci set firewall.dnat_controller_vnc.target="DNAT"

uci set firewall.dnat_controller_runtime="redirect"
uci set firewall.dnat_controller_runtime.name="DNAT_Controller_20248_to_20249"
uci set firewall.dnat_controller_runtime.src="vpn"
uci set firewall.dnat_controller_runtime.dest="lan"
uci set firewall.dnat_controller_runtime.proto="tcp"
uci set firewall.dnat_controller_runtime.src_dport="20248"
uci set firewall.dnat_controller_runtime.dest_ip="$CONTROLLER_IP"
uci set firewall.dnat_controller_runtime.dest_port="20249"
uci set firewall.dnat_controller_runtime.target="DNAT"

uci set firewall.dnat_controller_http="redirect"
uci set firewall.dnat_controller_http.name="DNAT_Controller_HTTP_8000"
uci set firewall.dnat_controller_http.src="vpn"
uci set firewall.dnat_controller_http.dest="lan"
uci set firewall.dnat_controller_http.proto="tcp"
uci set firewall.dnat_controller_http.src_dport="8000"
uci set firewall.dnat_controller_http.dest_ip="$CONTROLLER_IP"
uci set firewall.dnat_controller_http.dest_port="8000"
uci set firewall.dnat_controller_http.target="DNAT"

uci set firewall.dnat_plc_http="redirect"
uci set firewall.dnat_plc_http.name="DNAT_PLC_HTTP_81"
uci set firewall.dnat_plc_http.src="vpn"
uci set firewall.dnat_plc_http.dest="lan"
uci set firewall.dnat_plc_http.proto="tcp"
uci set firewall.dnat_plc_http.src_dport="81"
uci set firewall.dnat_plc_http.dest_ip="$PLC_IP"
uci set firewall.dnat_plc_http.dest_port="81"
uci set firewall.dnat_plc_http.target="DNAT"

uci commit firewall

log "Writing provisioning markers"
cat > /etc/litoral-router <<EOF
ROUTER_ID=$ROUTER_ID
HOSTNAME=$HOSTNAME
LAN_IP=$LAN_IP
WG_IP=$WG_IP/$WG_CIDR
PROVISIONED_AT=$(date || true)
EOF

touch /etc/litoral_provisioned

log "Restarting services"
service system reload
service uhttpd restart
service firewall restart
service network restart

log "Verification summary"
echo "Hostname: $(uci get system.@system[0].hostname)"
echo "LAN IP: $(uci get network.lan.ipaddr)"
echo "WG IP: $WG_IP/$WG_CIDR"
echo "Board: $BOARD"
echo "OpenWrt: $VERSION"

echo
echo "ROUTER PUBLIC KEY:"
echo "$ROUTER_PUBLIC_KEY"

echo
echo "Add this peer to the VPS:"
echo "[Peer]"
echo "PublicKey = $ROUTER_PUBLIC_KEY"
echo "AllowedIPs = $WG_IP/32"

echo
echo "Provisioning complete."
