#!/bin/bash

# Dover VPN Connection Script with Semi-Automation
# Usage: ./cisco-vpn.sh [-c|--connect] [-d|--disconnect] [-m|--menu] [-r|--routes] [-h|--hosts] [--help]
#
# Options:
#   -c, --connect  Start Cisco AnyConnect (optionally auto-login) and exit
#   -d, --disconnect  Disconnect (kill Cisco processes) and exit
#   -m, --menu     Skip auto-login, show menu directly
#   -r, --routes   Show current routing table and exit
#   -h, --hosts    Show /etc/hosts and exit
#   -s, --status   Show VPN and network status and exit
#   --help         Show this help message
#
# Keyboard shortcuts (global, work anywhere):
#   Ctrl+1 - Type email
#   Ctrl+2 - Type password
#   Ctrl+3 - Type TOTP code
#   Ctrl+4 - Type email + Tab + password (combo)
#   Ctrl+5 - Full sequence: email + Tab + password + Tab + TOTP + Enter

# Credentials from environment variables (set by runtipi)
EMAIL="${VPN_EMAIL:-}"
PASSWORD="${VPN_PASSWORD:-}"
TOTP_SECRET="${VPN_TOTP_SECRET:-}"
VPN_HOST="${VPN_HOST:-vpn-ord1.dovercorp.com}"
TARGET_IP="${TARGET_IP:-10.35.33.230}"

# Log directory and file (date-based rotation)
LOG_DIR="/var/log/cisco-vpn"
LOG_RETENTION_DAYS=7
mkdir -p "$LOG_DIR" 2>/dev/null

# Function to get current log file (changes daily)
get_log_file() {
    echo "$LOG_DIR/$(date '+%Y-%m-%d').log"
}

# Cleanup old log files (older than LOG_RETENTION_DAYS)
cleanup_old_logs() {
    find "$LOG_DIR" -name "*.log" -type f -mtime +$LOG_RETENTION_DAYS -delete 2>/dev/null
}

# Colors
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
CYAN='\033[0;36m'
GRAY='\033[0;90m'
NC='\033[0m'

# Print banner
print_banner() {
    echo -e "${CYAN}========================================${NC}"
    echo -e "${CYAN}       Dover VPN Connection Script      ${NC}"
    echo -e "${CYAN}========================================${NC}"
    echo ""
}

# Flags
SKIP_AUTO_LOGIN=false
DO_CONNECT=false
DO_DISCONNECT=false

# Logging function with timestamp - writes to both console and daily log file
log() {
    local level="$1"
    local msg="$2"
    local timestamp=$(date '+%Y-%m-%d %H:%M:%S')
    local timestamp_short=$(date '+%H:%M:%S')
    local log_file=$(get_log_file)

    # Strip ANSI color codes for log file
    local msg_plain=$(echo -e "$msg" | sed 's/\x1b\[[0-9;]*m//g')

    # Write to log file (plain text, no colors)
    echo "[$timestamp] [$level] $msg_plain" >> "$log_file"

    # Write to console (with colors)
    case $level in
        INFO)  echo -e "${GRAY}[$timestamp_short]${NC} ${GREEN}[INFO]${NC}  $msg" ;;
        WARN)  echo -e "${GRAY}[$timestamp_short]${NC} ${YELLOW}[WARN]${NC}  $msg" ;;
        ERROR) echo -e "${GRAY}[$timestamp_short]${NC} ${RED}[ERROR]${NC} $msg" ;;
        DEBUG) echo -e "${GRAY}[$timestamp_short]${NC} ${CYAN}[DEBUG]${NC} $msg" ;;
        CMD)   echo -e "${GRAY}[$timestamp_short]${NC} ${GRAY}[CMD]${NC}   $msg" ;;
        *)     echo -e "${GRAY}[$timestamp_short]${NC} $msg" ;;
    esac
}

# Run command with logging
run_cmd() {
    local desc="$1"
    shift
    log CMD "$desc: $*"
    output=$("$@" 2>&1)
    local rc=$?
    if [ -n "$output" ]; then
        echo "$output" | while IFS= read -r line; do
            echo -e "           ${GRAY}│${NC} $line"
        done
    fi
    return $rc
}

