#!/bin/bash
#
# ============================================================================
# STANDALONE REPRODUCER: Load Balancer + Provider Network (localnet) Bug
# ============================================================================
#
# This script reproduces the issue where a Load Balancer gets incorrectly
# associated to a provider network with localnet port (VLAN network),
# causing SYN packet drops and high latency when accessing via Floating IP.
#
# The script is self-contained and includes all necessary functions.
#
# Requirements:
# - edit /etc/neutron/plugins/ml2/ml2_conf.ini to ensure:
#    -[ml2]
#     type_drivers = flat,vlan,vxlan
#    -[ml2_type_flat]
#     flat_networks = provider,public,physnet1

# - OpenStack deployment with OVN as networking backend
# - Octavia with OVN provider driver
# - ovn-nbctl available (with sudo access if needed)
# - OpenStack CLI configured with credentials
#
# Usage:
#   ./lb_localnet_bug_reproducer_standalone.sh
#
# ============================================================================

set -e

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

# Check if we need sudo for ovn-nbctl
OVN_NBCTL="sudo ovn-nbctl"

# Global variables for cleanup
NET_ID=""
SUBNET_ID=""
ROUTER_ID=""
LB_ID=""
FIP_ID=""
MEMBER_PORT_ID=""
PROVIDER_NET_ID=""
PROVIDER_SUBNET_ID=""
PROVIDER_NET_CREATED=0

# ============================================================================
# CLEANUP FUNCTION
# ============================================================================
cleanup() {
    echo
    echo -e "${YELLOW}Cleaning up resources...${NC}"

    # Delete FIP if exists
    if [ -n "$FIP_ID" ]; then
        echo "Deleting Floating IP..."
        openstack floating ip delete $FIP_ID 2>/dev/null || true
    fi

    # Delete LB if exists
    if [ -n "$LB_ID" ]; then
        echo "Deleting Load Balancer..."
        openstack loadbalancer delete --cascade $LB_ID 2>/dev/null || true
        echo "Waiting for LB deletion..."
        sleep 5
    fi

    # Delete member port if exists
    if [ -n "$MEMBER_PORT_ID" ]; then
        echo "Deleting member port..."
        openstack port delete $MEMBER_PORT_ID 2>/dev/null || true
    fi

    # Delete router interfaces
    if [ -n "$ROUTER_ID" ] && [ -n "$SUBNET_ID" ]; then
        echo "Removing router interface..."
        openstack router remove subnet $ROUTER_ID $SUBNET_ID 2>/dev/null || true
    fi

    # Delete router
    if [ -n "$ROUTER_ID" ]; then
        echo "Deleting router..."
        openstack router delete $ROUTER_ID 2>/dev/null || true
    fi

    # Delete tenant network
    if [ -n "$NET_ID" ]; then
        echo "Deleting tenant network..."
        openstack network delete $NET_ID 2>/dev/null || true
    fi

    # Delete provider network if we created it
    if [ $PROVIDER_NET_CREATED -eq 1 ] && [ -n "$PROVIDER_NET_ID" ]; then
        echo "Deleting provider network..."
        openstack network delete $PROVIDER_NET_ID 2>/dev/null || true
    fi

    echo -e "${GREEN}Cleanup complete${NC}"
}

# Register cleanup on exit
trap cleanup EXIT

# ============================================================================
# HELPER FUNCTIONS
# ============================================================================

check_network_has_localnet() {
    local LS_NAME=$1
    local HAS_LOCALNET=0

    $OVN_NBCTL --no-leader-only lsp-list "$LS_NAME" 2>/dev/null | while IFS= read -r line; do
        PORT_UUID=$(echo "$line" | awk '{print $1}')
        if [ -n "$PORT_UUID" ]; then
            PORT_TYPE=$($OVN_NBCTL --no-leader-only lsp-get-type "$PORT_UUID" 2>/dev/null || echo "")
            if [ "$PORT_TYPE" = "localnet" ]; then
                echo "1"
                return
            fi
        fi
    done
    echo "0"
}

