#!/usr/bin/env bash
#
# Host routing script for rego-tunnel
# Routes TARGET_IP through the VPN container
#
set -euo pipefail

ACTION="${1:-start}"

# Fixed configuration (we assigned these)
CONTAINER_IP="172.31.0.10"
BRIDGE_NAME="br-rego-vpn"
TARGET_IP="${TARGET_IP:-10.35.33.230}"
LAN_SUBNET="192.168.0.0/23"
LAN_INTERFACES="eth0 eth1 wlan0"
LOG_FILE="/var/log/rego-routing.log"

log() {
    local msg="[$(date '+%Y-%m-%d %H:%M:%S')] [rego-routing] $*"
    echo "$msg" | tee -a "$LOG_FILE" >&2
}

get_lan_interface() {
    ip route show default | awk '/default/ {for(i=1;i<=NF;i++) if($i=="dev") print $(i+1)}' | head -1
}

remove_routes() {
    log "Removing stale routes for $TARGET_IP..."

    # Remove any existing route to TARGET_IP
    ip route del "$TARGET_IP" 2>/dev/null || true
    ip route del "$TARGET_IP/32" 2>/dev/null || true

    log "Stale routes removed"
}

apply_routes() {
    local lan_if
    lan_if="$(get_lan_interface)"

    log "Applying host routing rules..."
    log "  Container IP: $CONTAINER_IP"
    log "  Bridge: $BRIDGE_NAME"
    log "  Target IP: $TARGET_IP"
    log "  LAN interface: ${lan_if:-unknown}"

    # Enable IP forwarding
    echo 1 > /proc/sys/net/ipv4/ip_forward
    log "IP forwarding enabled"

    # Add route to TARGET_IP via container
    ip route replace "$TARGET_IP/32" via "$CONTAINER_IP" dev "$BRIDGE_NAME"
    log "Route added: $TARGET_IP via $CONTAINER_IP dev $BRIDGE_NAME"

    # Allow forwarding in DOCKER-USER chain for all LAN interfaces
    for lan_if in $LAN_INTERFACES; do
        # Check if interface exists
        if ip link show "$lan_if" &>/dev/null; then
            # Allow traffic from LAN to container for TARGET_IP
            iptables -C DOCKER-USER -i "$lan_if" -o "$BRIDGE_NAME" -d "$TARGET_IP" -j ACCEPT 2>/dev/null || \
                iptables -I DOCKER-USER 1 -i "$lan_if" -o "$BRIDGE_NAME" -d "$TARGET_IP" -j ACCEPT

            # Allow return traffic
            iptables -C DOCKER-USER -i "$BRIDGE_NAME" -o "$lan_if" -s "$TARGET_IP" -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT 2>/dev/null || \
                iptables -I DOCKER-USER 1 -i "$BRIDGE_NAME" -o "$lan_if" -s "$TARGET_IP" -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT

            log "DOCKER-USER iptables rules added for $lan_if <-> $BRIDGE_NAME"
        fi
    done

    # Masquerade traffic from LAN subnet to VPN bridge (so return traffic routes correctly)
    # Use nft since iptables-nft backend doesn't support iptables -t nat commands
    if ! nft list chain ip nat POSTROUTING 2>/dev/null | grep -q "saddr $LAN_SUBNET.*oifname.*$BRIDGE_NAME.*masquerade"; then
        nft add rule ip nat POSTROUTING ip saddr "$LAN_SUBNET" oifname "$BRIDGE_NAME" counter masquerade
        log "NAT masquerade rule added for $LAN_SUBNET -> $BRIDGE_NAME"
    else
        log "NAT masquerade rule already exists for $LAN_SUBNET -> $BRIDGE_NAME"
    fi

    log "OK: Host routing applied - $TARGET_IP via $CONTAINER_IP ($BRIDGE_NAME)"
}

remove_all() {
    log "Removing all routing rules..."

    # Remove route
    ip route del "$TARGET_IP/32" via "$CONTAINER_IP" dev "$BRIDGE_NAME" 2>/dev/null || true

    # Remove iptables rules for all LAN interfaces
    for lan_if in $LAN_INTERFACES; do
        iptables -D DOCKER-USER -i "$lan_if" -o "$BRIDGE_NAME" -d "$TARGET_IP" -j ACCEPT 2>/dev/null || true
        iptables -D DOCKER-USER -i "$BRIDGE_NAME" -o "$lan_if" -s "$TARGET_IP" -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT 2>/dev/null || true
    done

    # Remove masquerade rule (using nft)
    local handle
    handle=$(nft -a list chain ip nat POSTROUTING 2>/dev/null | grep "saddr $LAN_SUBNET.*oifname.*$BRIDGE_NAME.*masquerade" | grep -oP 'handle \K\d+' | head -1 || true)
    if [ -n "$handle" ]; then
        nft delete rule ip nat POSTROUTING handle "$handle" 2>/dev/null || true
    fi

    log "All routing rules removed"
}

case "$ACTION" in
    start)
        remove_routes
        apply_routes
        ;;
    stop)
        remove_all
        ;;
    restart)
        remove_all
        sleep 1
        remove_routes
        apply_routes
        ;;
    *)
        echo "Usage: $0 {start|stop|restart}" >&2
        exit 2
        ;;
esac
