#!/usr/bin/env bash
# In-sandbox e2e entry point. The sandbox has no browsers and no host access, so
# the dev-server + browser pair is handed to the host receiver over a
# forced-command ssh channel that can invoke nothing else.
set -euo pipefail

KEY_FILE="${SANDBOX_E2E_KEY:-/sandbox-secrets/e2e_key}"
KNOWN_HOSTS="${SANDBOX_E2E_KNOWN_HOSTS:-/sandbox-secrets/e2e_known_hosts}"
TARGET="${SANDBOX_E2E_TARGET:-}"
SANDBOX_ID="${SANDBOX_ID:-}"
WORKSPACES_ROOT="${SANDBOX_WORKSPACES_ROOT:-/sandbox/workspaces}"
ENCODER="/usr/local/lib/overdeck-sandbox/encode-payload.mjs"

usage() {
  cat >&2 <<'USAGE'
usage: e2e-remote [--server <shell-cmd> --wait-port <port>] [options] -- <client argv...>

  --server <cmd>     shell command that starts the server (runs beside the browser)
  --wait-port <n>    TCP port on 127.0.0.1 the server must listen on
  --wait-sec <n>     how long to wait for the port (default 240, max 3600)
  --env K=V          environment for BOTH server and client (repeatable)
  --mkdir <dir>      workspace-relative dir created before the run (repeatable)

Runs from inside the agent sandbox. Host selection is the receiver's decision and
cannot be set here. Artifacts must be written inside the workspace.
USAGE
  exit "${1:-2}"
}

SERVER_CMD=""
WAIT_PORT=""
WAIT_SEC=240
ENV_ARGS=()
MKDIRS=()
CLIENT=()

while [ $# -gt 0 ]; do
  case "$1" in
    --server)    SERVER_CMD="${2-}"; shift 2 ;;
    --wait-port) WAIT_PORT="${2-}"; shift 2 ;;
    --wait-sec)  WAIT_SEC="${2-}"; shift 2 ;;
    --env)       ENV_ARGS+=("${2-}"); shift 2 ;;
    --mkdir)     MKDIRS+=("${2-}"); shift 2 ;;
    --hosts)     echo "e2e-remote: --hosts is not available inside the sandbox; the receiver resolves the host from the buildbox registry" >&2; exit 2 ;;
    --)          shift; CLIENT=("$@"); break ;;
    -h|--help)   usage 0 ;;
    *)           echo "e2e-remote: unknown arg: $1" >&2; usage ;;
  esac
done

[ "${#CLIENT[@]}" -gt 0 ] || { echo "e2e-remote: missing client command after --" >&2; usage; }
[ -n "$TARGET" ] || { echo "e2e-remote: SANDBOX_E2E_TARGET unset — sandbox was not started with the e2e channel" >&2; exit 2; }
[ -n "$SANDBOX_ID" ] || { echo "e2e-remote: SANDBOX_ID unset" >&2; exit 2; }
[ -r "$KEY_FILE" ] || { echo "e2e-remote: e2e key not readable at $KEY_FILE" >&2; exit 2; }
[ -r "$KNOWN_HOSTS" ] || { echo "e2e-remote: known_hosts not readable at $KNOWN_HOSTS" >&2; exit 2; }
case "$WAIT_SEC" in ''|*[!0-9]*) echo "e2e-remote: --wait-sec must be numeric" >&2; exit 2 ;; esac
case "${WAIT_PORT:-0}" in *[!0-9]*) echo "e2e-remote: --wait-port must be numeric" >&2; exit 2 ;; esac

case "$PWD" in
  "$WORKSPACES_ROOT"/*) WORKSPACE_REL="${PWD#"$WORKSPACES_ROOT"/}" ;;
  *) echo "e2e-remote: run from inside $WORKSPACES_ROOT (cwd=$PWD)" >&2; exit 2 ;;
esac

json_array() { jq -n '$ARGS.positional' --args "$@"; }

PAYLOAD_JSON="$(jq -n \
  --arg id "$SANDBOX_ID" \
  --arg ws "$WORKSPACE_REL" \
  --arg server "$SERVER_CMD" \
  --argjson port "${WAIT_PORT:-null}" \
  --argjson waitSec "$WAIT_SEC" \
  --argjson envPairs "$(json_array ${ENV_ARGS[@]+"${ENV_ARGS[@]}"})" \
  --argjson mkdirs "$(json_array ${MKDIRS[@]+"${MKDIRS[@]}"})" \
  --argjson client "$(json_array "${CLIENT[@]}")" \
  '{v:1,sandboxId:$id,workspace:$ws,server:$server,waitPort:$port,waitSec:$waitSec,envPairs:$envPairs,mkdirs:$mkdirs,client:$client}')"

PAYLOAD_B64="$(printf '%s' "$PAYLOAD_JSON" | node "$ENCODER")"

exec ssh -T -F /dev/null \
  -p "${SANDBOX_E2E_PORT:-22}" \
  -o BatchMode=yes \
  -o StrictHostKeyChecking=yes \
  -o UserKnownHostsFile="$KNOWN_HOSTS" \
  -o IdentitiesOnly=yes \
  -i "$KEY_FILE" \
  "$TARGET" "$PAYLOAD_B64"
