#!/bin/bash
# The one way to start the box's browser (adapted from XBot's box/box-chrome): the same profile
# and DevTools port every time, so AnyBot's browser tools and the person in the viewer use the
# same window and logins; web pages exposed to accessibility, so their links and buttons get
# numbers on the bot's picture. A second start only hands its address to the running one.
set -euo pipefail
export DISPLAY="${DISPLAY:-:1}" HOME=/home/bot
export GTK_MODULES=atk-bridge GTK_A11Y=atspi GNOME_ACCESSIBILITY=1 NO_AT_BRIDGE=0
if [[ -z "${DBUS_SESSION_BUS_ADDRESS:-}" && -r /tmp/anybot-dbus.env ]]; then
  # shellcheck disable=SC1091
  source /tmp/anybot-dbus.env
  export DBUS_SESSION_BUS_ADDRESS
fi
# One profile. The box used to have two: Chromium's own (~/.config/chromium, what its menu entry
# opened, where a person logged in by hand) and AnyBot's (~/.config/anybot-browser, what the
# browser tools opened), so a site could be logged in in one and not the other. Chromium's own
# is the one now (the other stays as it was); a box that only has AnyBot's keeps that.
PROFILE=/home/bot/.config/anybot-profile
if [[ ! -e "$PROFILE" ]]; then
  if [[ -d /home/bot/.config/chromium/Default || ! -d /home/bot/.config/anybot-browser/Default ]]; then
    mkdir -p /home/bot/.config/chromium && ln -s /home/bot/.config/chromium "$PROFILE"
  else
    ln -s /home/bot/.config/anybot-browser "$PROFILE"
  fi
fi
# The box (a container) is the sandbox by default, so Chromium runs --no-sandbox. Under gVisor
# (容器隔離=runsc) the box has a virtualized kernel of its own and AnyBot starts it with
# ANYBOT_BOX_SANDBOX=1 — Chromium's own sandbox works there, so keep it as a second wall.
SANDBOX=(--no-sandbox --test-type)
[ "${ANYBOT_BOX_SANDBOX:-0}" = 1 ] && SANDBOX=()
FLAGS=("${SANDBOX[@]}" --user-data-dir="$PROFILE" --remote-debugging-address=127.0.0.1 --remote-debugging-port=9222
  --remote-allow-origins=* --force-renderer-accessibility --disable-blink-features=AutomationControlled
  --disable-dev-shm-usage --disable-gpu --use-angle=swiftshader --enable-unsafe-swiftshader --password-store=basic
  --no-first-run --no-default-browser-check --disable-session-crashed-bubble --hide-crash-restore-bubble
  --disable-features=TranslateUI --start-maximized)
# Two starts in the same second (the bot and the person) would both find no browser and fight
# over the profile ("in use"): one at a time until the first is listening.
exec 9>/tmp/.anybot-browser.lock
flock -w 30 9 || true
if pgrep -u bot -f -- "--user-data-dir=$PROFILE" >/dev/null || pgrep -u bot -f -- "--user-data-dir=$(readlink -f "$PROFILE")" >/dev/null; then
  flock -u 9
  exec chromium "${FLAGS[@]}" "$@" 9>&-
fi
# A profile from before this box (a new container) still names the old one in its lock.
rm -f "$PROFILE"/SingletonLock "$PROFILE"/SingletonSocket "$PROFILE"/SingletonCookie
# (The lock's fd is not handed to the browser: it would hold the lock for its whole life, and the
# next start would wait on it.)
setsid chromium "${FLAGS[@]}" "${@:-about:blank}" >/tmp/anybot-browser.log 2>&1 < /dev/null 9>&- &
for _ in $(seq 1 100); do
  python3 -c "import urllib.request; urllib.request.urlopen('http://127.0.0.1:9222/json/version', timeout=1).close()" 2>/dev/null && break
  sleep 0.25
done