wait_for_lb_active() {
    local lb_id=$1
    echo "Waiting for LB to become ACTIVE..."
    while true; do
        LB_STATUS=$(openstack loadbalancer show -f value -c provisioning_status $lb_id)
        if [ "$LB_STATUS" = "ACTIVE" ]; then
            break
        elif [ "$LB_STATUS" = "ERROR" ]; then
            echo -e "${RED}LB entered ERROR state${NC}"
            return 1
        fi
        echo -n "."
        sleep 2
    done
    echo
    return 0
}

# ============================================================================
# PART 1: SETUP PROVIDER NETWORK WITH LOCALNET
# ============================================================================

setup_provider_network() {
    echo -e "${BLUE}========================================${NC}"
    echo -e "${BLUE}Part 1: Setting up Provider Network${NC}"
    echo -e "${BLUE}========================================${NC}"
    echo

    # Check for existing provider networks with localnet
    echo "Checking for existing provider networks with localnet..."

    EXISTING_PROVIDER=""
    while IFS= read -r NET_ID_LINE; do
        if [ -z "$NET_ID_LINE" ]; then
            continue
        fi
        LS_NAME="neutron-$NET_ID_LINE"
        HAS_LOCALNET=$($OVN_NBCTL --no-leader-only lsp-list "$LS_NAME" 2>/dev/null | while IFS= read -r line; do
            PORT_UUID=$(echo "$line" | awk '{print $1}')
            if [ -n "$PORT_UUID" ]; then
                PORT_TYPE=$($OVN_NBCTL --no-leader-only lsp-get-type "$PORT_UUID" 2>/dev/null || echo "")
                if [ "$PORT_TYPE" = "localnet" ]; then
                    echo "yes"
                    break
                fi
            fi
        done)

        if [ "$HAS_LOCALNET" = "yes" ]; then
            NET_NAME=$(openstack network show -f value -c name "$NET_ID_LINE")
            echo -e "${GREEN}Found existing provider network with localnet:${NC}"
            echo "  Name: $NET_NAME"
            echo "  ID: $NET_ID_LINE"
            EXISTING_PROVIDER="$NET_ID_LINE"
            break
        fi
    done < <(openstack network list --external -f value -c ID)

    if [ -n "$EXISTING_PROVIDER" ]; then
        PROVIDER_NET_ID="$EXISTING_PROVIDER"
        echo -e "${GREEN}✓ Using existing provider network: $PROVIDER_NET_ID${NC}"
        return 0
    fi

    echo "No existing provider network with localnet found."
    echo "Creating a new one..."
    echo

    # Check OVN bridge mappings
    echo -e "${YELLOW}Checking OVN bridge mappings...${NC}"
    CURRENT_MAPPINGS=$(sudo ovs-vsctl get open . external-ids:ovn-bridge-mappings 2>/dev/null | tr -d '"' || echo "")
    echo "Current mappings: $CURRENT_MAPPINGS"

    # Default values
    PHYSICAL_NETWORK="physnet1"
    BRIDGE="br-ex"
    VLAN_ID=100

    # Configure bridge mapping if needed
    if [[ -z "$CURRENT_MAPPINGS" ]]; then
        NEW_MAPPINGS="$PHYSICAL_NETWORK:$BRIDGE"
    elif [[ "$CURRENT_MAPPINGS" == *"$PHYSICAL_NETWORK:$BRIDGE"* ]]; then
        NEW_MAPPINGS="$CURRENT_MAPPINGS"
    else
        NEW_MAPPINGS="$CURRENT_MAPPINGS,$PHYSICAL_NETWORK:$BRIDGE"
    fi

    echo "Setting bridge mapping: $NEW_MAPPINGS"
    sudo ovs-vsctl set open . external-ids:ovn-bridge-mappings="$NEW_MAPPINGS" 2>/dev/null || true

    # Create provider network
    PROVIDER_NET_NAME="provider-test-$(date +%s)"
    echo
    echo "Creating provider network: $PROVIDER_NET_NAME"
    echo "Physical network: $PHYSICAL_NETWORK"
    echo "VLAN ID: $VLAN_ID"

    PROVIDER_NET_ID=$(openstack network create \
        --provider-network-type vlan \
        --provider-physical-network "$PHYSICAL_NETWORK" \
        --provider-segment "$VLAN_ID" \
        --external \
        --share \
        -f value -c id \
        "$PROVIDER_NET_NAME" 2>&1) || {

        echo -e "${YELLOW}VLAN network creation failed, trying flat network...${NC}"
        PROVIDER_NET_ID=$(openstack network create \
            --provider-network-type flat \
            --provider-physical-network "$PHYSICAL_NETWORK" \
            --external \
            --share \
            -f value -c id \
            "$PROVIDER_NET_NAME-flat" 2>&1) || {
            echo -e "${RED}Failed to create provider network${NC}"
            echo "Error: $PROVIDER_NET_ID"
            echo
            echo "Please ensure physical network is configured in Neutron ML2 config"
            exit 1
        }
    }

    echo -e "${GREEN}✓ Provider network created: $PROVIDER_NET_ID${NC}"
    PROVIDER_NET_CREATED=1

    # Create subnet
    SUBNET_CIDR="172.24.4.0/24"
    echo "Creating subnet: $SUBNET_CIDR"
    PROVIDER_SUBNET_ID=$(openstack subnet create \
        --network "$PROVIDER_NET_ID" \
        --subnet-range "$SUBNET_CIDR" \
        --allocation-pool start=172.24.4.100,end=172.24.4.200 \
        --gateway 172.24.4.1 \
        --no-dhcp \
        -f value -c id \
        "subnet-$PROVIDER_NET_NAME")

    echo -e "${GREEN}✓ Subnet created: $PROVIDER_SUBNET_ID${NC}"

    # Wait for OVN to create localnet port
    echo "Waiting for OVN to create localnet port..."
    sleep 3

    PROVIDER_LS="neutron-$PROVIDER_NET_ID"
    LOCALNET_FOUND=0
    for i in {1..10}; do
        $OVN_NBCTL --no-leader-only lsp-list "$PROVIDER_LS" 2>/dev/null | while IFS= read -r line; do
            PORT_UUID=$(echo "$line" | awk '{print $1}')
            if [ -n "$PORT_UUID" ]; then
                PORT_TYPE=$($OVN_NBCTL --no-leader-only lsp-get-type "$PORT_UUID" 2>/dev/null || echo "")
                if [ "$PORT_TYPE" = "localnet" ]; then
                    echo -e "${GREEN}✓ localnet port created!${NC}"
                    LOCALNET_FOUND=1
                    break 2
                fi
            fi
        done
        echo "Waiting for localnet port... ($i/10)"
        sleep 2
    done

    echo -e "${GREEN}✓ Provider network setup complete${NC}"
}

