#!/usr/bin/env bash
# Prove the bundle works with no network: install from wheels only, then start
# every template and check it answers HTTP.
#
#   scripts/verify-offline.sh            # both Python sets
#   scripts/verify-offline.sh 3.12       # one set
#
# When run as root on a host with util-linux, each step runs inside an
# "unshare -n" namespace that has nothing but loopback, so any accidental
# outbound dependency shows up as a failure rather than passing silently.
set -uo pipefail

BUNDLE="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
WANT="${1:-all}"
PASS=0; FAIL=0; RESULTS=()

# --- pick a network-isolated runner ------------------------------------------
if [[ "$(id -u)" == "0" ]] && unshare -n true 2>/dev/null; then
  ISOLATED=1
  echo "== network isolation: unshare -n (loopback only)"
else
  ISOLATED=0
  echo "== network isolation: none available; relying on the host being offline"
fi

# run a command with only loopback available
iso() {
  if [[ $ISOLATED == 1 ]]; then
    unshare -n -- bash -c 'ip link set lo up 2>/dev/null; exec "$@"' _ "$@"
  else
    "$@"
  fi
}

record() {
  local status="$1" name="$2"
  if [[ "$status" == PASS ]]; then PASS=$((PASS+1)); else FAIL=$((FAIL+1)); fi
  RESULTS+=("$(printf '%-6s %s' "$status" "$name")")
  printf '   %-6s %s\n' "$status" "$name"
}

verify_set() {
  local ver="$1" tag pybin
  case "$ver" in
    3.9)  tag=py39;  pybin=python3.9  ;;
    3.12) tag=py312; pybin=python3.12 ;;
  esac

  echo
  echo "=============================================================="
  echo "  Python $ver  /  wheels/$tag"
  echo "=============================================================="

  if ! command -v "$pybin" >/dev/null 2>&1; then
    record SKIP "python $ver not installed on this host"
    return
  fi

  local venv; venv="$(mktemp -d)/venv-$tag"
  echo "-- installing into $venv (offline)"
  if iso bash "$BUNDLE/scripts/install-gradio.sh" "$ver" "$venv" >"$BUNDLE/logs/verify-install-$tag.log" 2>&1; then
    record PASS "py$ver offline install from bundled wheels"
  else
    record FAIL "py$ver offline install (see logs/verify-install-$tag.log)"
    tail -20 "$BUNDLE/logs/verify-install-$tag.log"
    return
  fi

  local gv
  gv="$("$venv/bin/python" -c 'import gradio;print(gradio.__version__)' 2>/dev/null)"
  echo "-- gradio $gv"

  # -- launch each template and check it serves ------------------------------
  local port=7870 t
  for t in "$BUNDLE"/templates/[0-9]*.py; do
    local name; name="$(basename "$t")"
    # 08 is a client, not a server: it needs a running app, tested separately.
    [[ "$name" == 08_* ]] && continue
    port=$((port+1))
    local log="$BUNDLE/logs/verify-$tag-$name.log"
    if iso env GRADIO_ANALYTICS_ENABLED=False HF_HUB_OFFLINE=1 DO_NOT_TRACK=1 \
           MPLBACKEND=Agg MPLCONFIGDIR="$(mktemp -d)" \
           GRADIO_SERVER_PORT="$port" \
           bash -c "cd '$BUNDLE/templates'
                    '$venv/bin/python' '$name' >'$log' 2>&1 &
                    for i in \$(seq 1 60); do
                      curl -sf -o /dev/null http://127.0.0.1:$port/ && ok=1 && break
                      sleep 1
                    done
                    code=\$(curl -s -o /dev/null -w '%{http_code}' http://127.0.0.1:$port/config)
                    kill %1 2>/dev/null
                    [[ \"\$code\" == 200 ]]"; then
      record PASS "py$ver  $name serves HTTP 200"
    else
      record FAIL "py$ver  $name (see $(basename "$log"))"
      tail -12 "$log" 2>/dev/null | sed 's/^/        /'
    fi
  done

  # -- gradio_client round trip against template 01 --------------------------
  port=$((port+1))
  local log="$BUNDLE/logs/verify-$tag-client.log"
  if iso env GRADIO_ANALYTICS_ENABLED=False HF_HUB_OFFLINE=1 \
         bash -c "cd '$BUNDLE/templates'
                  GRADIO_SERVER_PORT=$port '$venv/bin/python' 01_hello_interface.py >'$log' 2>&1 &
                  for i in \$(seq 1 60); do curl -sf -o /dev/null http://127.0.0.1:$port/ && break; sleep 1; done
                  '$venv/bin/python' 08_api_client.py http://127.0.0.1:$port/ >>'$log' 2>&1
                  rc=\$?
                  kill %1 2>/dev/null
                  grep -q 'Hello, RHEL!!!' '$log' && exit 0 || exit 1"; then
    record PASS "py$ver  08_api_client.py round trip"
  else
    record FAIL "py$ver  08_api_client.py round trip (see $(basename "$log"))"
    tail -12 "$log" 2>/dev/null | sed 's/^/        /'
  fi

  rm -rf "$(dirname "$venv")"
}

mkdir -p "$BUNDLE/logs"
[[ "$WANT" == all || "$WANT" == 3.9  ]] && verify_set 3.9
[[ "$WANT" == all || "$WANT" == 3.12 ]] && verify_set 3.12

echo
echo "=============================================================="
printf '  %d passed, %d failed\n' "$PASS" "$FAIL"
echo "=============================================================="
exit $(( FAIL > 0 ))
