#!/bin/bash
# Immediate fix for Incus network - fixes all containers NOW
# Usage: ./fix-network-now.sh

set -euo pipefail

# Colors
GREEN='\033[0;32m'
BLUE='\033[0;34m'
YELLOW='\033[1;33m'
RED='\033[0;31m'
NC='\033[0m'

NETWORK="veza-network"
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"

echo -e "${BLUE}🔧 IMMEDIATE FIX: Incus Network${NC}"
echo ""

# 0. Check host NAT tooling (Incus needs nftables or iptables to implement ipv4.nat=true)
echo -e "${BLUE}0. Checking host NAT tooling (nftables/iptables)...${NC}"
if ! command -v nft >/dev/null 2>&1 && ! command -v iptables >/dev/null 2>&1; then
    echo -e "${RED}❌ ERROR: Neither 'nft' nor 'iptables' is available on the host.${NC}"
    echo "   This is the most common reason containers can reach 10.10.10.1 but not the Internet."
    echo ""
    echo "   Install (Fedora):"
    echo "     sudo dnf install -y nftables iptables-nft"
    echo ""
    echo "   Then re-run:"
    echo "     $0"
    exit 1
fi
echo -e "${GREEN}   ✅ Host NAT tooling present${NC}"

# 1. Enable IP forwarding (CRITICAL)
echo -e "${BLUE}1. Enabling IP forwarding...${NC}"
if [ "$(cat /proc/sys/net/ipv4/ip_forward 2>/dev/null || echo 0)" != "1" ]; then
    if echo "1" | sudo tee /proc/sys/net/ipv4/ip_forward >/dev/null 2>&1; then
        echo -e "${GREEN}   ✅ IP forwarding enabled${NC}"
        # Make persistent
        if ! grep -q "net.ipv4.ip_forward=1" /etc/sysctl.conf 2>/dev/null; then
            echo "net.ipv4.ip_forward=1" | sudo tee -a /etc/sysctl.conf >/dev/null
        fi
    else
        echo -e "${RED}   ❌ Failed to enable IP forwarding${NC}"
        echo "   Run manually: sudo sh -c 'echo 1 > /proc/sys/net/ipv4/ip_forward'"
        exit 1
    fi
else
    echo -e "${GREEN}   ✅ IP forwarding already enabled${NC}"
fi

# 2. Ensure network NAT is enabled (Incus config)
echo -e "${BLUE}2. Ensuring Incus network NAT is enabled...${NC}"
incus network set ${NETWORK} ipv4.nat=true 2>/dev/null || true
incus network set ${NETWORK} ipv4.dhcp=true 2>/dev/null || true
echo -e "${GREEN}   ✅ Network NAT configured${NC}"

# 2b. Ensure host forwarding + masquerade rules exist (Fedora can block FORWARD by default)
echo -e "${BLUE}2b. Ensuring host NAT/FORWARD rules exist...${NC}"

# Detect external interface (default route)
EXT_IF="$(ip route get 8.8.8.8 2>/dev/null | awk '{for(i=1;i<=NF;i++) if ($i=="dev") {print $(i+1); exit}}')"
if [ -z "${EXT_IF}" ]; then
    EXT_IF="$(ip route show default 2>/dev/null | awk '{print $5; exit}')"
fi

# Detect bridge interface by IP 10.10.10.1/24 (avoid regex portability issues)
BR_IF="$(ip -o -4 addr show 2>/dev/null | awk '$4 == "10.10.10.1/24" {print $2; exit}')"
if [ -z "${BR_IF}" ]; then
    # Fallback: try common Incus bridge names
    for c in incusbr0 lxdbr0 ${NETWORK}; do
        if ip link show "${c}" >/dev/null 2>&1; then
            BR_IF="${c}"
            break
        fi
    done
fi

if [ -z "${EXT_IF}" ] || [ -z "${BR_IF}" ]; then
    echo -e "${YELLOW}   ⚠️  Could not auto-detect interfaces.${NC}"
    echo "     External IF: ${EXT_IF:-<unknown>}"
    echo "     Bridge IF:   ${BR_IF:-<unknown>}"
    echo "   You can still continue, but NAT may stay broken."