# ============================================================================
# PART 2: REPRODUCE THE BUG SCENARIO
# ============================================================================

reproduce_bug() {
    echo
    echo -e "${BLUE}========================================${NC}"
    echo -e "${BLUE}Part 2: Reproducing the Bug Scenario${NC}"
    echo -e "${BLUE}========================================${NC}"
    echo

    # Step 1: Create tenant network
    echo -e "${BLUE}Step 1: Creating tenant network${NC}"
    echo "=========================================="

    NET_NAME="test-tenant-net-$(date +%s)"
    NET_ID=$(openstack network create -f value -c id $NET_NAME)
    echo "Network ID: $NET_ID"

    SUBNET_NAME="test-subnet"
    SUBNET_ID=$(openstack subnet create -f value -c id \
        --network $NET_ID \
        --subnet-range 10.0.10.0/24 \
        $SUBNET_NAME)
    echo "Subnet ID: $SUBNET_ID"

    # Step 2: Create Load Balancer
    echo
    echo -e "${BLUE}Step 2: Creating Load Balancer on tenant network${NC}"
    echo "=========================================="

    LB_NAME="test-lb-$(date +%s)"
    LB_ID=$(openstack loadbalancer create -f value -c id \
        --name $LB_NAME \
        --provider ovn \
        --vip-subnet-id $SUBNET_ID)
    echo "Load Balancer ID: $LB_ID"

    wait_for_lb_active $LB_ID
    echo -e "${GREEN}Load Balancer is ACTIVE${NC}"

    # Get LB VIP address and port
    LB_VIP=$(openstack loadbalancer show -f value -c vip_address $LB_ID)
    LB_VIP_PORT_ID=$(openstack loadbalancer show -f value -c vip_port_id $LB_ID)
    echo "LB VIP: $LB_VIP"
    echo "LB VIP Port ID: $LB_VIP_PORT_ID"

    # Get OVN LB UUID
    echo "Looking up Load Balancer in OVN..."
    OVN_LB_UUID=$($OVN_NBCTL --no-leader-only --format=csv --no-headings --columns=_uuid \
        find Load_Balancer name="$LB_ID" 2>/dev/null || echo "")

    if [ -z "$OVN_LB_UUID" ]; then
        echo "Waiting 10 seconds and retrying..."
        sleep 10
        OVN_LB_UUID=$($OVN_NBCTL --no-leader-only --format=csv --no-headings --columns=_uuid \
            find Load_Balancer name="$LB_ID" 2>/dev/null || echo "")
    fi

    if [ -z "$OVN_LB_UUID" ]; then
        echo -e "${RED}Error: Load Balancer not found in OVN${NC}"
        exit 1
    fi
    echo "OVN LB UUID: $OVN_LB_UUID"

    # Step 3: Create listener and pool
    echo
    echo -e "${BLUE}Step 3: Creating listener and pool${NC}"
    echo "=========================================="

    LISTENER_ID=$(openstack loadbalancer listener create -f value -c id \
        --protocol TCP \
        --protocol-port 80 \
        --name test-listener \
        $LB_ID)
    echo "Listener ID: $LISTENER_ID"

    wait_for_lb_active $LB_ID

    POOL_ID=$(openstack loadbalancer pool create -f value -c id \
        --protocol TCP \
        --lb-algorithm SOURCE_IP_PORT \
        --listener $LISTENER_ID \
        --name test-pool)
    echo "Pool ID: $POOL_ID"

    wait_for_lb_active $LB_ID

    # Step 4: Create router and connect to external network
    echo
    echo -e "${BLUE}Step 4: Creating router and connecting to external network${NC}"
    echo "=========================================="

    ROUTER_NAME="test-router-$(date +%s)"
    ROUTER_ID=$(openstack router create -f value -c id $ROUTER_NAME)
    echo "Router ID: $ROUTER_ID"

    PUBLIC_NET="$PROVIDER_NET_ID"
    echo "External Network ID: $PUBLIC_NET"

    # Check network info
    PROVIDER_TYPE=$(openstack network show -f value -c provider:network_type "$PUBLIC_NET" 2>/dev/null || echo "")
    PROVIDER_PHYSICAL=$(openstack network show -f value -c provider:physical_network "$PUBLIC_NET" 2>/dev/null || echo "")
    echo "Provider Type: $PROVIDER_TYPE"
    echo "Physical Network: $PROVIDER_PHYSICAL"

    PROVIDER_LS="neutron-$PUBLIC_NET"
    echo "Provider Logical Switch: $PROVIDER_LS"

    # Set external gateway
    echo "Setting router external gateway..."
    openstack router set --external-gateway $PUBLIC_NET $ROUTER_ID

    # Add tenant subnet to router
    echo "Adding tenant subnet to router..."
    openstack router add subnet $ROUTER_ID $SUBNET_ID

    echo
    echo -e "${YELLOW}⏳ Waiting 5 seconds for OVN events to process...${NC}"
    sleep 5

    # Step 5: CHECK FOR THE BUG
    echo
    echo -e "${BLUE}Step 5: 🔍 CHECKING FOR THE ISSUE 🔍${NC}"
    echo "=========================================="

    TENANT_LS="neutron-$NET_ID"
    echo "Tenant Logical Switch: $TENANT_LS"

    echo
    echo "1. LBs in TENANT network (should have the LB):"
    TENANT_LBS=$($OVN_NBCTL --no-leader-only --format=csv --no-headings --columns=load_balancer find Logical_Switch name="$TENANT_LS")
    echo "  Raw output: $TENANT_LBS"
    if [[ "$TENANT_LBS" == *"$OVN_LB_UUID"* ]]; then
        echo -e "${GREEN}  ✓ LB IS associated to tenant network (CORRECT)${NC}"
    else
        echo -e "${RED}  ✗ LB is NOT associated to tenant network (WRONG)${NC}"
    fi

    echo
    echo "2. LBs in PROVIDER network (should be EMPTY):"
    PROVIDER_LBS=$($OVN_NBCTL --no-leader-only --format=csv --no-headings --columns=load_balancer find Logical_Switch name="$PROVIDER_LS")
    echo "  Raw output: $PROVIDER_LBS"
    BUG_FOUND=0
    if [[ "$PROVIDER_LBS" == *"$OVN_LB_UUID"* ]]; then
        echo -e "${RED}  ✗✗✗ LB IS associated to provider network (WRONG - BUG!)${NC}"
        echo -e "${RED}  This is the BUG we're trying to fix!${NC}"
        BUG_FOUND=1
    else
        echo -e "${GREEN}  ✓ LB is NOT associated to provider network (CORRECT)${NC}"
    fi

    # Step 6: Create member in provider network
    echo
    echo -e "${BLUE}Step 6: Creating member in provider network${NC}"
    echo "=========================================="

    # Get IPv4 subnet only (filter out IPv6 subnets)
    PROVIDER_SUBNET_ID_CHECK=""
    while IFS= read -r SUBNET_ID_LINE; do
        if [ -z "$SUBNET_ID_LINE" ]; then
            continue
        fi
        # Check if this subnet is IPv4 (ip_version = 4)
        IP_VERSION=$(openstack subnet show -f value -c ip_version "$SUBNET_ID_LINE" 2>/dev/null || echo "")
        if [ "$IP_VERSION" = "4" ]; then
            PROVIDER_SUBNET_ID_CHECK="$SUBNET_ID_LINE"
            break
        fi
    done < <(openstack subnet list --network $PUBLIC_NET -f value -c ID)

    if [ -z "$PROVIDER_SUBNET_ID_CHECK" ]; then
        echo -e "${RED}Error: Could not find IPv4 subnet in provider network${NC}"
        echo "Available subnets:"
        openstack subnet list --network $PUBLIC_NET
        exit 1
    fi

    # Get subnet CIDR and allocation pool to determine a valid IP
    PROVIDER_SUBNET_CIDR=$(openstack subnet show -f value -c cidr $PROVIDER_SUBNET_ID_CHECK)
    PROVIDER_ALLOC_POOL=$(openstack subnet show -f value -c allocation_pools $PROVIDER_SUBNET_ID_CHECK)
    echo "Provider subnet ID: $PROVIDER_SUBNET_ID_CHECK"
    echo "Provider subnet CIDR: $PROVIDER_SUBNET_CIDR"
    echo "Provider allocation pool: $PROVIDER_ALLOC_POOL"

    # Extract a valid IPv4 from the allocation pool (get start IP and add offset)
    # Format is like: [{'start': '192.168.5.10', 'end': '192.168.5.200'}] or start=X, end=Y
    POOL_START=$(echo "$PROVIDER_ALLOC_POOL" | grep -oE "([0-9]{1,3}\.){3}[0-9]{1,3}" | head -1)

    if [ -n "$POOL_START" ]; then
        # Use an IP near the end of the pool start (add 40 to last octet to avoid conflicts)
        BASE_IP=$(echo "$POOL_START" | cut -d. -f1-3)
        LAST_OCTET=$(echo "$POOL_START" | cut -d. -f4)
        NEW_OCTET=$((LAST_OCTET + 40))
        # Ensure we don't exceed 254
        if [ $NEW_OCTET -gt 254 ]; then
            NEW_OCTET=$((LAST_OCTET + 5))
        fi
        MEMBER_IP="${BASE_IP}.${NEW_OCTET}"
    else
        # Fallback: derive from CIDR (e.g., 192.168.5.0/24 -> 192.168.5.150)
        BASE_IP=$(echo "$PROVIDER_SUBNET_CIDR" | cut -d/ -f1 | cut -d. -f1-3)
        MEMBER_IP="${BASE_IP}.150"
    fi
    echo "Using Member IP: $MEMBER_IP"

    MEMBER_PORT_ID=$(openstack port create -f value -c id \
        --network $PUBLIC_NET \
        --fixed-ip subnet=$PROVIDER_SUBNET_ID_CHECK,ip-address=$MEMBER_IP \
        --no-security-group \
        --disable-port-security \
        test-member-port)
    echo "Member Port ID: $MEMBER_PORT_ID"
    echo "Member IP: $MEMBER_IP"

    MEMBER_ID=$(openstack loadbalancer member create -f value -c id \
        --address $MEMBER_IP \
        --protocol-port 80 \
        --subnet-id $PROVIDER_SUBNET_ID_CHECK \
        --name test-member \
        $POOL_ID)
    echo "Member ID: $MEMBER_ID"

    wait_for_lb_active $LB_ID

    # Re-check LB associations after adding member
    echo
    echo -e "${YELLOW}Re-checking LB associations after adding member...${NC}"
    echo

    echo "1. LBs in TENANT network:"
    TENANT_LBS=$($OVN_NBCTL --no-leader-only --format=csv --no-headings --columns=load_balancer find Logical_Switch name="$TENANT_LS")
    if [[ "$TENANT_LBS" == *"$OVN_LB_UUID"* ]]; then
        echo -e "${GREEN}  ✓ LB IS associated to tenant network (CORRECT)${NC}"
    else
        echo -e "${RED}  ✗ LB is NOT associated to tenant network (WRONG)${NC}"
    fi

    echo
    echo "2. LBs in PROVIDER network:"
    PROVIDER_LBS=$($OVN_NBCTL --no-leader-only --format=csv --no-headings --columns=load_balancer find Logical_Switch name="$PROVIDER_LS")
    if [[ "$PROVIDER_LBS" == *"$OVN_LB_UUID"* ]]; then
        echo -e "${RED}  ✗✗✗ LB IS associated to provider network (WRONG - BUG!)${NC}"
        BUG_FOUND=1
    else
        echo -e "${GREEN}  ✓ LB is NOT associated to provider network (CORRECT)${NC}"
    fi

    # Step 7: Assign Floating IP
    echo
    echo -e "${BLUE}Step 7: Assigning Floating IP to LB VIP${NC}"
    echo "=========================================="

    FIP_ID=$(openstack floating ip create -f value -c id \
        --port $LB_VIP_PORT_ID \
        $PUBLIC_NET)
    FIP_ADDR=$(openstack floating ip show -f value -c floating_ip_address $FIP_ID)
    echo "Floating IP: $FIP_ADDR"

    echo
    echo -e "${YELLOW}⏳ Waiting 3 seconds for FIP to be configured...${NC}"
    sleep 3

    # Step 8: Test connectivity
    echo
    echo -e "${BLUE}Step 8: Testing connection via Floating IP${NC}"
    echo "=========================================="
    echo "Command: curl -v http://$FIP_ADDR"
    echo
    echo -e "${YELLOW}Note: Connection will likely fail/timeout since there's no real backend.${NC}"
    echo -e "${YELLOW}The important part is checking the LB associations above.${NC}"

    # Summary
    echo
    echo -e "${BLUE}========================================${NC}"
    echo -e "${BLUE}Summary${NC}"
    echo -e "${BLUE}========================================${NC}"
    echo
    echo "Resources created:"
    echo "  - Tenant Network: $NET_NAME ($NET_ID)"
    echo "  - Router: $ROUTER_NAME ($ROUTER_ID)"
    echo "  - Load Balancer: $LB_NAME ($LB_ID)"
    echo "    - OVN UUID: $OVN_LB_UUID"
    echo "    - VIP: $LB_VIP"
    echo "  - Floating IP: $FIP_ADDR ($FIP_ID)"
    echo
    echo "OVN Logical Switches:"
    echo "  - Tenant: $TENANT_LS"
    echo "  - Provider: $PROVIDER_LS"
    echo

    if [ $BUG_FOUND -eq 1 ]; then
        echo -e "${RED}========================================${NC}"
        echo -e "${RED}🐛 BUG REPRODUCED! 🐛${NC}"
        echo -e "${RED}========================================${NC}"
        echo
        echo -e "${RED}The Load Balancer is incorrectly associated to the provider network!${NC}"
        echo -e "${RED}This causes SYN packet drops and high latency on FIP connections.${NC}"
        echo
        echo "To verify:"
        echo "  $OVN_NBCTL --format=csv --no-headings --columns=load_balancer find Logical_Switch name=$PROVIDER_LS"
        echo
        echo "To manually fix (remove LB from provider network):"
        echo "  $OVN_NBCTL --if-exists remove Logical_Switch $PROVIDER_LS load_balancer $OVN_LB_UUID"
        echo
        echo "Expected behavior with fix:"
        echo "  - LB should NOT be associated to provider networks with localnet ports"
        echo "  - The fix detects localnet ports and skips LB association"
    else
        echo -e "${GREEN}========================================${NC}"
        echo -e "${GREEN}✓ No bug detected (fix may already be applied)${NC}"
        echo -e "${GREEN}========================================${NC}"
        echo
        echo -e "${GREEN}The Load Balancer is correctly NOT associated to the provider network.${NC}"
    fi

    echo
    echo "Press Ctrl+C to cleanup and exit, or Enter to keep resources for testing..."
    read -p "" WAIT

    # Disable auto-cleanup if user chose to keep resources
    trap - EXIT
    echo
    echo "Resources kept for manual testing. To cleanup manually:"
    echo "  openstack loadbalancer delete --cascade $LB_ID"
    echo "  openstack floating ip delete $FIP_ID"
    echo "  openstack port delete $MEMBER_PORT_ID"
    echo "  openstack router remove subnet $ROUTER_ID $SUBNET_ID"
    echo "  openstack router delete $ROUTER_ID"
    echo "  openstack network delete $NET_ID"
    if [ $PROVIDER_NET_CREATED -eq 1 ]; then
        echo "  openstack network delete $PROVIDER_NET_ID"
    fi
}

# ============================================================================
# MAIN
# ============================================================================

echo -e "${BLUE}========================================${NC}"
echo -e "${BLUE}LB + Provider Network (localnet) Bug Reproducer${NC}"
echo -e "${BLUE}========================================${NC}"
echo
echo -e "${YELLOW}This script will:${NC}"
echo "1. Find or create a provider network with localnet port (VLAN network)"
echo "2. Create a tenant network with a Load Balancer"
echo "3. Connect them via a router"
echo "4. Check if the LB gets incorrectly associated to the provider network"
echo "5. Assign a Floating IP to test connectivity"
echo
echo -e "${YELLOW}The bug causes:${NC}"
echo "  - SYN packet drops when accessing LB via Floating IP"
echo "  - High latency (1+ second delays)"
echo "  - Intermittent connection failures"
echo
read -p "Continue? [y/N]: " CONFIRM
if [[ ! "$CONFIRM" =~ ^[Yy]$ ]]; then
    echo "Aborted"
    exit 0
fi

# Run the reproducer
setup_provider_network
reproduce_bug

echo
echo "Done!"