# Show help
show_help() {
    echo -e "${CYAN}Dover VPN Connection Script${NC}"
    echo ""
    echo "Usage: $0 [OPTIONS]"
    echo ""
    echo "Options:"
    echo "  -c, --connect  Start Cisco AnyConnect and exit"
    echo "  -d, --disconnect  Disconnect (kill Cisco processes) and exit"
    echo "  -m, --menu     Skip auto-login, show menu directly"
    echo "  -r, --routes   Show current routing table and exit"
    echo "  -h, --hosts    Show /etc/hosts and exit"
    echo "  -s, --status   Show VPN and network status and exit"
    echo "  --help         Show this help message"
    echo ""
    echo "Menu Options:"
    echo "  1 - Start Cisco AnyConnect (kill existing + launch)"
    echo "  2 - Copy credentials to clipboard (one by one)"
    echo "  3 - Show live TOTP"
    echo "  4 - Setup IP forwarding rules only"
    echo "  5 - Test connection to target"
    echo "  6 - Show network status"
    echo "  7 - Kill all Cisco processes"
    echo "  8 - Show routing table"
    echo "  9 - Show /etc/hosts"
    echo "  e - Edit /etc/hosts"
    echo "  q - Quit"
}

# Show routing table
show_routes() {
    echo -e "${CYAN}========================================${NC}"
    echo -e "${CYAN}         Current Routing Table          ${NC}"
    echo -e "${CYAN}========================================${NC}"
    echo ""
    echo -e "${GREEN}IPv4 Routes:${NC}"
    ip -4 route show | while IFS= read -r line; do
        # Highlight VPN-related routes
        if echo "$line" | grep -qE "cscotun|tun[0-9]"; then
            echo -e "  ${YELLOW}$line${NC}"
        elif echo "$line" | grep -qE "10\.|172\.(1[6-9]|2[0-9]|3[01])\.|192\.168\."; then
            echo -e "  ${CYAN}$line${NC}"
        else
            echo "  $line"
        fi
    done
    echo ""
    echo -e "${GREEN}VPN Interface:${NC}"
    local vpn_iface=$(get_vpn_interface)
    if [ -n "$vpn_iface" ]; then
        ip addr show "$vpn_iface" 2>/dev/null | grep -E "inet|link" | while IFS= read -r line; do
            echo "  $line"
        done
    else
        echo -e "  ${RED}No VPN interface found${NC}"
    fi
}

# Show /etc/hosts
show_hosts() {
    echo -e "${CYAN}========================================${NC}"
    echo -e "${CYAN}            /etc/hosts                  ${NC}"
    echo -e "${CYAN}========================================${NC}"
    echo ""
    cat -n /etc/hosts
}

# Edit /etc/hosts
edit_hosts() {
    local editor="${EDITOR:-nano}"
    if command -v "$editor" &>/dev/null; then
        "$editor" /etc/hosts
    else
        log ERROR "No editor found. Set EDITOR environment variable."
        log INFO "Try: nano /etc/hosts"
    fi
}

# Function to get current TOTP
get_totp() {
    oathtool --totp -b "$TOTP_SECRET"
}

# Function to detect VPN tunnel interface dynamically
get_vpn_interface() {
    # Look for cscotun* or tun* interfaces that are UP
    local iface=$(ip link show | grep -oP '(cscotun\d+|tun\d+)(?=:.*UP)' | head -1)
    if [ -z "$iface" ]; then
        # Fallback: any cscotun interface
        iface=$(ip link show | grep -oP 'cscotun\d+' | head -1)
    fi
    echo "$iface"
}

# Function to get container's IP on the rego-tunnel network
get_container_ip() {
    # eth0 is the rego-tunnel network (172.31.0.x)
    ip addr show eth0 2>/dev/null | grep -oP 'inet \K[\d.]+' | head -1
}

