#!/usr/bin/env bash
# Test gradio on this host. Intended to be run ON the offline RHEL 9.6 target.
#
#   scripts/run-tests.sh                    # both interpreters, everything
#   scripts/run-tests.sh 3.12               # one interpreter
#   scripts/run-tests.sh 3.12 --quick       # fewer performance repetitions
#   scripts/run-tests.sh both --no-perf     # functional checks only
#   scripts/run-tests.sh 3.9 --suites functional
#
# Creates the venv if it is missing (offline, from the bundled wheels), sources
# gradio-offline.env, then runs tests/run_tests.py inside each venv. Reports go
# to results/.
#
# Exit status: 0 if every test passed, 1 if any failed. Warnings do not fail the
# run; they flag known gradio limitations.
set -uo pipefail

BUNDLE="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
cd "$BUNDLE"

WANT="both"; QUICK=""; SUITES="all"; KEEP=0
args=()
for a in "$@"; do args+=("$a"); done
i=0
while [[ $i -lt ${#args[@]} ]]; do
  case "${args[$i]}" in
    3.9|39)     WANT=3.9 ;;
    3.12|312)   WANT=3.12 ;;
    both|all)   WANT=both ;;
    --quick)    QUICK="--quick" ;;
    --no-perf)  SUITES="environment,install,functional,offline" ;;
    --suites)   i=$((i+1)); SUITES="${args[$i]:-all}" ;;
    --keep-venv) KEEP=1 ;;
    -h|--help)  sed -n '2,17p' "${BASH_SOURCE[0]}" | sed 's/^# \{0,1\}//'; exit 0 ;;
    *) echo "unknown argument: ${args[$i]}" >&2; exit 2 ;;
  esac
  i=$((i+1))
done

STAMP="$(date +%Y%m%d-%H%M%S)"
OUT="$BUNDLE/results"
mkdir -p "$OUT"

# Offline environment for every app the tests start.
set -a; . "$BUNDLE/gradio-offline.env"; set +a
# The harness allocates its own ports; leave GRADIO_SERVER_PORT unset so a
# stale value cannot collide with them.
unset GRADIO_SERVER_PORT

overall=0
declare -a SUMMARY

run_one() {
  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"
  echo "##############################################################"

  if ! command -v "$pybin" >/dev/null 2>&1; then
    echo "   $pybin is not installed on this host; skipping."
    echo "   (see docs/PREREQUISITES.md)"
    SUMMARY+=("$(printf '  python %-5s SKIPPED  interpreter not installed' "$ver")")
    return 0
  fi

  local venv="$BUNDLE/venv-$tag"
  if [[ ! -x "$venv/bin/python" ]]; then
    echo "-- creating $venv from the bundled wheels (offline)"
    if ! ./scripts/install-gradio.sh "$ver" "$venv" > "$OUT/install-$tag-$STAMP.log" 2>&1; then
      echo "   INSTALL FAILED; see results/install-$tag-$STAMP.log"
      tail -15 "$OUT/install-$tag-$STAMP.log" | sed 's/^/     /'
      SUMMARY+=("$(printf '  python %-5s FAILED   offline install' "$ver")")
      overall=1
      return 1
    fi
    echo "   installed"
  else
    echo "-- using existing $venv"
  fi

  local report="$OUT/report-$tag-$STAMP.md"
  local json="$OUT/results-$tag-$STAMP.json"
  "$venv/bin/python" tests/run_tests.py \
      --suites "$SUITES" $QUICK --report "$report" --json "$json"
  local rc=$?

  # Pull the counts back out of the JSON for the combined summary.
  local line
  line="$("$venv/bin/python" - "$json" <<'PY'
import json, sys
try:
    d = json.load(open(sys.argv[1]))
    print("%d passed, %d failed, %d warned, %d skipped  (gradio %s)"
          % (d["passed"], d["failed"], d.get("warned", 0), d["skipped"], d["gradio"]))
except Exception as exc:
    print("no results (%s)" % exc)
PY
)"
  SUMMARY+=("$(printf '  python %-5s %s' "$ver" "$line")")
  [[ $rc -ne 0 ]] && overall=1
  return 0
}

[[ "$WANT" == both || "$WANT" == 3.9  ]] && run_one 3.9
[[ "$WANT" == both || "$WANT" == 3.12 ]] && run_one 3.12

echo
echo "=============================================================="
echo "  combined result"
echo "=============================================================="
for s in "${SUMMARY[@]}"; do echo "$s"; done
echo
echo "  reports: $OUT/report-*-$STAMP.md"
if [[ $overall == 0 ]]; then
  echo "  ALL TESTS PASSED"
else
  echo "  FAILURES PRESENT -- see the reports above"
fi
echo "=============================================================="

if [[ $KEEP == 0 ]]; then
  echo
  echo "(venvs kept at venv-py39 / venv-py312 for reuse; delete them to"
  echo " force a clean reinstall on the next run)"
fi
exit $overall
