#!/bin/sh
# Updates FlowFabric on the app server to the latest commit and migrates
# the database:
#
#   sh /opt/flowfabric/deploy/scripts/update.sh
#
# 1. pulls the code, 2. builds the images, 3. dumps the main database
# (the API's own role owns it, so no superuser is needed), 4. applies
# pending migrations, 5. restarts the containers and waits for /ready.
# SKIP_BACKUP=1 leaves out step 3.
set -eu

DEPLOY_DIR=$(cd "$(dirname "$0")/.." && pwd)
cd "$DEPLOY_DIR"
compose() { docker compose -f docker-compose.prod.yml "$@"; }

echo "==> Pulling the latest code"
git -C .. pull --ff-only

echo "==> Building images"
compose build

if [ "${SKIP_BACKUP:-0}" != "1" ]; then
  echo "==> Dumping the database before migrating"
  BACKUP_DIR=${BACKUP_DIR:-/var/backups/flowfabric/pre-update}
  mkdir -p "$BACKUP_DIR"
  DB_URL=$(sed -n 's/^DATABASE_URL=//p' .env | tail -n 1 | sed 's/+asyncpg//')
  STAMP=$(date +%Y-%m-%d_%H%M)
  docker run --rm --network host -v "$BACKUP_DIR:/backup" postgres:18-alpine \
    pg_dump -Fc -d "$DB_URL" -f "/backup/flowfabric-$STAMP.dump"
  echo "    $BACKUP_DIR/flowfabric-$STAMP.dump"
fi

echo "==> Applying migrations"
compose run --rm --no-deps backend python -m app.db_migrate deploy

echo "==> Restarting"
compose up -d --remove-orphans

echo "==> Waiting for the API"
i=0
until compose exec -T backend python -c "import urllib.request; urllib.request.urlopen('http://127.0.0.1:8000/ready', timeout=4)" >/dev/null 2>&1; do
  i=$((i + 1))
  if [ "$i" -ge 30 ]; then
    echo "The API isn't ready after 2.5 minutes — check: docker compose -f docker-compose.prod.yml logs backend" >&2
    exit 1
  fi
  sleep 5
done
compose ps
docker image prune -f >/dev/null
echo "==> FlowFabric is up to date"