# Function to get VPN tunnel IP
get_vpn_ip() {
    local iface=$(get_vpn_interface)
    if [ -n "$iface" ]; then
        ip addr show "$iface" 2>/dev/null | grep -oP 'inet \K[\d.]+' | head -1
    fi
}

# Start xbindkeys for keyboard macros
start_xbindkeys() {
    log INFO "Starting keyboard macro listener (xbindkeys)..."

    # Kill any existing xbindkeys
    pkill xbindkeys 2>/dev/null
    sleep 0.5

    # Start xbindkeys
    xbindkeys -f ~/.xbindkeysrc 2>/dev/null &
    XBINDKEYS_PID=$!

    if pgrep xbindkeys >/dev/null; then
        log DEBUG "xbindkeys started (PID: $(pgrep xbindkeys))"
        log INFO "Keyboard shortcuts active: Ctrl+1=email, Ctrl+2=pass, Ctrl+3=TOTP, Ctrl+4=combo, Ctrl+5=all"
    else
        log WARN "Failed to start xbindkeys"
    fi
}

# Stop xbindkeys
stop_xbindkeys() {
    if pgrep xbindkeys >/dev/null; then
        log INFO "Stopping keyboard macro listener..."
        pkill xbindkeys 2>/dev/null
        log DEBUG "xbindkeys stopped"
    fi
}

# Kill all Cisco-related processes
kill_cisco_processes() {
    local kill_agentd="${1:-false}"
    log INFO "Killing all Cisco-related processes..."

    local killed=0
    local my_pid=$$
    local my_ppid=$(ps -o ppid= -p $$ | tr -d ' ')

    # Kill vpnui specifically (not just any process with "vpn" in name)
    for pid in $(pgrep -x "vpnui" 2>/dev/null); do
        if [ "$pid" != "$my_pid" ] && [ "$pid" != "$my_ppid" ]; then
            log DEBUG "Killing vpnui (PID $pid)"
            kill -9 "$pid" 2>/dev/null && ((killed++))
        fi
    done

    # Optionally kill vpnagentd (useful to clear stale state)
    if [ "$kill_agentd" = "true" ]; then
        for pid in $(pgrep -x "vpnagentd" 2>/dev/null); do
            if [ "$pid" != "$my_pid" ] && [ "$pid" != "$my_ppid" ]; then
                log DEBUG "Killing vpnagentd (PID $pid)"
                kill -9 "$pid" 2>/dev/null && ((killed++))
            fi
        done
    fi

    # Kill Cisco-specific processes by exact path
    for proc in cstub cscan acwebsecagent vpndownloader; do
        for pid in $(pgrep -x "$proc" 2>/dev/null); do
            log DEBUG "Killing $proc (PID $pid)"
            kill -9 "$pid" 2>/dev/null && ((killed++))
        done
    done

    # Kill openconnect (exact match)
    for pid in $(pgrep -x "openconnect" 2>/dev/null); do
        log DEBUG "Killing openconnect (PID $pid)"
        kill -9 "$pid" 2>/dev/null && ((killed++))
    done

    if [ $killed -eq 0 ]; then
        log INFO "No Cisco processes were running"
    else
        log INFO "Killed $killed process(es)"
        sleep 1
    fi

    sleep 5
}

# Disconnect VPN (best-effort)
disconnect_vpn() {
    log INFO "Disconnecting Cisco AnyConnect..."

    # If vpncli exists, attempt a clean disconnect first (ignore failures)
    if [ -x /opt/cisco/secureclient/bin/vpncli ]; then
        run_cmd "Attempting clean disconnect via vpncli" /opt/cisco/secureclient/bin/vpncli -s <<'EOF' || true
disconnect
exit
EOF
    fi

    # Always kill agent/UI processes afterwards
    kill_cisco_processes "true"

    # Confirm status
    if check_vpn_status; then
        log WARN "VPN still appears connected (interface still up)"
        return 1
    fi

    log INFO "VPN disconnected"
    return 0
}

