# syntax=docker/dockerfile:1

# =============================================================================
# PHP 8.5 + FrankenPHP - Backend Classeo
# =============================================================================

FROM dunglas/frankenphp:1-php8.5-alpine AS base

# Install system dependencies
RUN apk add --no-cache \
    acl \
    fcgi \
    file \
    gettext \
    git \
    freetype-dev \
    icu-dev \
    imagemagick-dev \
    libjpeg-turbo-dev \
    libpng-dev \
    libzip-dev \
    postgresql-dev \
    rabbitmq-c-dev \
    linux-headers \
    $PHPIZE_DEPS

# Install PHP extensions (opcache is pre-installed in FrankenPHP)
RUN docker-php-ext-configure gd --with-freetype --with-jpeg \
    && docker-php-ext-install gd intl pcntl pdo_pgsql zip sockets

# Install Imagick extension for image processing (logo resize, etc.)
RUN pecl install imagick && docker-php-ext-enable imagick

# Install AMQP extension for RabbitMQ
RUN pecl install amqp && docker-php-ext-enable amqp

# Install Redis extension
RUN pecl install redis && docker-php-ext-enable redis

# Install Composer
COPY --from=composer:2 /usr/bin/composer /usr/bin/composer

# Set working directory
WORKDIR /app

# Configure PHP for production
RUN mv "$PHP_INI_DIR/php.ini-production" "$PHP_INI_DIR/php.ini"

# Custom PHP configuration
RUN echo "opcache.enable=1" >> "$PHP_INI_DIR/conf.d/opcache.ini" \
    && echo "opcache.memory_consumption=256" >> "$PHP_INI_DIR/conf.d/opcache.ini" \
    && echo "opcache.interned_strings_buffer=16" >> "$PHP_INI_DIR/conf.d/opcache.ini" \
    && echo "opcache.max_accelerated_files=20000" >> "$PHP_INI_DIR/conf.d/opcache.ini" \
    && echo "opcache.validate_timestamps=0" >> "$PHP_INI_DIR/conf.d/opcache.ini" \
    && echo "realpath_cache_size=4096K" >> "$PHP_INI_DIR/conf.d/opcache.ini" \
    && echo "realpath_cache_ttl=600" >> "$PHP_INI_DIR/conf.d/opcache.ini"

# =============================================================================
# Development stage
# =============================================================================
FROM base AS dev

# Install gosu for proper user switching
ENV GOSU_VERSION=1.17
RUN set -eux; \
    apk add --no-cache --virtual .gosu-deps dpkg gnupg; \
    dpkgArch="$(dpkg --print-architecture | awk -F- '{ print $NF }')"; \
    wget -O /usr/local/bin/gosu "https://github.com/tianon/gosu/releases/download/$GOSU_VERSION/gosu-$dpkgArch"; \
    chmod +x /usr/local/bin/gosu; \
    gosu --version; \
    gosu nobody true; \
    apk del --no-network .gosu-deps

# Enable opcache revalidation for dev (zz- prefix loads last alphabetically)
RUN echo "opcache.validate_timestamps=1" >> "$PHP_INI_DIR/conf.d/zz-opcache-dev.ini"

# Enable Xdebug for development
RUN pecl install xdebug && docker-php-ext-enable xdebug
RUN echo "xdebug.mode=develop,debug,coverage" >> "$PHP_INI_DIR/conf.d/xdebug.ini" \
    && echo "xdebug.client_host=host.docker.internal" >> "$PHP_INI_DIR/conf.d/xdebug.ini" \
    && echo "xdebug.start_with_request=trigger" >> "$PHP_INI_DIR/conf.d/xdebug.ini"

# Caddy config for FrankenPHP
ENV SERVER_NAME=:8000
# In dev mode, we do NOT use worker mode to enable automatic file reloading
# Each request loads PHP fresh, so code changes are picked up immediately
# Worker mode is only used in production for performance
ENV FRANKENPHP_CONFIG=""

# Entrypoint: detect host UID/GID and run as matching user
# Uses gosu with UID:GID directly (no need to create user in Dockerfile)
COPY --chmod=755 <<'EOF' /usr/local/bin/docker-entrypoint.sh
#!/bin/sh
set -e

# Detect UID/GID from mounted /app directory
HOST_UID=$(stat -c %u /app)
HOST_GID=$(stat -c %g /app)

# If root owns /app, run as root (CI environment or volume not mounted)
if [ "$HOST_UID" = "0" ]; then
    # Install dependencies if not present
    if [ ! -f /app/vendor/autoload.php ]; then
        echo "Installing Composer dependencies..."
        composer install --prefer-dist --no-progress --no-interaction
    fi
    mkdir -p /app/var/cache /app/var/log
    exec "$@"
fi

# Ensure directories exist with correct ownership
mkdir -p /app/var/cache /app/var/log /data /config
chown -R "$HOST_UID:$HOST_GID" /app/var /data /config 2>/dev/null || true

# Install Composer dependencies if not present (as host user)
if [ ! -f /app/vendor/autoload.php ]; then
    echo "Installing Composer dependencies..."
    gosu "$HOST_UID:$HOST_GID" composer install --prefer-dist --no-progress --no-interaction
fi

# Run command as host user via gosu (using UID:GID directly)
exec gosu "$HOST_UID:$HOST_GID" "$@"
EOF

EXPOSE 8000

ENTRYPOINT ["/usr/local/bin/docker-entrypoint.sh"]
CMD ["frankenphp", "run", "--config", "/etc/caddy/Caddyfile"]

# =============================================================================
# Production stage
# =============================================================================
FROM base AS prod

ENV APP_ENV=prod
ENV SERVER_NAME=:8000
ENV FRANKENPHP_CONFIG="worker ./public/index.php"

# Copy application files
COPY . /app

# Install dependencies (prod only, optimized)
RUN composer install --no-dev --prefer-dist --no-progress --no-interaction --optimize-autoloader

# Warmup cache
RUN php bin/console cache:warmup

# Ensure var directory exists with proper permissions
RUN mkdir -p var/cache var/log && chmod -R 755 var

EXPOSE 8000

CMD ["frankenphp", "run", "--config", "/etc/caddy/Caddyfile"]
