# =============================================================================
# HostSeba NOC — production PHP-FPM image (VPS / Docker deployment)
# =============================================================================
# Multi-stage:
#   1. composer     — install vendor/ from composer.lock (cached layer)
#   2. frontend     — npm build of NOC + AI Portal SPAs (cached layer)
#   3. runtime      — slim php-fpm with the app baked in, vendor/ + public/ copied
#
# Build context = repo root (f:/antigravity/noc). docker-compose.yml sets it.
# =============================================================================


# ─────────── Stage 1: composer ───────────
FROM composer:2.7 AS composer
WORKDIR /app
# Copy only the manifests first so layer cache survives source changes
COPY backend/hostseba-noc-backend/composer.json backend/hostseba-noc-backend/composer.lock ./
RUN composer install \
        --no-dev \
        --no-interaction \
        --no-scripts \
        --optimize-autoloader \
        --classmap-authoritative \
        --prefer-dist


# ─────────── Stage 2: frontend ───────────
FROM node:20-alpine AS frontend
WORKDIR /build
# Copy both frontend packages (NOC + AI Portal). NOC's build script also
# triggers the AI Portal build (npm --prefix ../frontend-ai run build).
COPY frontend/package.json frontend/package-lock.json* ./frontend/
COPY frontend-ai/package.json frontend-ai/package-lock.json* ./frontend-ai/
RUN cd frontend && npm ci --no-audit --no-fund \
 && cd ../frontend-ai && npm ci --no-audit --no-fund

# Copy source + a stub backend public/ (so vite outDir relative path resolves)
COPY frontend ./frontend
COPY frontend-ai ./frontend-ai
RUN mkdir -p backend/hostseba-noc-backend/public

# Build NOC → public/noc/, AI Portal → public/ai/
RUN cd frontend && npm run build


# ─────────── Stage 3: runtime ───────────
FROM php:8.3-fpm-alpine AS runtime

# System deps + PHP extensions Laravel needs.
# - pdo_mysql, mysqli       : MariaDB
# - bcmath, gd              : standard Laravel deps
# - opcache                 : production perf
# - redis (PECL)            : queue + cache backend
# - sodium, openssl, mbstring, tokenizer, xml, ctype, zip, fileinfo,
#   curl, intl              : Laravel core requirements
RUN apk add --no-cache \
        bash git curl tini icu-libs libzip libpng libjpeg-turbo freetype \
        oniguruma libxml2 sqlite-libs \
 && apk add --no-cache --virtual .build-deps \
        $PHPIZE_DEPS icu-dev libzip-dev libpng-dev libjpeg-turbo-dev \
        freetype-dev oniguruma-dev libxml2-dev sqlite-dev linux-headers \
 && docker-php-ext-configure gd --with-freetype --with-jpeg \
 && docker-php-ext-install -j$(nproc) \
        pdo_mysql mysqli bcmath gd opcache pcntl intl zip \
 && pecl install redis \
 && docker-php-ext-enable redis \
 && apk del .build-deps \
 && rm -rf /tmp/* /var/cache/apk/*

# OPcache tuning — production defaults: keep all PHP files in RAM, no
# revalidation timestamps (we redeploy on code change instead).
RUN { \
        echo 'opcache.enable=1'; \
        echo 'opcache.enable_cli=0'; \
        echo 'opcache.memory_consumption=192'; \
        echo 'opcache.interned_strings_buffer=16'; \
        echo 'opcache.max_accelerated_files=20000'; \
        echo 'opcache.validate_timestamps=0'; \
        echo 'opcache.save_comments=1'; \
        echo 'opcache.fast_shutdown=1'; \
    } > /usr/local/etc/php/conf.d/opcache.ini

# PHP runtime tuning. Long-polling endpoints (/api/agent/probes/pending)
# need >30s execution time on a real VPS; we allow 60.
RUN { \
        echo 'max_execution_time=60'; \
        echo 'memory_limit=256M'; \
        echo 'post_max_size=32M'; \
        echo 'upload_max_filesize=32M'; \
        echo 'expose_php=Off'; \
    } > /usr/local/etc/php/conf.d/zz-app.ini

# App user — non-root for security, matches host UID 1000 by default so
# bind-mounted storage/logs is writable from outside the container.
ARG APP_UID=1000
ARG APP_GID=1000
RUN addgroup -g $APP_GID app \
 && adduser -D -u $APP_UID -G app app

WORKDIR /var/www/app

# Copy Laravel source (without vendor/ or public/noc public/ai — those
# come from the other stages)
COPY --chown=app:app backend/hostseba-noc-backend/ ./

# Vendor from composer stage
COPY --chown=app:app --from=composer /app/vendor ./vendor

# Built frontend SPAs from frontend stage
COPY --chown=app:app --from=frontend /build/backend/hostseba-noc-backend/public/noc ./public/noc
COPY --chown=app:app --from=frontend /build/backend/hostseba-noc-backend/public/ai ./public/ai

# Storage + cache must be writable at runtime (these are mounted as
# volumes too, but the empty dirs need to exist in the image)
RUN mkdir -p storage/framework/{cache,sessions,views,testing} \
             storage/logs \
             bootstrap/cache \
 && chown -R app:app storage bootstrap/cache \
 && chmod -R 775 storage bootstrap/cache

USER app

# php-fpm exposes 9000 internally; nginx in the sibling container talks
# to it over the compose network. Tini = signal-handling init.
EXPOSE 9000
ENTRYPOINT ["/sbin/tini", "--"]
CMD ["php-fpm", "-F"]
