# ---- vendor ----------------------------------------------------------------
FROM composer:2 AS vendor

WORKDIR /app

# anagram-finder/core is a VCS repository, so composer needs git.
RUN apk add --no-cache git

COPY composer.json composer.lock ./
RUN composer install \
        --no-dev \
        --no-scripts \
        --no-autoloader \
        --prefer-dist \
        --no-interaction

COPY . .
# --no-scripts: Laravel's post-autoload-dump hook runs artisan, which wants an
# environment that does not exist at build time. Package discovery happens on boot.
RUN composer dump-autoload --no-dev --optimize --classmap-authoritative --no-scripts

# ---- assets ----------------------------------------------------------------
FROM node:22-alpine AS assets

WORKDIR /app

# @lvl0/ui is a git dependency, so npm needs git available.
RUN apk add --no-cache git

COPY package.json package-lock.json ./
RUN npm ci

COPY vite.config.js ./
COPY resources ./resources

# app.css imports Flux's stylesheet from vendor/ and scans three vendor globs
# for class names, so the asset build needs composer's output present.
COPY --from=vendor /app/vendor ./vendor

RUN npm run build

# ---- runtime ---------------------------------------------------------------
FROM dunglas/frankenphp:1-php8.4-alpine

RUN apk add --no-cache mariadb-client curl

RUN install-php-extensions \
    pdo_mysql \
    opcache \
    zip \
    gd \
    intl \
    bcmath \
    pcntl

RUN mv "$PHP_INI_DIR/php.ini-production" "$PHP_INI_DIR/php.ini"

WORKDIR /app

COPY --from=vendor /app /app
COPY --from=assets /app/public/build /app/public/build

# The dev server writes public/hot and only removes it on a clean shutdown; a
# stray copy makes @vite() point at a dev server that does not exist here.
RUN rm -f /app/public/hot

RUN cat > /etc/caddy/Caddyfile <<'EOF'
{
    frankenphp
    order php_server before file_server
}

:8000 {
    root * /app/public

    php_server {
        index index.php
    }

    encode gzip
    file_server

    header {
        X-Frame-Options "SAMEORIGIN"
        X-Content-Type-Options "nosniff"
        Referrer-Policy "strict-origin-when-cross-origin"
    }
}
EOF

RUN cat > /start.sh <<'EOF'
#!/bin/sh
set -e

if [ -n "$DB_HOST" ]; then
    echo "Waiting for database..."
    until mariadb -h "$DB_HOST" -u "$DB_USERNAME" -p"$DB_PASSWORD" -e "SELECT 1" >/dev/null 2>&1; do
        sleep 2
    done
fi

# Rebuild the package manifest from what is actually installed. Any manifest
# baked in at build time could name a dev provider that --no-dev omitted.
rm -f bootstrap/cache/packages.php bootstrap/cache/services.php
php artisan package:discover --ansi

php artisan migrate --force

# Cached at boot rather than at build: config:cache bakes in environment values,
# which are not known until the container runs.
php artisan config:cache
php artisan route:cache
php artisan view:cache

exec frankenphp run --config /etc/caddy/Caddyfile
EOF
RUN chmod +x /start.sh

RUN chown -R www-data:www-data /app/storage /app/bootstrap/cache

EXPOSE 8000

CMD ["/start.sh"]
