#!/usr/bin/env bash

# This box runs cPanel/WHM with cpanel_php_fpm - the account's default CLI
# `php` on PATH is NOT necessarily the same version as this vhost's
# configured PHP-FPM (they drift independently; confirmed via `uapi
# LangPHP.php_get_vhost_versions` on 2026-08-20 that they currently do
# differ: CLI default was 8.1.34 while this vhost's FPM was explicitly
# pinned to ea-php83). A 2026-08-19 incident shipped a vendor/ built for a
# newer PHP than the CLI default resolved to; deploy.sh deleted and
# re-extracted the whole app directory before any version check ran, so
# there was no automatic rollback once the mismatch surfaced. To not repeat
# that: resolve the ACTUAL configured PHP binary for this vhost via `uapi`
# below, and verify it meets composer.json's minimum BEFORE touching
# anything on disk.

set -euo pipefail

APP_DIR="${1:-}"
ARCHIVE_PATH="${2:-}"
ENV_FILE_PATH="${3:-}"
SYNC_ENV="${4:-false}" # deploy.yml only passes "true" for an explicit, manually-triggered env sync - see its workflow_dispatch input
MIN_PHP_VERSION_ID="${MIN_PHP_VERSION_ID:-80200}" # keep in sync with composer.json's config.platform.php

if [ -z "$APP_DIR" ] || [ -z "$ARCHIVE_PATH" ] || [ -z "$ENV_FILE_PATH" ]; then
  echo "Usage: deploy.sh <app_dir> <archive_path> <env_file_path> [sync_env]"
  exit 1
fi

if [ ! -f "$ENV_FILE_PATH" ]; then
  echo "Env file not found at $ENV_FILE_PATH"
  exit 1
fi

VHOST_NAME="$(basename "$APP_DIR")"

# Ask cPanel itself which PHP-FPM version is configured for this vhost,
# rather than assuming the CLI `php` on PATH matches it. Falls back to the
# CLI default only if `uapi` genuinely isn't available (e.g. a non-cPanel
# host), so this still works outside this specific VPS.
PHP_BIN="$(php -r '
$vhost = $argv[1];
$json = @shell_exec("uapi --output=json LangPHP php_get_vhost_versions 2>/dev/null");
$data = $json ? json_decode($json, true) : null;
foreach (($data["result"]["data"] ?? []) as $row) {
    if (($row["vhost"] ?? null) === $vhost && !empty($row["version"])) {
        $candidate = "/opt/cpanel/" . $row["version"] . "/root/usr/bin/php";
        if (is_executable($candidate)) {
            echo $candidate;
        }
        break;
    }
}
' "$VHOST_NAME" 2>/dev/null || true)"

if [ -z "$PHP_BIN" ]; then
  echo "Could not resolve this vhost's configured PHP-FPM binary via uapi (vhost lookup: $VHOST_NAME) - falling back to CLI default 'php'."
  PHP_BIN="php"
fi

ACTUAL_PHP_VERSION_ID="$("$PHP_BIN" -r 'echo PHP_VERSION_ID;' 2>/dev/null || echo 0)"
if [ "$ACTUAL_PHP_VERSION_ID" -lt "$MIN_PHP_VERSION_ID" ]; then
  echo "Refusing to deploy: resolved PHP binary '$PHP_BIN' reports PHP_VERSION_ID=$ACTUAL_PHP_VERSION_ID, below the required $MIN_PHP_VERSION_ID."
  echo "This check runs before anything on disk is touched, specifically so a version mismatch can't leave the app half-deployed again."
  echo "Fix the mismatch (check cPanel MultiPHP Manager for $VHOST_NAME, or this account's CLI PHP default) and re-run."
  exit 1
fi
echo "Deploying with PHP binary: $PHP_BIN (PHP_VERSION_ID=$ACTUAL_PHP_VERSION_ID)"

USE_SUDO=0
if command -v sudo >/dev/null 2>&1 && sudo -n true >/dev/null 2>&1; then
  USE_SUDO=1
fi

run_fs() {
  if [ "$USE_SUDO" -eq 1 ]; then
    sudo "$@"
  else
    "$@"
  fi
}

if [ -d "$APP_DIR" ]; then
  if [ ! -w "$APP_DIR" ]; then
    if [ "$USE_SUDO" -eq 0 ]; then
      echo "Deployment path exists but is not writable: $APP_DIR"
      echo "Use an SSH user that owns this directory, or set DEPLOY_PATH to a writable path in GitHub secrets."
      echo "Or configure passwordless sudo for this SSH user."
      exit 1
    fi
  fi
else
  APP_PARENT_DIR="$(dirname "$APP_DIR")"
  if [ ! -d "$APP_PARENT_DIR" ]; then
    echo "Parent directory does not exist: $APP_PARENT_DIR"
    echo "Set DEPLOY_PATH to an existing writable path in GitHub secrets."
    exit 1
  fi

  if [ ! -w "$APP_PARENT_DIR" ]; then
    if [ "$USE_SUDO" -eq 0 ]; then
      echo "Cannot create deployment directory. Parent is not writable: $APP_PARENT_DIR"
      echo "Set DEPLOY_PATH to a writable path in GitHub secrets."
      echo "Or configure passwordless sudo for this SSH user."
      exit 1
    fi
  fi

  run_fs mkdir -p "$APP_DIR"
fi

run_fs mkdir -p "$APP_DIR/storage/framework/cache"
run_fs mkdir -p "$APP_DIR/storage/framework/sessions"
run_fs mkdir -p "$APP_DIR/storage/framework/views"
run_fs mkdir -p "$APP_DIR/storage/logs"
run_fs mkdir -p "$APP_DIR/bootstrap/cache"

cd "$APP_DIR"

run_fs find "$APP_DIR" -mindepth 1 -maxdepth 1 \
  ! -name '.env' \
  ! -name 'storage' \
  ! -name 'bootstrap' \
  ! -name '.well-known' \
  -exec rm -rf {} +

if [ "$SYNC_ENV" = "true" ] || [ ! -f "$APP_DIR/.env" ]; then
  echo "Syncing .env from the deploy package (explicit sync_env=true, or no .env exists yet on this box)."
  run_fs cp "$ENV_FILE_PATH" "$APP_DIR/.env"
else
  echo "Leaving the live .env untouched (sync_env not requested) - see deploy.yml's workflow_dispatch input to opt in."
fi

run_fs tar -xzf "$ARCHIVE_PATH" -C "$APP_DIR"
run_fs rm -f "$ARCHIVE_PATH" "$ENV_FILE_PATH"

if [ "$USE_SUDO" -eq 1 ]; then
  APP_OWNER="$(id -un)"
  APP_GROUP="$(id -gn)"
  sudo chown -R "$APP_OWNER:$APP_GROUP" "$APP_DIR"
fi

run_fs chmod -R ug+rw "$APP_DIR/storage" "$APP_DIR/bootstrap/cache"

"$PHP_BIN" artisan optimize:clear
"$PHP_BIN" artisan config:cache
"$PHP_BIN" artisan route:cache || true
"$PHP_BIN" artisan view:cache
"$PHP_BIN" artisan migrate --force
"$PHP_BIN" artisan db:seed --class=RoleSeeder --force
