#!/bin/bash
# ========================================================
#   SERVERS MONITOR - AI VPN & SOCKS5 ROTATOR (macOS / Linux)
# ========================================================

PORT=1080
DEFAULT_USER="root"
SERVERS=(
  "Nodo 1 (67.217.242.242)|67.217.242.242"
  "Nodo 2 (69.48.204.65)|69.48.204.65"
  "Nodo 3 (162.222.206.177)|162.222.206.177"
  "Nodo 4 (162.222.204.3)|162.222.204.3"
  "Nodo 5 (74.208.55.38)|74.208.55.38"
  "Nodo 6 (74.208.233.247)|74.208.233.247"
)

PID_FILE="/tmp/servers_vpn_ssh.pid"
ACTIVE_NODE_FILE="/tmp/servers_vpn_active.txt"

# Detect default network service on macOS (Wi-Fi, Ethernet, etc.)
get_macos_network_service() {
  if command -v networksetup >/dev/null 2>&1; then
    # Find active interface using default gateway route
    local default_iface=$(route -n get default 2>/dev/null | awk '/interface:/{print $2}')
    if [ -n "$default_iface" ]; then
      networksetup -listallhardwareports 2>/dev/null | awk -v iface="$default_iface" '
        $1=="Hardware" && $2=="Port:" {port=$3; for(i=4;i<=NF;i++) port=port" "$i}
        $1=="Device:" && $2==iface {print port; exit}
      '
    else
      echo "Wi-Fi"
    fi
  else
    echo ""
  fi
}

NET_SERVICE=$(get_macos_network_service)

set_macos_socks_proxy() {
  local enable="$1"
  if [ -n "$NET_SERVICE" ] && command -v networksetup >/dev/null 2>&1; then
    if [ "$enable" = "on" ]; then
      networksetup -setsocksfirewallproxy "$NET_SERVICE" 127.0.0.1 "$PORT" off 2>/dev/null
      networksetup -setsocksfirewallproxystate "$NET_SERVICE" on 2>/dev/null
      networksetup -setproxybypassdomains "$NET_SERVICE" "localhost" "127.0.0.1" "*.local" 2>/dev/null
      echo "  [macOS] Proxy SOCKS configurado en '$NET_SERVICE' -> 127.0.0.1:$PORT (Bypass: localhost, 127.0.0.1)"
    else
      networksetup -setsocksfirewallproxystate "$NET_SERVICE" off 2>/dev/null
      echo "  [macOS] Proxy SOCKS desactivado en '$NET_SERVICE'"
    fi
  fi
}

stop_vpn() {
  if [ -f "$PID_FILE" ]; then
    local pid=$(cat "$PID_FILE" 2>/dev/null)
    if [ -n "$pid" ] && kill -0 "$pid" 2>/dev/null; then
      kill "$pid" 2>/dev/null
      sleep 0.5
      kill -9 "$pid" 2>/dev/null
    fi
    rm -f "$PID_FILE"
  fi
  
  # Also kill any leftover ssh port 1080 forwarding
  pkill -f "ssh.*-D $PORT" 2>/dev/null

  set_macos_socks_proxy "off"
  rm -f "$ACTIVE_NODE_FILE"
  echo "  [OK] VPN Desconectada. Navegacion directa restaurada."
}

