#!/usr/bin/env bash
# One-time (idempotent) environment bootstrap for running the
# espresso_frame FastAPI server and browser-driving its UI, in a
# container that ships with NO Python/Node/Docker/browser and NO sudo.
# Re-run any time; every step checks whether it already happened.
set -euo pipefail
cd "$(git -C "$(dirname "${BASH_SOURCE[0]}")" rev-parse --show-toplevel)/server"

UV_BIN="$HOME/.local/bin/uv"
DEPS_ROOT="/tmp/run-server-chromium-deps"
APT_WORK="/tmp/apt-work-run-server"
SKILL_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
ENV_FILE="$SKILL_DIR/env.sh"

# 1. uv: a static Rust binary that can fetch its own Python build with
# no C compiler needed (this container has none).
if [ ! -x "$UV_BIN" ]; then
  echo "installing uv..."
  curl -LsSf https://astral.sh/uv/install.sh | sh
fi

# 2. Python 3.12 + venv + server deps
if [ ! -x .venv/bin/uvicorn ]; then
  echo "creating venv + installing server deps..."
  "$UV_BIN" python install 3.12
  "$UV_BIN" venv --python 3.12 .venv
  "$UV_BIN" pip install -r requirements.txt
fi

# 3. Playwright (Python) + its Chromium download (~280MB: full chrome +
# chrome-headless-shell + ffmpeg)
if ! .venv/bin/python -c "import playwright" 2>/dev/null; then
  echo "installing playwright..."
  "$UV_BIN" pip install playwright
fi
if ! ls "$HOME"/.cache/ms-playwright/chromium-*/chrome-linux64/chrome >/dev/null 2>&1; then
  echo "downloading chromium..."
  .venv/bin/playwright install chromium
fi

# 4. Chromium's shared libs + fonts. `playwright install-deps` and
# `apt-get install` both need root; neither is available. Instead:
# download the .deb files directly (apt-get download works read-only
# without root once given a user-writable state dir) and extract
# (not install) them with dpkg-deb -x, which needs no root either.
if [ ! -f "$DEPS_ROOT/usr/lib/x86_64-linux-gnu/libglib-2.0.so.0" ]; then
  echo "fetching chromium's shared libs + fonts (non-root)..."
  mkdir -p "$APT_WORK/lists" "$APT_WORK/cache/archives/partial" "$APT_WORK/debs" "$DEPS_ROOT"

  apt-get -o Dir::State::Lists="$APT_WORK/lists" -o Dir::Cache="$APT_WORK/cache" \
    -o Dir::Etc::SourceParts=/dev/null update

  PKGS="libglib2.0-0t64 libnspr4 libnss3 libatk1.0-0t64 libatk-bridge2.0-0t64
        libdbus-1-3 libxcomposite1 libxdamage1 libxfixes3 libxrandr2 libgbm1
        libxkbcommon0 libasound2t64 libatspi2.0-0t64 libcups2t64 libcairo2
        libpango-1.0-0 libpangocairo-1.0-0 libx11-6 libxcb1 libxext6
        fonts-liberation fontconfig libfontconfig1"
  # ^ first row: what chrome-headless-shell's ldd reported missing.
  # second row: what the FULL chrome binary additionally needed (we use
  # full chrome, not headless-shell -- see Gotchas in SKILL.md).

  apt-get -o Dir::State::Lists="$APT_WORK/lists" -o Dir::Cache="$APT_WORK/cache" \
    -o Dir::Etc::SourceParts=/dev/null install --download-only --reinstall -y \
    --print-uris $PKGS | grep -oP "^'[^']+'" | tr -d "'" > "$APT_WORK/urls.txt"

  (cd "$APT_WORK/debs" && xargs -n1 -P8 curl -sS -O --max-time 30) < "$APT_WORK/urls.txt"
  for f in "$APT_WORK"/debs/*.deb; do dpkg-deb -x "$f" "$DEPS_ROOT"; done

  # fonts.conf as shipped points at the real /usr/share/fonts, which is
  # root-owned and has nothing extracted into it. Point it at our
  # extracted copy instead, and give it a writable cache dir.
  mkdir -p /tmp/run-server-fontcache
  sed -i "s#<dir>/usr/share/fonts</dir>#<dir>$DEPS_ROOT/usr/share/fonts</dir>#" \
    "$DEPS_ROOT/etc/fonts/fonts.conf"
  sed -i "s#<cachedir>.*</cachedir>#<cachedir>/tmp/run-server-fontcache</cachedir>#" \
    "$DEPS_ROOT/etc/fonts/fonts.conf"

  PATH="$DEPS_ROOT/usr/bin:$PATH" \
    LD_LIBRARY_PATH="$DEPS_ROOT/usr/lib/x86_64-linux-gnu:$DEPS_ROOT/lib/x86_64-linux-gnu" \
    FONTCONFIG_PATH="$DEPS_ROOT/etc/fonts" \
    "$DEPS_ROOT/usr/bin/fc-cache" -f
fi

# 5. tmux -- also missing, also no apt/sudo. Same non-root download +
# dpkg-deb -x trick, into the same extracted root (so its `usr/bin` is
# already on PATH via env.sh).
if [ ! -f "$DEPS_ROOT/usr/bin/tmux" ]; then
  echo "fetching tmux (non-root)..."
  mkdir -p "$APT_WORK/lists" "$APT_WORK/cache/archives/partial" "$APT_WORK/debs" "$DEPS_ROOT"
  apt-get -o Dir::State::Lists="$APT_WORK/lists" -o Dir::Cache="$APT_WORK/cache" \
    -o Dir::Etc::SourceParts=/dev/null install --download-only --reinstall -y \
    --print-uris tmux | grep -oP "^'[^']+'" | tr -d "'" > "$APT_WORK/tmux_urls.txt"
  (cd "$APT_WORK/debs" && xargs -n1 -P3 curl -sS -O --max-time 30) < "$APT_WORK/tmux_urls.txt"
  for f in $(sed -E 's#.*/##' "$APT_WORK/tmux_urls.txt"); do dpkg-deb -x "$APT_WORK/debs/$f" "$DEPS_ROOT"; done
fi

CHROME_BIN="$(ls "$HOME"/.cache/ms-playwright/chromium-*/chrome-linux64/chrome | head -1)"

cat > "$ENV_FILE" <<EOF
# Generated by setup.sh. Source this before running driver.py (it
# needs LD_LIBRARY_PATH/FONTCONFIG_PATH set before the Chromium
# subprocess launches -- driver.py does not source it for you).
# start-server.sh does NOT need this file -- uvicorn has no such deps.
export PATH="\$HOME/.local/bin:$DEPS_ROOT/usr/bin:\$PATH"
export LD_LIBRARY_PATH="$DEPS_ROOT/usr/lib/x86_64-linux-gnu:$DEPS_ROOT/lib/x86_64-linux-gnu"
export FONTCONFIG_PATH="$DEPS_ROOT/etc/fonts"
export RUN_SERVER_CHROME_BIN="$CHROME_BIN"
EOF

echo "setup complete -> $ENV_FILE"
