#!/usr/bin/env bash
# ============================================================================
# OpenFUT — FIFA 17 offline FUT backend orchestrator
#
#   ./openfut-fut.sh start     bring up the whole harness (arm host + all servers)
#   ./openfut-fut.sh stop      shut the servers down
#   ./openfut-fut.sh restart   stop + start
#   ./openfut-fut.sh status    show what's up
#
# After `start`, launch FIFA 17 and select Ultimate Team. See RUNBOOK below (status).
# Volatile host state (sysctls/iptables/cert) does NOT survive a reboot; `start`
# re-arms everything, so just re-run it after booting. /etc/hosts persists.
# ============================================================================
set -uo pipefail
cd "$(dirname "$(readlink -f "$0")")"           # tools/

CERT=redir_cert.pem; KEY=redir_key.pem
# name  script                     "port[,port...]"   extra-env
SERVERS=(
  "lsx      lsx_responder_v2.py    4216               OPENFUT_LSX_EVENT_COUNT=100000"
  "blaze    blaze_responder_v3b.py 42127,42130,42131  -"
  "roster   roster_server.py       8081               -"
  "utas     utas_server.py         8099               -"
  "autopatch autopatch.py          -                  -"
  # POW/EASFC — the "EA FC servers unreachable" layer. Harmless when idle: it just
  # binds 8094/8080 and nothing points at it unless FUT_POW=1 makes blaze serve the
  # FIFA_POW_URL redirect keys. See pow_server.py for the powdll evidence.
  "pow      pow_server.py          8094,8080          -"
)

c()  { printf '  %s\n' "$*"; }
up() { ss -tlnp 2>/dev/null | grep -q ":$1 "; }

ensure_cert() {
  [ -s "$CERT" ] && [ -s "$KEY" ] && return 0
  echo "[*] generating self-signed TLS cert (redirector MITM; ProtoSSL verify is patched)"
  openssl req -x509 -newkey rsa:2048 -nodes -keyout "$KEY" -out "$CERT" -days 3650 \
    -subj "/CN=winter15.gosredirector.ea.com" \
    -addext "subjectAltName=DNS:winter15.gosredirector.ea.com,DNS:*.gosredirector.ea.com,DNS:*.ea.com,IP:127.0.0.1" \
    >/dev/null 2>&1
}

armed() {
  [ "$(cat /proc/sys/kernel/yama/ptrace_scope 2>/dev/null)" = 0 ] \
    && [ "$(cat /proc/sys/net/ipv4/conf/lo/route_localnet 2>/dev/null)" = 1 ] \
    && grep -q '[[:space:]]easw\.easports\.com\b' /etc/hosts 2>/dev/null
}

ensure_armed() {
  if armed; then c "host already armed (ptrace_scope=0, route_localnet=1, /etc/hosts ok)"; return 0; fi
  echo "[*] arming host state (needs root — a password dialog will appear)"
  pkexec sh "$PWD/root_arm.sh" || { echo "!! root_arm failed. Run manually:  pkexec sh $PWD/root_arm.sh"; return 1; }
}

start() {
  ensure_cert
  ensure_armed || exit 1
  echo "[*] starting servers (detached)…"
  for s in "${SERVERS[@]}"; do
    read -r name script ports env <<<"$s"
    pkill -9 -f "$script" 2>/dev/null; :
  done
  sleep 1
  for s in "${SERVERS[@]}"; do
    read -r name script ports env <<<"$s"
    local envprefix=""; [ "$env" != "-" ] && envprefix="env $env"
    : > "/tmp/${name}.log" 2>/dev/null || true
    setsid bash -c "exec $envprefix python3 -u $script" </dev/null >"/tmp/${name}.log" 2>&1 &
    disown
  done
  sleep 2
  status
}

stop() {
  echo "[*] stopping servers…"
  for s in "${SERVERS[@]}"; do read -r name script _ <<<"$s"; pkill -9 -f "$script" 2>/dev/null; :; done
  sleep 1; c "servers stopped (host arm + /etc/hosts left intact)"
}

status() {
  echo "== OpenFUT FIFA17 FUT backend =="
  armed && c "host: ARMED ✓" || c "host: NOT armed (run: pkexec sh $PWD/root_arm.sh)"
  for s in "${SERVERS[@]}"; do
    read -r name script ports env <<<"$s"
    if pgrep -f "$script" >/dev/null; then
      if [ "$ports" = "-" ]; then c "$name  ✓ (running)"
      else
        local ok=1; IFS=',' read -ra ps <<<"$ports"
        for p in "${ps[@]}"; do up "$p" || ok=0; done
        [ $ok = 1 ] && c "$name  ✓ ($ports)" || c "$name  ⚠ running but a port is down ($ports)"
      fi
    else c "$name  ✗ DOWN"; fi
  done
  echo "-- RUNBOOK --"
  c "1. (this must be done BEFORE launching FIFA — servers bind the ports the game needs)"
  c "2. Launch FIFA 17 fresh:  ~/Desktop/launch-fifa17.sh   (a FRESH launch avoids the live-DB error)"
  c "3. In-game: select Ultimate Team.  At the 'security question', type ANY answer -> Continue -> OK."
  c "4. -> the FUT hub.  Logs: /tmp/{lsx,blaze,roster,utas,autopatch}.log"
}

case "${1:-status}" in
  start) start ;;
  stop) stop ;;
  restart) stop; start ;;
  status) status ;;
  *) echo "usage: $0 {start|stop|restart|status}"; exit 1 ;;
esac