start_vpn() {
  local server_name="$1"
  local server_ip="$2"

  stop_vpn

  echo "  Conectando tunel SOCKS5 a $server_name ($server_ip)..."
  ssh -D "$PORT" -N -q -o BatchMode=yes -o StrictHostKeyChecking=no -o ConnectTimeout=8 "$DEFAULT_USER@$server_ip" &
  local new_pid=$!
  echo "$new_pid" > "$PID_FILE"
  echo "$server_name ($server_ip)" > "$ACTIVE_NODE_FILE"

  sleep 1.5

  if ! kill -0 "$new_pid" 2>/dev/null; then
    echo "  [ERROR] No se pudo levantar el tunel SSH con $server_ip."
    rm -f "$PID_FILE" "$ACTIVE_NODE_FILE"
    return 1
  fi

  set_macos_socks_proxy "on"

  echo "  [OK] VPN ACTIVA en 127.0.0.1:$PORT -> Salida: $server_ip"
  
  # Check external IP test
  if command -v curl >/dev/null 2>&1; then
    local out_ip=$(curl --socks5-hostname 127.0.0.1:$PORT -s --max-time 4 https://api.ipify.org 2>/dev/null)
    if [ -n "$out_ip" ]; then
      echo "  [IP Publica Confirmada]: $out_ip"
    fi
  fi
}

launch_opencode_gui() {
  if [ ! -f "$PID_FILE" ]; then
    echo "  Iniciando VPN primero con Nodo 1..."
    start_vpn "Nodo 1 (67.217.242.242)" "67.217.242.242"
  fi

  echo "  Lanzando OpenCode Desktop con variables de entorno..."
  export HTTPS_PROXY="socks5://127.0.0.1:$PORT"
  export HTTP_PROXY="socks5://127.0.0.1:$PORT"
  export NO_PROXY="localhost,127.0.0.1,::1"

  if [ -d "/Applications/OpenCode.app" ]; then
    open -a "/Applications/OpenCode.app"
  elif command -v opencode >/dev/null 2>&1; then
    opencode &
  else
    echo "  OpenCode no se encontro en /Applications/OpenCode.app ni en PATH."
  fi
}

launch_opencode_cli() {
  if [ ! -f "$PID_FILE" ]; then
    echo "  Iniciando VPN primero con Nodo 1..."
    start_vpn "Nodo 1 (67.217.242.242)" "67.217.242.242"
  fi

  echo "  Lanzando terminal con OpenCode CLI enrutado por SOCKS5..."
  export HTTPS_PROXY="socks5://127.0.0.1:$PORT"
  export HTTP_PROXY="socks5://127.0.0.1:$PORT"
  export NO_PROXY="localhost,127.0.0.1,::1"
  if command -v opencode >/dev/null 2>&1; then
    opencode
  else
    echo "  El comando 'opencode' no esta en tu PATH. Instalar con: npm i -g opencode-ai"
  fi
}

launch_opencode_web() {
  if [ ! -f "$PID_FILE" ]; then
    echo "  Iniciando VPN primero con Nodo 1..."
    start_vpn "Nodo 1 (67.217.242.242)" "67.217.242.242"
  fi

  echo "  Iniciando servidor 'opencode web'..."
  export HTTPS_PROXY="socks5://127.0.0.1:$PORT"
  export HTTP_PROXY="socks5://127.0.0.1:$PORT"
  export NO_PROXY="localhost,127.0.0.1,::1"
  opencode web
}

show_status() {
  if [ -f "$PID_FILE" ] && kill -0 "$(cat "$PID_FILE" 2>/dev/null)" 2>/dev/null; then
    local active_desc=$(cat "$ACTIVE_NODE_FILE" 2>/dev/null)
    echo "  Estado: CONECTADO [VERDE]"
    echo "  Nodo Activo: $active_desc"
    echo "  Puerto local: 127.0.0.1:$PORT"
  else
    echo "  Estado: DESCONECTADO (Conexion directa)"
  fi
}

# Trap exit
trap stop_vpn INT TERM

while true; do
  clear
  echo "========================================================"
  echo "       SERVERS MONITOR - AI VPN HUB (macOS / Linux)"
  echo "========================================================"
  show_status
  echo "========================================================"
  echo "  [1] Activar VPN con Nodo 1 (67.217.242.242)"
  echo "  [2] Cambiar de Servidor / Rotar IP"
  echo "  [3] Desconectar VPN"
  echo "  ------------------------------------------------------"
  echo "  [4] Lanzar OpenCode Desktop (GUI)"
  echo "  [5] Lanzar OpenCode Web GUI"
  echo "  [6] Lanzar OpenCode CLI"
  echo "  ------------------------------------------------------"
  echo "  [7] Abrir Monitor Web (https://servers.reneworks.mx/)"
  echo "  [0] Salir"
  echo "========================================================"
  read -p "  Selecciona una opcion: " opt

  case "$opt" in
    1)
      start_vpn "Nodo 1 (67.217.242.242)" "67.217.242.242"
      read -p "  Presiona [Enter] para continuar..."
      ;;
    2)
      echo ""
      echo "  Selecciona el servidor destino:"
      idx=1
      for s in "${SERVERS[@]}"; do
        sname="${s%%|*}"
        echo "    [$idx] $sname"
        idx=$((idx + 1))
      done
      read -p "    Numero de servidor: " snum
      if [ "$snum" -ge 1 ] && [ "$snum" -le "${#SERVERS[@]}" ]; then
        chosen="${SERVERS[$((snum - 1))]}"
        chosen_name="${chosen%%|*}"
        chosen_ip="${chosen##*|}"
        start_vpn "$chosen_name" "$chosen_ip"
      else
        echo "    Opcion invalida."
      fi
      read -p "  Presiona [Enter] para continuar..."
      ;;
    3)
      stop_vpn
      read -p "  Presiona [Enter] para continuar..."
      ;;
    4)
      launch_opencode_gui
      read -p "  Presiona [Enter] para continuar..."
      ;;
    5)
      launch_opencode_web
      read -p "  Presiona [Enter] para continuar..."
      ;;
    6)
      launch_opencode_cli
      read -p "  Presiona [Enter] para continuar..."
      ;;
    7)
      if command -v open >/dev/null 2>&1; then
        open "https://servers.reneworks.mx/"
      elif command -v xdg-open >/dev/null 2>&1; then
        xdg-open "https://servers.reneworks.mx/"
      fi
      ;;
    0)
      stop_vpn
      echo "  Saliendo..."
      exit 0
      ;;
    *)
      echo "  Opcion invalida."
      sleep 1
      ;;
  esac
done
