#!/bin/bash
# Deploy a release zip (built as in DEPLOY.md 0.3) atomically.
#   sudo greenathon-deploy /home/ubuntu/greenathon-release.zip
#
# Layout:  /var/www/greenathon/releases/<timestamp>/   one folder per release
#          /var/www/greenathon/shared/.env, shared/storage/   kept across releases
#          /var/www/greenathon/current -> releases/<timestamp>   what nginx and workers use
set -Eeuo pipefail

APP=${GREENATHON_APP:-/var/www/greenathon}
APP_USER=${GREENATHON_USER:-greenathon}
KEEP=${GREENATHON_KEEP_RELEASES:-5}
FPM_SERVICE=${GREENATHON_FPM_SERVICE:-php8.3-fpm}
ZIP=${1:?usage: greenathon-deploy <release.zip>}

[[ $EUID -eq 0 ]] || { echo "Run with sudo." >&2; exit 1; }
[[ -f $ZIP ]] || { echo "No such file: $ZIP" >&2; exit 1; }
[[ -f $APP/shared/.env ]] || { echo "Missing $APP/shared/.env (see EC2-SETUP.md step 9)." >&2; exit 1; }

as_app() { sudo -u "$APP_USER" -H "$@"; }
TS=$(date +%Y%m%d%H%M%S)
REL=$APP/releases/$TS
TMP=$(mktemp -d)
WENT_DOWN=0

on_error() {
    echo "!! Deploy failed; the previous release stays live." >&2
    rm -rf "$TMP"
    [[ -d $REL && $(readlink -f "$APP/current" 2>/dev/null) != "$REL" ]] && rm -rf "$REL"
    if [[ $WENT_DOWN -eq 1 && -e $APP/current ]]; then as_app php "$APP/current/artisan" up || true; fi
}
trap on_error ERR

echo "== Unpacking $ZIP"
unzip -q "$ZIP" -d "$TMP"
SRC=$(dirname "$(find "$TMP" -maxdepth 2 -name artisan -type f | head -1)")
[[ -f $SRC/artisan && -d $SRC/vendor && -f $SRC/public/build/manifest.json ]] \
    || { echo "Release must contain artisan, vendor/ and public/build/ (run composer install and npm run build first)." >&2; false; }

mkdir -p "$APP/releases"
mv "$SRC" "$REL"
rm -rf "$TMP"

# Shared state: .env and storage/ live outside the release.
mkdir -p "$APP"/shared/storage/{app/private,app/public,framework/cache/data,framework/sessions,framework/views,logs}
rm -rf "$REL/storage" "$REL/.env"
ln -s "$APP/shared/storage" "$REL/storage"
ln -s "$APP/shared/.env" "$REL/.env"
rm -f "$REL"/bootstrap/cache/*.php
chown -R "$APP_USER:$APP_USER" "$REL" "$APP/shared/storage"
chmod -R g+rX,o-rwx "$REL"

echo "== Checking the release boots"
as_app php "$REL/artisan" --version

if [[ -e $APP/current ]]; then
    echo "== Maintenance mode on the current release"
    as_app php "$APP/current/artisan" down --retry=15 --refresh=15
    WENT_DOWN=1
fi

echo "== Migrating"
as_app php "$REL/artisan" migrate --force

echo "== Switching current -> releases/$TS"
ln -sfn "$REL" "$APP/current.new"
mv -Tf "$APP/current.new" "$APP/current"

echo "== Caching config, routes, views"
as_app php "$APP/current/artisan" optimize
systemctl reload "$FPM_SERVICE"
as_app php "$APP/current/artisan" queue:restart
as_app php "$APP/current/artisan" up
WENT_DOWN=0

echo "== Removing old releases (keeping $KEEP)"
ls -1dt "$APP"/releases/*/ | tail -n +$((KEEP + 1)) | xargs -r rm -rf

trap - ERR
echo "Deployed $TS."
