#!/usr/bin/env bash
#
# register-runner.sh — Reproducibly register (or re-register) a Gitea Actions
# runner against the local/VM Gitea instance.
#
# Why this exists: the runner was originally registered by hand, which is not
# reproducible for the next operator. This script captures the canonical flow:
# fetch a registration token from Gitea, register act_runner with the agreed
# labels + capacity, and externalise the npm token into a gitignored env_file
# (never inline in config.yaml).
#
# Usage:
#   GITEA_ADMIN_USER=gitea-admin GITEA_ADMIN_PASS=... bash register-runner.sh
#   bash register-runner.sh --instance http://localhost:3300 --name bytelyst-mac
#   bash register-runner.sh --mode docker      # containerized labels
#   bash register-runner.sh --capacity 2       # parallel jobs
#
# Idempotent: if a runner is already registered (.runner exists), it prints the
# current registration and exits unless --force is passed.
set -euo pipefail

# ── defaults ───────────────────────────────────────────────────────────────
INSTANCE="${GITEA_INSTANCE:-http://localhost:3300}"
RUNNER_NAME="${RUNNER_NAME:-$(hostname -s)}"
CAPACITY="${RUNNER_CAPACITY:-2}"
MODE="host"                       # host | docker
FORCE=0
CONFIG_DIR="${ACT_RUNNER_CONFIG_DIR:-/opt/homebrew/etc/act_runner}"
RUNNER_FILE="${ACT_RUNNER_FILE:-/opt/homebrew/var/lib/act_runner/.runner}"
ENV_FILE="${ACT_RUNNER_ENV_FILE:-$CONFIG_DIR/runner.env}"

# Docker image used when MODE=docker (mirrors GitHub's ubuntu-latest closely).
DOCKER_IMAGE="${RUNNER_DOCKER_IMAGE:-catthehacker/ubuntu:act-latest}"

while [ $# -gt 0 ]; do
  case "$1" in
    --instance) INSTANCE="$2"; shift 2 ;;
    --name)     RUNNER_NAME="$2"; shift 2 ;;
    --capacity) CAPACITY="$2"; shift 2 ;;
    --mode)     MODE="$2"; shift 2 ;;
    --force)    FORCE=1; shift ;;
    -h|--help)  grep '^#' "$0" | sed 's/^# \{0,1\}//'; exit 0 ;;
    *) echo "unknown arg: $1" >&2; exit 2 ;;
  esac
done

command -v act_runner >/dev/null 2>&1 || {
  echo "✗ act_runner not on PATH. Install: brew install act_runner" >&2
  exit 1
}

# ── labels per mode ──────────────────────────────────────────────────────────
if [ "$MODE" = "docker" ]; then
  LABELS="ubuntu-latest:docker://$DOCKER_IMAGE,ubuntu-22.04:docker://$DOCKER_IMAGE,self-hosted:host"
else
  LABELS="ubuntu-latest:host,macos-latest:host,macos-15:host,self-hosted:host"
fi

echo "── Gitea runner registration ──"
echo "  instance : $INSTANCE"
echo "  name     : $RUNNER_NAME"
echo "  mode     : $MODE"
echo "  capacity : $CAPACITY"
echo "  labels   : $LABELS"

# ── already registered? ──────────────────────────────────────────────────────
if [ -f "$RUNNER_FILE" ] && [ "$FORCE" -ne 1 ]; then
  echo ""
  echo "✓ runner already registered ($RUNNER_FILE). Current identity:"
  python3 - "$RUNNER_FILE" <<'PY' 2>/dev/null || cat "$RUNNER_FILE"
import json, sys
d = json.load(open(sys.argv[1]))
for k in ("id", "uuid", "name", "address", "labels", "ephemeral"):
    print(f"  {k}: {d.get(k)}")
PY
  echo ""
  echo "  Pass --force to re-register (this invalidates the old runner)."
  exit 0
fi

# ── fetch a registration token ───────────────────────────────────────────────
# Admin-scoped: GET /admin/runners/registration-token (Gitea >= 1.20).
: "${GITEA_ADMIN_USER:?set GITEA_ADMIN_USER}"
: "${GITEA_ADMIN_PASS:?set GITEA_ADMIN_PASS}"

REG_TOKEN=$(curl -fsS -u "$GITEA_ADMIN_USER:$GITEA_ADMIN_PASS" \
  "$INSTANCE/api/v1/admin/runners/registration-token" \
  | python3 -c "import json,sys; print(json.load(sys.stdin)['token'])")
[ -n "$REG_TOKEN" ] || { echo "✗ could not fetch registration token" >&2; exit 1; }
echo "✓ registration token obtained"

# ── register ────────────────────────────────────────────────────────────────
[ "$FORCE" -eq 1 ] && rm -f "$RUNNER_FILE"
act_runner register \
  --no-interactive \
  --instance "$INSTANCE" \
  --token "$REG_TOKEN" \
  --name "$RUNNER_NAME" \
  --labels "$LABELS" \
  --config "$CONFIG_DIR/config.yaml"
echo "✓ runner registered"

echo ""
echo "Next: externalise secrets into $ENV_FILE (see GITEA_VM_SETUP.md §11),"
echo "set runner.capacity: $CAPACITY in config.yaml, then:"
echo "  brew services restart act_runner"