# Function to setup iptables rules for forwarding
setup_forwarding() {
    log INFO "Setting up IP forwarding rules for $TARGET_IP..."

    local vpn_iface=$(get_vpn_interface)
    if [ -z "$vpn_iface" ]; then
        log ERROR "No VPN interface found! Is VPN connected?"
        return 1
    fi

    local vpn_ip=$(get_vpn_ip)
    local container_ip=$(get_container_ip)

    log DEBUG "VPN interface: $vpn_iface"
    log DEBUG "VPN IP: $vpn_ip"
    log DEBUG "Container IP: $container_ip"

    # Enable IP forwarding
    run_cmd "Enabling IP forwarding" sysctl -w net.ipv4.ip_forward=1

    # NAT masquerade for traffic from container network (172.31.0.0/24) going through VPN
    # This is the ONLY masquerade rule needed - source-based, not destination-based
    if ! iptables -t nat -C POSTROUTING -s 172.31.0.0/24 -o "$vpn_iface" -j MASQUERADE 2>/dev/null; then
        run_cmd "Adding NAT masquerade for container network -> VPN" iptables -t nat -A POSTROUTING -s 172.31.0.0/24 -o "$vpn_iface" -j MASQUERADE
    else
        log DEBUG "NAT masquerade for container network already exists"
    fi

    # Forward rules - MUST be at position 1 to run BEFORE cisco VPN chains
    # The cisco VPN chains have catch-all DROP rules that would block our traffic

    # Wait for Cisco to create its chains (they appear after VPN connects)
    local wait_count=0
    while ! iptables -L ciscovpn -n &>/dev/null && [ $wait_count -lt 30 ]; do
        log DEBUG "Waiting for Cisco VPN chains to be created..."
        sleep 1
        ((wait_count++))
    done

    if iptables -L ciscovpn -n &>/dev/null; then
        log DEBUG "Cisco VPN chains detected"
    else
        log WARN "Cisco VPN chains not created after ${wait_count}s - proceeding anyway"
    fi

    # Remove any existing rules first (ignore errors if they don't exist)
    iptables -D FORWARD -d "$TARGET_IP" -j ACCEPT 2>/dev/null || true
    iptables -D FORWARD -s "$TARGET_IP" -j ACCEPT 2>/dev/null || true
    iptables -D FORWARD -s 172.31.0.0/24 -j ACCEPT 2>/dev/null || true
    iptables -D FORWARD -d 172.31.0.0/24 -j ACCEPT 2>/dev/null || true

    # Insert at position 1 (reverse order so they end up in correct order)
    run_cmd "Inserting forward rule (to container network)" iptables -I FORWARD 1 -d 172.31.0.0/24 -j ACCEPT
    run_cmd "Inserting forward rule (from container network)" iptables -I FORWARD 1 -s 172.31.0.0/24 -j ACCEPT
    run_cmd "Inserting forward rule (from target)" iptables -I FORWARD 1 -s "$TARGET_IP" -j ACCEPT
    run_cmd "Inserting forward rule (to target)" iptables -I FORWARD 1 -d "$TARGET_IP" -j ACCEPT

    # Cisco VPN chain bypass (insert at top if chain exists)
    if iptables -L ciscovpn -n &>/dev/null; then
        if ! iptables -C ciscovpn -o "$vpn_iface" -d "$TARGET_IP" -j ACCEPT 2>/dev/null; then
            run_cmd "Adding ciscovpn bypass (outbound)" iptables -I ciscovpn 1 -o "$vpn_iface" -d "$TARGET_IP" -j ACCEPT
        else
            log DEBUG "Ciscovpn bypass (outbound) already exists"
        fi

        if ! iptables -C ciscovpn -i "$vpn_iface" -s "$TARGET_IP" -j ACCEPT 2>/dev/null; then
            run_cmd "Adding ciscovpn bypass (inbound)" iptables -I ciscovpn 2 -i "$vpn_iface" -s "$TARGET_IP" -j ACCEPT
        else
            log DEBUG "Ciscovpn bypass (inbound) already exists"
        fi

        # Also allow container network through ciscovpn chain
        if ! iptables -C ciscovpn -s 172.31.0.0/24 -j ACCEPT 2>/dev/null; then
            run_cmd "Adding ciscovpn bypass (container network)" iptables -I ciscovpn 3 -s 172.31.0.0/24 -j ACCEPT
        fi
    else
        log DEBUG "ciscovpn chain does not exist (yet)"
    fi

    log INFO "Forwarding rules configured"
    echo ""

    # Trigger host routing service restart
    log INFO "Triggering host routing service restart..."
    touch /runtime/restart-routing
    sleep 2
    if [ ! -f /runtime/restart-routing ]; then
        log INFO "Host routing service restarted"
    else
        log WARN "Host watcher may not be running (trigger file still exists)"
    fi

    log INFO "Routing configured for $TARGET_IP through VPN tunnel"
    echo ""
}

