#!/usr/bin/env bash
set -euo pipefail

release_id="${1:?release id required}"
site_host="${2:?Sites origin host required}"
wheel_name="${3:?wheel filename required}"
payload="${4:?payload directory required}"

case "$release_id" in
  *[!A-Za-z0-9._-]*) echo "invalid release id" >&2; exit 2 ;;
esac
case "$site_host" in
  *[!A-Za-z0-9.-]*) echo "invalid Sites host" >&2; exit 2 ;;
esac
case "$wheel_name" in
  *[!A-Za-z0-9._-]*) echo "invalid wheel filename" >&2; exit 2 ;;
esac

domain="backplane.cyberelf.link"
app_root="/opt/backplane-runtime"
release_dir="$app_root/releases/$release_id"
current_link="$app_root/current"
nginx_available="/etc/nginx/sites-available/$domain"
nginx_enabled="/etc/nginx/sites-enabled/$domain"
previous_release="$(readlink -f "$current_link" 2>/dev/null || true)"
nginx_backup=""

rollback() {
  status=$?
  if test "$status" -eq 0; then
    return
  fi

  echo "deployment failed; rolling back" >&2
  if test -n "$previous_release" && test -d "$previous_release"; then
    ln -sfn "$previous_release" "$app_root/current.rollback"
    mv -Tf "$app_root/current.rollback" "$current_link"
    systemctl restart backplane-runtime || true
  else
    rm -f "$current_link"
    systemctl stop backplane-runtime || true
  fi
  if test -n "$nginx_backup" && test -f "$nginx_backup"; then
    cp "$nginx_backup" "$nginx_available"
    nginx -t && systemctl reload nginx || true
  fi
  exit "$status"
}
trap rollback EXIT

test -f "$payload/$wheel_name"
test -f "$payload/backplane-runtime.service"
test -f "$payload/nginx.bootstrap.conf"
test -f "$payload/nginx.backplane.conf.template"

mkdir -p "$app_root/releases" /var/www/backplane-acme
if test -f "$nginx_available"; then
  nginx_backup="$payload/nginx.previous.conf"
  cp "$nginx_available" "$nginx_backup"
fi

if ! test -f "/etc/letsencrypt/live/$domain/fullchain.pem"; then
  cp "$payload/nginx.bootstrap.conf" "$nginx_available"
  ln -sfn "$nginx_available" "$nginx_enabled"
  nginx -t
  systemctl reload nginx
  certbot certonly \
    --webroot \
    -w /var/www/backplane-acme \
    -d "$domain" \
    --non-interactive \
    --agree-tos \
    --email justin@cyberelf.link
fi

test ! -e "$release_dir"
mkdir -p "$release_dir"
python3 -m venv "$release_dir/.venv"
"$release_dir/.venv/bin/python" -m pip install --disable-pip-version-check "$payload/$wheel_name"

install -m 0644 "$payload/backplane-runtime.service" /etc/systemd/system/backplane-runtime.service
sed "s/__SITE_HOST__/$site_host/g" "$payload/nginx.backplane.conf.template" > "$nginx_available"
ln -sfn "$nginx_available" "$nginx_enabled"

ln -sfn "$release_dir" "$app_root/current.next"
mv -Tf "$app_root/current.next" "$current_link"

systemctl daemon-reload
systemctl enable backplane-runtime
systemctl restart backplane-runtime

for _ in $(seq 1 20); do
  if curl --silent --show-error --fail http://127.0.0.1:8994/api/health >/dev/null; then
    break
  fi
  sleep 1
done
curl --silent --show-error --fail http://127.0.0.1:8994/api/health >/dev/null

nginx -t
systemctl reload nginx
for _ in $(seq 1 20); do
  if curl --silent --show-error --fail "https://$domain/api/health" >/dev/null; then
    break
  fi
  sleep 1
done
curl --silent --show-error --fail "https://$domain/api/health" >/dev/null
curl --silent --show-error --fail "https://$domain/" | grep -q "The model stays frozen"

trap - EXIT
echo "deployed $release_id"
