#!/usr/bin/env bash
# ============================================================================
# OpenFUT FIFA-17 FUT backend — in-CONTAINER orchestrator.
#
# Runs the 5 network responders that the game dials. Unlike the host-based
# openfut-fut.sh, this does NO host arming (no pkexec / iptables / /etc/hosts /
# ptrace) — those are client-side concerns handled on the game machine (105).
# autopatch.py is NOT run here: it patches the FIFA17.exe process memory and must
# run on the box the game runs on.
#
# Address behaviour is driven by two env vars (see each responder):
#   OPENFUT_BIND       bind address for every listener   (container: 0.0.0.0)
#   OPENFUT_ADVERTISE  address handed to the client for the next hop
#                      (the server's LAN IP, e.g. 203.0.113.10)
# ============================================================================
set -uo pipefail
cd "$(dirname "$(readlink -f "$0")")/tools"

BIND="${OPENFUT_BIND:-0.0.0.0}"
ADV="${OPENFUT_ADVERTISE:?OPENFUT_ADVERTISE must be set to the server LAN IP (e.g. 203.0.113.10)}"
export OPENFUT_BIND="$BIND"
export OPENFUT_ADVERTISE="$ADV"
# POW keys advertised by blaze must also point at the server, not loopback.
export POW_HOST="${POW_HOST:-$ADV:8094}"
export POW_CONTENT_HOST="${POW_CONTENT_HOST:-$ADV:8080}"
export POW_ADDR="${POW_ADDR:-$BIND:8094}"
export POW_CONTENT_ADDR="${POW_CONTENT_ADDR:-$BIND:8080}"

echo "[openfut] bind=$BIND advertise=$ADV"

# name   script                  extra-env
declare -a SERVERS=(
  "lsx|lsx_responder_v2.py|OPENFUT_LSX_EVENT_COUNT=100000"
  "blaze|blaze_responder_v3b.py|-"
  "roster|roster_server.py|-"
  "utas|utas_server.py|FUT_TRADING=1 FUT_PILESIZES=1 FUT_TRADEABLE=1 FUT_DISCARD_TABLE=1 FUT_DISCARD_SEND=1"
  "pow|pow_server.py|-"
)

pids=()
names=()
for entry in "${SERVERS[@]}"; do
  IFS='|' read -r name script env <<<"$entry"
  envprefix=""; [ "$env" != "-" ] && envprefix="env $env"
  echo "[openfut] starting $name ($script)"
  # shellcheck disable=SC2086
  $envprefix python3 -u "$script" &
  pids+=($!)
  names+=("$name")
done

# Propagate SIGTERM/SIGINT to children so `docker stop` is clean.
term() {
  echo "[openfut] shutting down…"
  for p in "${pids[@]}"; do kill "$p" 2>/dev/null || true; done
  wait
  exit 0
}
trap term TERM INT

# If ANY responder dies, take the whole container down so the failure is visible
# (they all bind ports the game needs — a partial stack is a broken stack).
while true; do
  for i in "${!pids[@]}"; do
    if ! kill -0 "${pids[$i]}" 2>/dev/null; then
      echo "[openfut] responder ${names[$i]} (pid ${pids[$i]}) exited - bringing container down"
      term
    fi
  done
  sleep 2
done