# Copy credentials to clipboard as alternative
copy_to_clipboard() {
    log INFO "Starting clipboard credential rotation..."
    echo ""

    log INFO "Copying EMAIL to clipboard"
    echo "$EMAIL" | xclip -selection clipboard
    echo -e "           ${CYAN}Email ready: $EMAIL${NC}"
    echo -e "           Paste now (Ctrl+V), then press ${GREEN}Enter${NC} here for password..."
    read -r

    log INFO "Copying PASSWORD to clipboard"
    echo "$PASSWORD" | xclip -selection clipboard
    echo -e "           ${CYAN}Password ready${NC}"
    echo -e "           Paste now (Ctrl+V), then press ${GREEN}Enter${NC} here for TOTP..."
    read -r

    TOTP=$(get_totp)
    log INFO "Copying TOTP to clipboard"
    echo "$TOTP" | xclip -selection clipboard
    echo -e "           ${CYAN}TOTP ready: $TOTP${NC}"
    echo -e "           Paste now (Ctrl+V)"
}

# Print current TOTP with countdown
show_totp() {
    log INFO "Starting live TOTP display (Ctrl+C to stop)"
    echo ""
    while true; do
        TOTP=$(get_totp)
        SECONDS_LEFT=$((30 - ($(date +%s) % 30)))
        echo -ne "\r           ${CYAN}Current TOTP:${NC} ${GREEN}$TOTP${NC} (expires in ${YELLOW}${SECONDS_LEFT}s${NC})   "
        sleep 1
    done
}

# Show network status
show_network_status() {
    log INFO "Current network status:"

    # Container IPs
    echo ""
    log DEBUG "Container Network Interfaces:"
    ip -4 addr show | grep -E "inet |^[0-9]+:" | while IFS= read -r line; do
        echo -e "           ${GRAY}│${NC} $line"
    done

    # VPN status
    echo ""
    local vpn_iface=$(get_vpn_interface)
    if [ -n "$vpn_iface" ]; then
        local vpn_ip=$(get_vpn_ip)
        log INFO "VPN Status: ${GREEN}CONNECTED${NC}"
        log DEBUG "  Interface: $vpn_iface"
        log DEBUG "  VPN IP: $vpn_ip"
    else
        log WARN "VPN Status: ${RED}NOT CONNECTED${NC}"
    fi

    # Container IP on rego-tunnel network
    local container_ip=$(get_container_ip)
    if [ -n "$container_ip" ]; then
        log DEBUG "Container IP: $container_ip"
    fi

    # Default gateway
    echo ""
    log DEBUG "Default gateway:"
    ip route show default | while IFS= read -r line; do
        echo -e "           ${GRAY}│${NC} $line"
    done

    echo ""
}

# Main menu
main_menu() {
    echo -e "${GREEN}Options:${NC}"
    echo -e "  ${CYAN}1${NC} - Start Cisco AnyConnect (kill existing + launch)"
    echo -e "  ${CYAN}2${NC} - Copy credentials to clipboard (one by one)"
    echo -e "  ${CYAN}3${NC} - Show live TOTP"
    echo -e "  ${CYAN}4${NC} - Setup IP forwarding rules only"
    echo -e "  ${CYAN}5${NC} - Test connection to $TARGET_IP"
    echo -e "  ${CYAN}6${NC} - Show network status"
    echo -e "  ${CYAN}7${NC} - Kill all Cisco processes"
    echo -e "  ${CYAN}8${NC} - Show routing table"
    echo -e "  ${CYAN}9${NC} - Show /etc/hosts"
    echo -e "  ${CYAN}e${NC} - Edit /etc/hosts"
    echo -e "  ${CYAN}q${NC} - Quit"
    echo ""
}

