#!/usr/bin/env bash
# Deploy on a Docker-enabled account without sudo. The only shared component is
# the existing Caddy edge, which receives one validated hostname block.
set -euo pipefail

: "${RKT_DOMAIN:?Set RKT_DOMAIN, e.g. rkt.203.0.113.10.sslip.io}"
if [[ ! "$RKT_DOMAIN" =~ ^[A-Za-z0-9.-]+$ ]]; then
  echo "RKT_DOMAIN must be a hostname."
  exit 1
fi

APP_DIR="${RKT_APP_DIR:-$HOME/roaring-kitty-tracker}"
CADDY_REPO="${RKT_CADDY_REPO:-/opt/lorespace/ontospace_tachyon}"
CADDY_FILE="$CADDY_REPO/deploy/caddy/Caddyfile"
CADDY_CONTAINER="${RKT_CADDY_CONTAINER:-lorespace-caddy}"
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
DATA_VOLUME="roaring-kitty-tracker_tracker-data"

if [ "$PWD" != "$APP_DIR" ]; then
  echo "Run this from $APP_DIR after copying the repository there."
  exit 1
fi
if ! command -v docker >/dev/null; then
  echo "Docker is required for this deployment."
  exit 1
fi
if ! command -v crontab >/dev/null; then
  echo "crontab is required for scheduled refreshes."
  exit 1
fi
if ! docker network inspect ontospace_tachyon_default >/dev/null 2>&1; then
  echo "The shared Caddy Docker network is unavailable."
  exit 1
fi
if [ ! -w "$CADDY_FILE" ]; then
  echo "The shared Caddyfile is not writable by this deployment account."
  exit 1
fi

docker volume create "$DATA_VOLUME" >/dev/null
if [ -n "${RKT_BOOTSTRAP_DATA:-}" ]; then
  if [ ! -d "$RKT_BOOTSTRAP_DATA" ]; then
    echo "RKT_BOOTSTRAP_DATA does not exist: $RKT_BOOTSTRAP_DATA"
    exit 1
  fi
  # The snapshot is copied outside the image so fresh output is available before
  # the first server-side refresh completes.
  docker run --rm \
    -v "$DATA_VOLUME:/target" \
    -v "$RKT_BOOTSTRAP_DATA:/source:ro" \
    alpine:3.20 sh -c 'cp -a /source/. /target/'
fi

docker compose -f deploy/docker-compose.yml build
docker compose -f deploy/docker-compose.yml up -d dashboard

route_file="$(mktemp)"
sed "s/__RKT_DOMAIN__/${RKT_DOMAIN}/g" "$SCRIPT_DIR/Caddyfile.docker" > "$route_file"
backup_file="$(mktemp)"
cp "$CADDY_FILE" "$backup_file"

python3 - "$CADDY_FILE" "$route_file" <<'PY'
from pathlib import Path
import sys

caddyfile = Path(sys.argv[1])
route = Path(sys.argv[2]).read_text()
begin = "# BEGIN RoaringKitty Tracker"
end = "# END RoaringKitty Tracker"
text = caddyfile.read_text()

if begin in text:
    prefix, remainder = text.split(begin, 1)
    if end not in remainder:
        raise SystemExit("Existing RoaringKitty Caddy block has no end marker.")
    _, suffix = remainder.split(end, 1)
    text = prefix + suffix.lstrip("\n")

caddyfile.write_text(text.rstrip() + f"\n\n{begin}\n{route}{end}\n")
PY

if docker exec "$CADDY_CONTAINER" caddy validate --config /etc/caddy/Caddyfile --adapter caddyfile; then
  docker exec "$CADDY_CONTAINER" caddy reload --config /etc/caddy/Caddyfile --adapter caddyfile
else
  cp "$backup_file" "$CADDY_FILE"
  rm -f "$route_file" "$backup_file"
  echo "Caddy configuration was invalid; the previous configuration was restored."
  exit 1
fi
rm -f "$route_file" "$backup_file"

mkdir -p "$APP_DIR/logs"
docker_bin="$(command -v docker)"
cron_file="$(mktemp)"
(crontab -l 2>/dev/null || true) | grep -vF '# RKT_REFRESH' > "$cron_file" || true
printf '30 2 * * 1-5 cd %q && %q compose -f %q run --rm refresh >> %q 2>&1 # RKT_REFRESH\n' \
  "$APP_DIR" "$docker_bin" "$APP_DIR/deploy/docker-compose.yml" "$APP_DIR/logs/refresh.log" >> "$cron_file"
crontab "$cron_file"
rm -f "$cron_file"

if [ "${RKT_START_INITIAL_REFRESH:-0}" = "1" ]; then
  docker compose -f deploy/docker-compose.yml run -d --name rkt-initial-refresh refresh
fi

echo "Tracker deployed: https://${RKT_DOMAIN}/dashboard.html"
echo "Health check: https://${RKT_DOMAIN}/healthz"
echo "Weekday refresh: 02:30 server time (deploy user crontab)"
