#!/bin/sh
set -e

cd /var/www/html

# --- PHP dependencies -------------------------------------------------------
# Dev and production get deliberately different behaviour here.
#
# Production: vendor/ is baked into the image by the `build` stage of the
# Dockerfile and there is no source bind-mount. Running `composer install` at
# boot is never correct - if /var/www/html is empty or masked by a mount there
# is no composer.json to install from, composer exits non-zero, `set -e` kills
# the entrypoint, and `restart: unless-stopped` turns that into a crash loop
# that never reaches PHP-FPM. Fail loudly with an actionable message instead.
#
# Development: the project directory IS bind-mounted from the host, so vendor/
# is legitimately absent on a fresh checkout and installing it here is the
# convenience that makes `docker compose up` work with no host PHP toolchain.
if [ "$APP_ENV" = "production" ]; then
    if [ ! -f vendor/autoload.php ]; then
        echo "[entrypoint] ERROR: vendor/autoload.php is missing from the image."
        echo "[entrypoint] Production dependencies are installed at BUILD time, not at boot."
        echo "[entrypoint] Check that the image was built from the 'prod' target and that"
        echo "[entrypoint] .dockerignore is not excluding composer.json or the application."
        echo "[entrypoint]   docker compose -f docker-compose.prod.yml build --no-cache backend"
        exit 1
    fi
elif [ ! -f vendor/autoload.php ]; then
    echo "[entrypoint] Installing composer dependencies..."
    composer install --no-interaction --prefer-dist
fi

# In development the project directory is bind-mounted and .env lives on the host.
# In production config is injected via docker compose env_file (apps/backend/.env).
if [ "$APP_ENV" != "production" ] && [ ! -f .env ]; then
    echo "[entrypoint] Creating .env from .env.example"
    cp .env.example .env
fi

# Remove any stale compiled manifests before booting the framework. These may
# reference dev-only packages (e.g. laravel/pail) that are absent from a
# --no-dev production install, which would otherwise crash on boot.
echo "[entrypoint] Clearing stale bootstrap/config caches..."
rm -f bootstrap/cache/packages.php \
      bootstrap/cache/services.php \
      bootstrap/cache/config.php \
      bootstrap/cache/routes-v7.php 2>/dev/null || true

# Application key: prefer the container environment (env_file), then .env on disk.
has_app_key() {
    if [ -n "$APP_KEY" ] && [ "$APP_KEY" != "base64:" ]; then
        return 0
    fi
    if [ -f .env ] && grep -qE '^APP_KEY=base64:' .env 2>/dev/null; then
        return 0
    fi
    return 1
}

if ! has_app_key; then
    if [ -f .env ] && [ ! -w .env ]; then
        echo "[entrypoint] ERROR: APP_KEY is not set and .env is read-only."
        echo "[entrypoint] Set APP_KEY in apps/backend/.env on the host, then restart."
        echo "[entrypoint]   cd apps/backend && php artisan key:generate"
        exit 1
    fi

    if [ "$APP_ENV" = "production" ]; then
        echo "[entrypoint] ERROR: APP_KEY is not set."
        echo "[entrypoint] Set APP_KEY in apps/backend/.env on the host, then restart."
        echo "[entrypoint]   cd apps/backend && php artisan key:generate"
        exit 1
    fi

    echo "[entrypoint] Generating application key..."
    php artisan key:generate --force
fi

# Wait for the database to accept connections.
DB_HOST="${DB_HOST:-mysql}"
DB_PORT="${DB_PORT:-3306}"
echo "[entrypoint] Waiting for database at ${DB_HOST}:${DB_PORT}..."
until php -r "exit(@fsockopen(getenv('DB_HOST') ?: 'mysql', intval(getenv('DB_PORT') ?: 3306)) ? 0 : 1);" 2>/dev/null; do
    sleep 2
done
echo "[entrypoint] Database is reachable."

php artisan migrate --force || true
php artisan storage:link || true

if [ "$APP_ENV" = "production" ]; then
    echo "[entrypoint] Caching configuration for production..."
    php artisan config:cache
    php artisan route:cache
    php artisan view:cache || true
fi

chown -R www-data:www-data storage bootstrap/cache 2>/dev/null || true

exec "$@"