# Check if VPN is already connected
check_vpn_status() {
    local vpn_iface=$(get_vpn_interface)
    if [ -n "$vpn_iface" ]; then
        local vpn_ip=$(get_vpn_ip)
        log INFO "VPN is ${GREEN}CONNECTED${NC}"
        log DEBUG "  Interface: $vpn_iface"
        log DEBUG "  VPN IP: $vpn_ip"
        return 0
    else
        log WARN "VPN is ${RED}NOT CONNECTED${NC}"
        return 1
    fi
}

# Focus on Cisco AnyConnect window
focus_vpn_window() {
    local win_id=$(xdotool search --name "Cisco" 2>/dev/null | head -1)
    if [ -n "$win_id" ]; then
        xdotool windowactivate --sync "$win_id" 2>/dev/null
        sleep 0.3
        return 0
    fi
    return 1
}

# Auto-login sequence using xdotool (no auto-focus, types to active window)
auto_login() {
    log INFO "Starting automated login sequence..."

    # Wait for UI to fully load
    log DEBUG "Waiting 5s for UI to load..."
    sleep 5

    # Press Enter to initiate connection
    log DEBUG "Pressing Enter to start connection..."
    xdotool key Return
    sleep 5

    # Type email
    log DEBUG "Typing email..."
    xdotool type --delay 50 "$EMAIL"
    xdotool key Return
    sleep 5

    # Type password
    log DEBUG "Typing password..."
    xdotool type --delay 50 "$PASSWORD"
    xdotool key Return
    sleep 5

    # Type TOTP
    log DEBUG "Typing TOTP..."
    local totp=$(oathtool --totp -b "$TOTP_SECRET")
    log DEBUG "TOTP: $totp"
    xdotool type --delay 50 "$totp"
    xdotool key Return
    sleep 5

    # Extra enters for any confirmation dialogs
    log DEBUG "Sending confirmation enters..."
    xdotool key Return
    sleep 2
    xdotool key Return
    sleep 5
    xdotool key Return

    log INFO "Auto-login sequence completed"
}

# Watchdog - monitors VPN and reconnects if dropped
start_watchdog() {
    log INFO "Starting VPN watchdog (check every 60s, keepalive ping every 5min)..."

    local check_interval=60
    local keepalive_interval=300
    local last_keepalive=0
    local reconnect_attempts=0
    local max_reconnect_attempts=3

    while true; do
        sleep $check_interval

        local now=$(date +%s)
        local vpn_iface=$(get_vpn_interface)

        if [ -n "$vpn_iface" ]; then
            # VPN is up
            reconnect_attempts=0

            # Keepalive ping every 5 minutes to prevent idle timeout
            if [ $((now - last_keepalive)) -ge $keepalive_interval ]; then
                if ping -c 1 -W 5 "$TARGET_IP" &>/dev/null; then
                    log DEBUG "Keepalive ping to $TARGET_IP successful"
                else
                    log WARN "Keepalive ping to $TARGET_IP failed (VPN may be degraded)"
                fi
                last_keepalive=$now
            fi
        else
            # VPN is down
            ((reconnect_attempts++))
            log WARN "VPN disconnected! Reconnect attempt $reconnect_attempts/$max_reconnect_attempts..."

            if [ $reconnect_attempts -le $max_reconnect_attempts ]; then
                # Kill stale processes and restart
                kill_cisco_processes "true"
                sleep 2

                # Start vpnagentd
                if ! pgrep -x vpnagentd >/dev/null; then
                    /opt/cisco/secureclient/bin/vpnagentd &
                    sleep 5
                fi

                # Start vpnui
                export GDK_BACKEND=x11
                export WEBKIT_DISABLE_DMABUF_RENDERER=1
                /opt/cisco/secureclient/bin/vpnui &
                disown
                sleep 3

                # Run auto-login
                auto_login &

                # Wait for connection
                local wait_count=0
                while [ -z "$(get_vpn_interface)" ] && [ $wait_count -lt 120 ]; do
                    sleep 2
                    ((wait_count+=2))
                done

                if [ -n "$(get_vpn_interface)" ]; then
                    log INFO "VPN reconnected successfully!"
                    setup_forwarding
                    reconnect_attempts=0
                else
                    log ERROR "Reconnect attempt $reconnect_attempts failed"
                fi
            else
                log ERROR "Max reconnect attempts reached. Manual intervention required."
                log ERROR "Use menu option 1 to restart VPN manually."
                # Reset counter after a longer wait
                sleep 300
                reconnect_attempts=0
            fi
        fi
    done
}

