#!/bin/sh
# Enable forwarding between Docker network and WireGuard tunnel
# Idempotent: check before adding to prevent duplicates on restart
# Allow Docker→VPN (poller/API reaching devices)
iptables -C FORWARD -i eth0 -o wg0 -j ACCEPT 2>/dev/null || iptables -A FORWARD -i eth0 -o wg0 -j ACCEPT
# Allow VPN→Docker ONLY (devices reaching poller/API, NOT the public internet)
iptables -C FORWARD -i wg0 -o eth0 -d 172.16.0.0/12 -j ACCEPT 2>/dev/null || iptables -A FORWARD -i wg0 -o eth0 -d 172.16.0.0/12 -j ACCEPT
# Block VPN→anywhere else (prevents using server as exit node)
iptables -C FORWARD -i wg0 -o eth0 -j DROP 2>/dev/null || iptables -A FORWARD -i wg0 -o eth0 -j DROP

# Block cross-subnet traffic on wg0 (tenant isolation)
# Peers in 10.10.1.0/24 cannot reach peers in 10.10.2.0/24
iptables -C FORWARD -i wg0 -o wg0 -j DROP 2>/dev/null || iptables -A FORWARD -i wg0 -o wg0 -j DROP

# Block IPv6 forwarding on wg0 (prevent link-local bypass)
ip6tables -C FORWARD -i wg0 -j DROP 2>/dev/null || ip6tables -A FORWARD -i wg0 -j DROP

# NAT for return traffic — per-tenant SNAT rules are applied by wg-reload watcher
# (nat_rules.sh is generated by sync_wireguard_config)

echo "WireGuard forwarding and tenant isolation rules applied"

# Start config reload watcher in background
# Polls for .reload flag every 2s, applies changes via wg syncconf
(
    CONF_DIR="/config/wg_confs"
    RELOAD_FLAG="$CONF_DIR/.reload"
    echo "wg-reload: watcher started (pid $$)"
    # Wait for wg0 interface to be fully up before processing reloads
    while ! wg show wg0 >/dev/null 2>&1; do
        sleep 2
    done
    # Apply NAT rules on startup if they exist
    if [ -f "$CONF_DIR/nat_rules.sh" ]; then
        sh "$CONF_DIR/nat_rules.sh" 2>&1
        echo "wg-reload: startup NAT rules applied"
    fi
    # Clear any reload flag that was set during startup (interface already has the config)
    rm -f "$RELOAD_FLAG"
    echo "wg-reload: wg0 is up, watching for changes"
    while true; do
        if [ -f "$RELOAD_FLAG" ]; then
            rm -f "$RELOAD_FLAG"
            sleep 0.5
            if [ -f "$CONF_DIR/wg0.conf" ]; then
                # Strip Address and comments; keep ListenPort + PrivateKey + Peers
                # wg syncconf rejects Address but needs ListenPort to preserve it
                grep -v "^Address" "$CONF_DIR/wg0.conf" | grep -v "^#" | wg syncconf wg0 /dev/stdin 2>&1
                # Apply per-tenant SNAT rules for poller connectivity
                if [ -f "$CONF_DIR/nat_rules.sh" ]; then
                    sh "$CONF_DIR/nat_rules.sh" 2>&1
                    echo "wg-reload: NAT rules applied"
                fi
                if [ $? -eq 0 ]; then
                    echo "wg-reload: config applied"
                else
                    echo "wg-reload: syncconf failed"
                fi
            fi
        fi
        sleep 2
    done
) &

# Start status writer in background
# Writes wg_status.json every 15 seconds from `wg show wg0 dump`
(
    STATUS_FILE="/config/wg_status.json"
    # Wait for wg0
    while ! wg show wg0 >/dev/null 2>&1; do
        sleep 2
    done
    echo "wg-status: writer started"
    while true; do
        # Parse `wg show wg0 dump` into JSON array
        # Format: private_key  public_key  listen_port  fwmark
        # Peer lines: public_key  preshared_key  endpoint  allowed_ips  latest_handshake  transfer_rx  transfer_tx  persistent_keepalive
        wg show wg0 dump 2>/dev/null | awk -F'\t' '
            BEGIN { printf "[" ; first=1 }
            NR > 1 {
                if (!first) printf ","
                first=0
                printf "{\"public_key\":\"%s\",\"endpoint\":\"%s\",\"allowed_ips\":\"%s\",\"last_handshake\":%s,\"rx\":%s,\"tx\":%s}",
                    $1, $3, $4, ($5 == "" ? "0" : $5), ($6 == "" ? "0" : $6), ($7 == "" ? "0" : $7)
            }
            END { printf "]\n" }
        ' > "${STATUS_FILE}.tmp" && mv "${STATUS_FILE}.tmp" "$STATUS_FILE"
        sleep 15
    done
) &