else
    echo -e "${BLUE}   External interface: ${EXT_IF}${NC}"
    echo -e "${BLUE}   Bridge interface:   ${BR_IF}${NC}"

    # Prefer iptables if available (works with iptables-nft backend on Fedora)
    if command -v iptables >/dev/null 2>&1; then
        # MASQUERADE for container subnet out of external interface
        if sudo iptables -t nat -C POSTROUTING -s 10.10.10.0/24 -o "${EXT_IF}" -j MASQUERADE >/dev/null 2>&1; then
            echo -e "${GREEN}   ✅ iptables MASQUERADE rule already present${NC}"
        else
            sudo iptables -t nat -A POSTROUTING -s 10.10.10.0/24 -o "${EXT_IF}" -j MASQUERADE
            echo -e "${GREEN}   ✅ Added iptables MASQUERADE rule${NC}"
        fi

        # Allow forwarding from bridge to external
        if sudo iptables -C FORWARD -i "${BR_IF}" -o "${EXT_IF}" -j ACCEPT >/dev/null 2>&1; then
            echo -e "${GREEN}   ✅ iptables FORWARD bridge->ext already present${NC}"
        else
            sudo iptables -A FORWARD -i "${BR_IF}" -o "${EXT_IF}" -j ACCEPT
            echo -e "${GREEN}   ✅ Added iptables FORWARD bridge->ext${NC}"
        fi

        # Allow established return traffic from external to bridge
        if sudo iptables -C FORWARD -i "${EXT_IF}" -o "${BR_IF}" -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT >/dev/null 2>&1; then
            echo -e "${GREEN}   ✅ iptables FORWARD ext->bridge (established) already present${NC}"
        else
            sudo iptables -A FORWARD -i "${EXT_IF}" -o "${BR_IF}" -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
            echo -e "${GREEN}   ✅ Added iptables FORWARD ext->bridge (established)${NC}"
        fi
    else
        echo -e "${YELLOW}   ⚠️  iptables not found; not adding explicit rules.${NC}"
        echo "   If NAT is still broken, install iptables-nft and re-run:"
        echo "     sudo dnf install -y iptables-nft"
    fi
fi

# 3. Fix all containers
echo -e "${BLUE}3. Fixing network in all containers...${NC}"
echo ""

CONTAINERS=$(incus list veza- --format csv 2>/dev/null | cut -d',' -f1 || echo "")

if [ -z "${CONTAINERS}" ]; then
    echo -e "${YELLOW}⚠️  No Veza containers found${NC}"
    exit 0
fi

for CONTAINER in ${CONTAINERS}; do
    echo -e "${BLUE}--- Fixing ${CONTAINER} ---${NC}"
    
    # Get IP from device config
    CONTAINER_IP=$(incus config device show ${CONTAINER} 2>/dev/null | grep "ipv4.address" | head -1 | awk '{print $2}' || echo "")
    
    # Fallback methods
    if [ -z "${CONTAINER_IP}" ] || [ "${CONTAINER_IP}" = "" ]; then
        CONTAINER_IP=$(incus list ${CONTAINER} --format csv 2>/dev/null | cut -d',' -f4 | awk '{print $1}' | head -1 || echo "")
    fi
    
    # Determine IP from service type if still not found
    if [ -z "${CONTAINER_IP}" ] || [ "${CONTAINER_IP}" = "" ]; then
        case ${CONTAINER} in
            *infra*) CONTAINER_IP="10.10.10.10" ;;
            *backend-api*) CONTAINER_IP="10.10.10.2" ;;
            *chat-server*) CONTAINER_IP="10.10.10.3" ;;
            *stream-server*) CONTAINER_IP="10.10.10.4" ;;
            *web*) CONTAINER_IP="10.10.10.5" ;;
            *haproxy*) CONTAINER_IP="10.10.10.6" ;;
            *) echo -e "${YELLOW}   ⚠️  Could not determine IP, skipping...${NC}"; continue ;;
        esac
    fi
    
    echo -e "${BLUE}   IP: ${CONTAINER_IP}${NC}"
    
    # Fix network
    if incus exec ${CONTAINER} -- bash -c "
        set -e
        # Flush existing IP
        ip addr flush dev eth0 2>/dev/null || true
        # Add IP
        ip addr add ${CONTAINER_IP}/24 dev eth0 2>/dev/null || \
            ip addr replace ${CONTAINER_IP}/24 dev eth0
        # Remove old routes
        ip route del default 2>/dev/null || true
        ip route del 10.10.10.0/24 2>/dev/null || true
        # Add routes
        ip route add 10.10.10.0/24 dev eth0 proto kernel scope link src ${CONTAINER_IP}
        ip route add default via 10.10.10.1 dev eth0
        # Verify
        if ! ip route | grep -q 'default via 10.10.10.1'; then
            exit 1
        fi
        # DNS
        rm -f /etc/resolv.conf
        echo 'nameserver 8.8.8.8' > /etc/resolv.conf
        echo 'nameserver 1.1.1.1' >> /etc/resolv.conf
        systemctl restart systemd-resolved 2>/dev/null || true
    " 2>/dev/null; then
        echo -e "${GREEN}   ✅ Network configured${NC}"
        
        # Test
        sleep 1
        if incus exec ${CONTAINER} -- ping -c 1 -W 1 8.8.8.8 >/dev/null 2>&1; then
            echo -e "${GREEN}   ✅ Internet connectivity OK${NC}"
        else
            echo -e "${YELLOW}   ⚠️  Internet connectivity test failed${NC}"
        fi
    else
        echo -e "${RED}   ❌ Failed to configure network${NC}"
    fi
    
    echo ""
done

echo -e "${GREEN}✅ Network fix complete!${NC}"
echo ""
echo "Test connectivity:"
echo "  incus exec veza-infra -- ping -c 2 8.8.8.8"