# Start Cisco AnyConnect with logging
start_anyconnect() {
    local do_auto_login="$1"
    log INFO "=== Starting Cisco AnyConnect VPN ==="
    echo ""

    # Kill existing processes first
    # Always restart vpnagentd for a clean session
    kill_cisco_processes "true"

    # Start vpnagentd if not running
    if ! pgrep -x vpnagentd >/dev/null; then
        log INFO "Starting vpnagentd..."
        /opt/cisco/secureclient/bin/vpnagentd &
        log DEBUG "Waiting for vpnagentd to initialize..."
        sleep 5
    fi

    # Show credentials
    log INFO "Credentials for SSO login:"
    echo -e "           ${CYAN}Email:    $EMAIL${NC}"
    echo -e "           ${CYAN}Password: $PASSWORD${NC}"
    TOTP=$(get_totp)
    echo -e "           ${CYAN}TOTP:     $TOTP${NC}"
    echo ""

    # Start AnyConnect with GPU/WebKit workarounds
    log INFO "Launching Cisco AnyConnect UI..."
    export GDK_BACKEND=x11
    export WEBKIT_DISABLE_DMABUF_RENDERER=1
    /opt/cisco/secureclient/bin/vpnui &
    VPNUI_PID=$!
    disown $VPNUI_PID
    log DEBUG "vpnui started with PID $VPNUI_PID"

    if [ "$do_auto_login" = "true" ]; then
        # Run auto-login in background
        auto_login &
        AUTO_LOGIN_PID=$!
        log DEBUG "Auto-login started with PID $AUTO_LOGIN_PID"
    else
        log INFO "Manual login mode - use keyboard shortcuts or menu option 2 for credentials"
        return 0
    fi

    # Wait for VPN to connect
    log INFO "Waiting for VPN connection..."
    local wait_count=0
    local max_wait=300  # 5 minutes
    while [ -z "$(get_vpn_interface)" ]; do
        sleep 2
        ((wait_count+=2))
        if [ $((wait_count % 10)) -eq 0 ]; then
            log DEBUG "Still waiting for VPN... (${wait_count}s)"
        fi
        if [ $wait_count -ge $max_wait ]; then
            log ERROR "Timeout waiting for VPN connection after ${max_wait}s"
            stop_xbindkeys
            return 1
        fi
    done

    log INFO "VPN connected!"
    local vpn_iface=$(get_vpn_interface)
    local vpn_ip=$(get_vpn_ip)
    log DEBUG "  Interface: $vpn_iface"
    log DEBUG "  VPN IP: $vpn_ip"

    # Wait a bit for routes to stabilize
    log DEBUG "Waiting for routes to stabilize..."
    sleep 3

    # Setup forwarding
    setup_forwarding

    # Test connection
    log INFO "Testing connection to $TARGET_IP..."
    if ping -c 2 -W 3 "$TARGET_IP" &>/dev/null; then
        log INFO "Connection test: ${GREEN}SUCCESS${NC}"
    else
        log WARN "Connection test: ${RED}FAILED${NC} (may need manual route on Windows)"
    fi

    log INFO "VPN setup complete"

    # Disable screen blanking/power saving
    xset s off 2>/dev/null || true
    xset -dpms 2>/dev/null || true
    xset s noblank 2>/dev/null || true
    log DEBUG "Screen blanking disabled"

    # Start watchdog in background
    start_watchdog &
    WATCHDOG_PID=$!
    log DEBUG "Watchdog started with PID $WATCHDOG_PID"
    return 0
}

