#!/usr/bin/env bash
# Is the FIFA client currently connected to anything?
#
#   client-state.sh [client-ip]
#
# WHY THIS EXISTS
#
# Host-side `ss` CANNOT see the Python backend's connections. The Python
# responders run inside a container, so a client session terminates at
# 172.20.0.2:42130 in the container's network namespace; the host only ever sees
# the NAT'd flow, and a plain `ss | grep <client>` on the host reports nothing.
#
# That produced a wrong precondition check: "no .105 Blaze session — closed" was
# reported while FIFA was mid-session on Python, and gate 9 was armed against a
# client that had never exited. Python's own log gave it away — it logs closes
# reliably (45 of them) and there was no close for that session.
#
# So this looks in BOTH namespaces, and reports the Rust sidecar and the Python
# container separately.
#
# Exit 0 when the client has no live session anywhere (safe to start a gate),
# 1 when it does.
set -uo pipefail

CLIENT="${1:-${OPENFUT_CLIENT_IP:-}}"
if [[ -z "$CLIENT" ]]; then
  echo "usage: client-state.sh <client-ip>   (or set OPENFUT_CLIENT_IP)" >&2
  echo "  no default: the lab's address is deployment config, not architecture," >&2
  echo "  and a default that matches the current lab hides the coupling." >&2
  exit 2
fi
CONTAINER="${OPENFUT_PY_CONTAINER:-openfut-fut-backend}"
live=0

decode_tcp() {
  # /proc/net/tcp rows -> "local remote state", little-endian hex addresses.
  python3 -c "
import sys
def d(x):
    ip, port = x.split(':')
    return '.'.join(str(int(ip[i:i+2], 16)) for i in (6, 4, 2, 0)) + ':' + str(int(port, 16))
for line in sys.stdin:
    f = line.split()
    if len(f) < 4 or not f[0].endswith(':'):
        continue
    try:
        print(d(f[1]), d(f[2]), f[3])
    except Exception:
        pass
"
}

echo "client: $CLIENT"

# ---- Rust sidecar (host namespace)
rust="$(ss -tn state established 2>/dev/null | grep -F "$CLIENT" | grep -E ':42230' || true)"
if [[ -n "$rust" ]]; then
  echo "  RUST sidecar : LIVE session(s)"
  sed 's/^/    /' <<<"$rust"
  live=1
else
  echo "  RUST sidecar : none"
fi

# ---- Python backend (container namespace)
if docker exec "$CONTAINER" true 2>/dev/null; then
  py="$(docker exec "$CONTAINER" cat /proc/net/tcp 2>/dev/null | decode_tcp \
        | awk '$3=="01"' | grep -F "$CLIENT" || true)"
  if [[ -n "$py" ]]; then
    echo "  PYTHON backend: LIVE session(s)"
    awk '{printf "    %-22s <- %-22s ESTABLISHED\n", $1, $2}' <<<"$py"
    live=1
  else
    echo "  PYTHON backend: none"
  fi
else
  echo "  PYTHON backend: container '$CONTAINER' not reachable — CANNOT confirm"
  live=1   # unknown is not the same as clear
fi

echo
if [[ $live -eq 0 ]]; then
  echo "RESULT: no live client session — safe to begin a gate"
else
  echo "RESULT: client still connected — close FIFA before starting a gate"
fi
exit $live
