###############################################################################
# EspoCRM - Minimal Secure Build from Source
# Multi-stage build with Alpine base images
###############################################################################

# Stage 1: Build frontend assets
FROM node:20-alpine AS frontend
WORKDIR /build
COPY package.json package-lock.json ./
RUN npm ci --ignore-scripts
COPY . .
RUN npx grunt

# Stage 2: Install PHP dependencies
FROM composer:2 AS composer
WORKDIR /build
COPY composer.json composer.lock ./
COPY dev/ ./dev/
RUN composer install \
    --no-dev \
    --no-interaction \
    --no-progress \
    --prefer-dist \
    --optimize-autoloader \
    --ignore-platform-reqs

# Stage 3: Minimal runtime
FROM php:8.4-fpm-alpine

RUN set -ex; \
    apk add --no-cache \
        nginx \
        freetype \
        libjpeg-turbo \
        libwebp \
        libpng \
        libzip \
        libpq \
        libldap \
        icu-libs \
        unzip \
    ; \
    apk add --no-cache --virtual .build-deps \
        freetype-dev \
        libjpeg-turbo-dev \
        libwebp-dev \
        libpng-dev \
        libzip-dev \
        postgresql-dev \
        openldap-dev \
        icu-dev \
    ; \
    docker-php-ext-configure gd \
        --with-freetype --with-jpeg --with-webp \
    ; \
    docker-php-ext-install -j$(nproc) \
        gd pdo_mysql pdo_pgsql zip ldap \
        exif pcntl posix bcmath intl \
    ; \
    apk del .build-deps; \
    rm -rf /tmp/* /var/cache/apk/*

# PHP hardened config
RUN { \
    echo 'expose_php = Off'; \
    echo 'display_errors = Off'; \
    echo 'display_startup_errors = Off'; \
    echo 'log_errors = On'; \
    echo 'memory_limit = 256M'; \
    echo 'max_execution_time = 180'; \
    echo 'max_input_time = 180'; \
    echo 'post_max_size = 50M'; \
    echo 'upload_max_filesize = 50M'; \
    echo 'session.cookie_httponly = 1'; \
    echo 'session.cookie_secure = 1'; \
    echo 'session.use_strict_mode = 1'; \
} > "$PHP_INI_DIR/conf.d/espocrm.ini"

# Nginx config
RUN cat > /etc/nginx/http.d/default.conf <<'NGINX'
server {
    listen 80;
    server_name _;
    root /var/www/html;
    index index.php index.html;

    server_tokens off;
    add_header X-Content-Type-Options "nosniff" always;
    add_header X-Frame-Options "SAMEORIGIN" always;
    add_header X-XSS-Protection "1; mode=block" always;
    add_header Referrer-Policy "same-origin" always;

    client_max_body_size 50M;

    location / {
        try_files $uri $uri/ /index.php?$query_string;
    }

    location ~ \.php$ {
        fastcgi_pass 127.0.0.1:9000;
        fastcgi_index index.php;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
        include fastcgi_params;
        fastcgi_read_timeout 180;
    }

    location ~ /\. { deny all; }
    location ~ ^/(data|application|custom|vendor)/ { deny all; }
    location = /data/config.php { deny all; }
}
NGINX

WORKDIR /var/www/html

# Copy application
COPY --chown=82:82 . .
COPY --chown=82:82 --from=composer /build/vendor ./vendor
COPY --chown=82:82 --from=frontend /build/client ./client

# Remove dev/build files
RUN rm -rf node_modules .git .github tests dev \
    Gruntfile.js package.json package-lock.json \
    phpstan.neon phpunit.xml .idea .vscode \
    .editorconfig .gitattributes .gitignore .npmrc \
    diff.js lang.js po.js jsconfig.json

# Set permissions
RUN set -ex; \
    find . -type d -exec chmod 755 {} +; \
    find . -type f -exec chmod 644 {} +; \
    chmod 754 bin/command 2>/dev/null || true; \
    for dir in data custom client/custom; do \
        mkdir -p "$dir"; \
        chown -R 82:82 "$dir"; \
    done

# Entrypoint
COPY --chmod=755 <<'EOF' /entrypoint.sh
#!/bin/sh
set -e

if [ -n "$ESPOCRM_DATABASE_HOST" ] && [ ! -f "data/config.php" ]; then
    echo "Waiting for database..."
    i=0
    while [ $i -lt 30 ]; do
        if php -r "new PDO('mysql:host=${ESPOCRM_DATABASE_HOST};port=${ESPOCRM_DATABASE_PORT:-3306}','${ESPOCRM_DATABASE_USER:-root}','${ESPOCRM_DATABASE_PASSWORD}');" 2>/dev/null; then
            echo "Database ready. Running installer..."
            php bin/command install \
                --databasePlatform="${ESPOCRM_DATABASE_PLATFORM:-Mysql}" \
                --databaseHost="$ESPOCRM_DATABASE_HOST" \
                --databasePort="${ESPOCRM_DATABASE_PORT:-3306}" \
                --databaseName="${ESPOCRM_DATABASE_NAME:-espocrm}" \
                --databaseUser="${ESPOCRM_DATABASE_USER:-root}" \
                --databasePassword="$ESPOCRM_DATABASE_PASSWORD" \
                --adminUsername="${ESPOCRM_ADMIN_USERNAME:-admin}" \
                --adminPassword="${ESPOCRM_ADMIN_PASSWORD:-admin}" \
                --siteUrl="${ESPOCRM_SITE_URL:-http://localhost}" \
            && echo "Install complete." \
            || echo "CLI install failed. Use web installer."
            break
        fi
        i=$((i + 1))
        sleep 2
    done
fi

php-fpm -D
exec nginx -g 'daemon off;'
EOF

VOLUME /var/www/html/data
EXPOSE 80

ENTRYPOINT ["/entrypoint.sh"]