# Parse command line arguments
parse_args() {
    while [[ $# -gt 0 ]]; do
        case $1 in
            -c|--connect)
                DO_CONNECT=true
                shift
                ;;
            -d|--disconnect)
                DO_DISCONNECT=true
                shift
                ;;
            -m|--menu)
                SKIP_AUTO_LOGIN=true
                shift
                ;;
            -r|--routes)
                show_routes
                exit 0
                ;;
            -h|--hosts)
                show_hosts
                exit 0
                ;;
            -s|--status)
                echo -e "${CYAN}========================================${NC}"
                echo -e "${CYAN}       VPN and Network Status           ${NC}"
                echo -e "${CYAN}========================================${NC}"
                echo ""
                check_vpn_status
                echo ""
                show_network_status
                exit 0
                ;;
            --help)
                show_help
                exit 0
                ;;
            *)
                echo "Unknown option: $1"
                echo "Use --help for usage information"
                exit 1
                ;;
        esac
    done

    if [ "$DO_CONNECT" = "true" ] && [ "$DO_DISCONNECT" = "true" ]; then
        echo "Error: --connect and --disconnect are mutually exclusive"
        exit 1
    fi
}

# Main
parse_args "$@"

# Cleanup old logs and start fresh
cleanup_old_logs

# Log script start
echo "" >> "$(get_log_file)"
echo "========================================" >> "$(get_log_file)"
log INFO "cisco-vpn script started"
log DEBUG "VPN_EMAIL=$EMAIL"
log DEBUG "VPN_HOST=$VPN_HOST"
log DEBUG "TARGET_IP=$TARGET_IP"
log DEBUG "TOTP_SECRET is $([ -n "$TOTP_SECRET" ] && echo 'set' || echo 'NOT SET')"

print_banner

if [ "$DO_DISCONNECT" = "true" ]; then
    disconnect_vpn
    exit $?
fi

if [ "$DO_CONNECT" = "true" ]; then
    echo -e "${CYAN}========================================${NC}"
    echo -e "${CYAN}       Dover VPN Connection Script      ${NC}"
    echo -e "${CYAN}========================================${NC}"
    echo ""
    if [ "$SKIP_AUTO_LOGIN" = "true" ]; then
        start_anyconnect "false"
    else
        start_anyconnect "true"
    fi
    exit $?
fi

log INFO "Script started"
echo ""

# If -m/--menu flag, skip everything and go straight to menu
if [ "$SKIP_AUTO_LOGIN" = "true" ]; then
    log INFO "Menu mode - skipping auto-login"
# Check current status
elif check_vpn_status; then
    echo ""
    log INFO "VPN already connected. Setting up forwarding..."
    setup_forwarding
else
    echo ""
    log INFO "Auto-starting VPN connection..."
    echo ""
    start_anyconnect "true"
fi

while true; do
    echo ""
    main_menu
    echo -ne "${CYAN}Choice: ${NC}"
    read -r choice
    echo ""

    # Ignore empty/whitespace input
    [[ -z "${choice// }" ]] && continue

    case $choice in
        1) if [ "$SKIP_AUTO_LOGIN" = "true" ]; then
                start_anyconnect "false"
            else
                start_anyconnect "true"
            fi ;;
        2) copy_to_clipboard ;;
        3) show_totp ;;
        4) setup_forwarding ;;
        5) log INFO "Testing connection to $TARGET_IP..."
           ping -c 3 "$TARGET_IP" && log INFO "Connection test: ${GREEN}SUCCESS${NC}" || log ERROR "Connection test: ${RED}FAILED${NC}" ;;
        6) show_network_status ;;
        7) kill_cisco_processes "true";;
        8) show_routes ;;
        9) show_hosts ;;
        e|E) edit_hosts ;;
        q|Q) log INFO "Goodbye!"; exit 0 ;;
        *) ;; # Ignore invalid input silently
    esac
done
