#!/usr/bin/env bash
# Shared entrypoint for every Kedebah Laravel container (web, worker,
# scheduler, reverb). It prepares writable dirs, waits for the DB, optionally
# runs migrations, warms caches, then execs the container command.
set -euo pipefail

APP_DIR=/var/www/html
cd "$APP_DIR"

log() { echo "[entrypoint] $*"; }

# ---------------------------------------------------------------------------
# 1. Ensure the Laravel writable directories exist (named volumes start empty).
# ---------------------------------------------------------------------------
mkdir -p \
  storage/app/public \
  storage/framework/cache/data \
  storage/framework/sessions \
  storage/framework/views \
  storage/logs \
  bootstrap/cache
chown -R www-data:www-data storage bootstrap/cache 2>/dev/null || true
chmod -R ug+rw storage bootstrap/cache 2>/dev/null || true

# ---------------------------------------------------------------------------
# 2. Generate an APP_KEY if none was provided (kept only for the container's
#    lifetime unless you pin APP_KEY in the env file — recommended for prod).
# ---------------------------------------------------------------------------
if [ -z "${APP_KEY:-}" ]; then
  log "APP_KEY is empty; generating an ephemeral key. Pin APP_KEY in the env file for production."
  export APP_KEY="base64:$(head -c 32 /dev/urandom | base64)"
fi

# ---------------------------------------------------------------------------
# 3. Optionally wait for the database (compose sets WAIT_FOR_DB=true on the
#    services that need it first). Uses PHP PDO so no extra tooling is needed.
# ---------------------------------------------------------------------------
if [ "${WAIT_FOR_DB:-false}" = "true" ]; then
  log "Waiting for database ${DB_HOST:-?}:${DB_PORT:-?} ..."
  tries=0
  until php -r '
    $c=getenv("DB_CONNECTION")?:"pgsql";
    $h=getenv("DB_HOST"); $p=getenv("DB_PORT")?:"5432";
    $d=getenv("DB_DATABASE"); $u=getenv("DB_USERNAME"); $w=getenv("DB_PASSWORD");
    try { new PDO("$c:host=$h;port=$p;dbname=$d",$u,$w,[PDO::ATTR_TIMEOUT=>3]); exit(0);}
    catch(Throwable $e){ fwrite(STDERR, $e->getMessage()."\n"); exit(1);} ' 2>/dev/null
  do
    tries=$((tries+1))
    if [ "$tries" -ge "${DB_WAIT_RETRIES:-30}" ]; then
      log "Database not reachable after ${tries} attempts; continuing anyway."
      break
    fi
    sleep 2
  done
  log "Database check finished."
fi

# ---------------------------------------------------------------------------
# 4. Optional automatic migrations. OFF by default — run migrations manually
#    (see bin/migrate.sh) because this stack points at a pre-existing DB.
# ---------------------------------------------------------------------------
if [ "${RUN_MIGRATIONS:-false}" = "true" ]; then
  log "RUN_MIGRATIONS=true -> php artisan migrate --force"
  php artisan migrate --force || log "migrate failed (continuing)"
fi
if [ "${RUN_TENANT_MIGRATIONS:-false}" = "true" ]; then
  log "RUN_TENANT_MIGRATIONS=true -> php artisan tenants:migrate --force"
  php artisan tenants:migrate --force || log "tenants:migrate failed (continuing)"
  # tenant-processor owns module paths (finance lives under database/migrations/finance)
  if [ "${SERVICE_NAME:-}" = "tenant_processor" ] \
    && [ -d database/migrations/finance ]; then
    log "tenant_processor -> php artisan tenants:migrate --path=database/migrations/finance --force"
    php artisan tenants:migrate --path=database/migrations/finance --force \
      || log "tenants:migrate finance path failed (continuing)"
  fi
fi

# ---------------------------------------------------------------------------
# 4b. Tune the php-fpm pool from env (web containers only; harmless elsewhere).
# ---------------------------------------------------------------------------
FPM_POOL=/usr/local/etc/php-fpm.d/zz-www.conf
if [ -f "$FPM_POOL" ]; then
  mc="${PHP_FPM_MAX_CHILDREN:-25}"
  mr="${PHP_FPM_MAX_REQUESTS:-1000}"
  ss=$(( mc / 4 )); [ "$ss" -lt 2 ] && ss=2
  maxs=$(( mc / 2 )); [ "$maxs" -lt "$ss" ] && maxs=$(( ss + 1 ))
  sed -i \
    -e "s/^pm.max_children = .*/pm.max_children = ${mc}/" \
    -e "s/^pm.start_servers = .*/pm.start_servers = ${ss}/" \
    -e "s/^pm.min_spare_servers = .*/pm.min_spare_servers = ${ss}/" \
    -e "s/^pm.max_spare_servers = .*/pm.max_spare_servers = ${maxs}/" \
    -e "s/^pm.max_requests = .*/pm.max_requests = ${mr}/" \
    "$FPM_POOL" 2>/dev/null || true
  log "php-fpm pool: max_children=${mc} start=${ss} spare=${ss}-${maxs} max_requests=${mr}"
fi

# ---------------------------------------------------------------------------
# 5. Storage symlink + config/route/view caches (safe: no DB access needed).
# ---------------------------------------------------------------------------
php artisan storage:link 2>/dev/null || true

if [ "${OPTIMIZE:-true}" = "true" ]; then
  php artisan config:clear >/dev/null 2>&1 || true
  php artisan config:cache >/dev/null 2>&1 || log "config:cache skipped"
  php artisan route:cache  >/dev/null 2>&1 || log "route:cache skipped"
  php artisan event:cache  >/dev/null 2>&1 || true
fi

log "Starting: $*"
exec "$@"
