# =============================================================================
# FLORIAN — Mehrstufiger Build.
#   deps    : Abhängigkeiten installieren (wird gecacht)
#   builder : Prisma-Client erzeugen, Next.js bauen, Worker transpilieren
#   runner  : schlankes Laufzeit-Image, non-root, mit Healthcheck
# =============================================================================

ARG NODE_VERSION=22.20.0

# -----------------------------------------------------------------------------
# Stufe 1: Abhängigkeiten
# -----------------------------------------------------------------------------
FROM node:${NODE_VERSION}-bookworm-slim AS deps
WORKDIR /app

# openssl wird von Prisma benötigt, ca-certificates für ausgehendes TLS.
RUN apt-get update \
    && apt-get install -y --no-install-recommends openssl ca-certificates \
    && rm -rf /var/lib/apt/lists/*

ENV NEXT_TELEMETRY_DISABLED=1
COPY package.json package-lock.json* .npmrc ./
RUN npm ci --include=dev

# -----------------------------------------------------------------------------
# Stufe 2: Build
# -----------------------------------------------------------------------------
FROM node:${NODE_VERSION}-bookworm-slim AS builder
WORKDIR /app

RUN apt-get update \
    && apt-get install -y --no-install-recommends openssl ca-certificates \
    && rm -rf /var/lib/apt/lists/*

ENV NEXT_TELEMETRY_DISABLED=1
ENV NODE_ENV=production

COPY --from=deps /app/node_modules ./node_modules
COPY . .

# Prisma-Client aus dem Schema erzeugen — ohne Datenbankverbindung.
RUN npx prisma generate

# Der Next.js-Build braucht formal gültige Variablen, verbindet sich aber nicht.
# Die echten Werte kommen zur Laufzeit aus der Umgebung.
RUN DATABASE_URL="postgresql://build:build@localhost:5432/build?schema=public" \
    DIRECT_DATABASE_URL="postgresql://build:build@localhost:5432/build?schema=public" \
    AUTH_SECRET="build_time_platzhalter_mindestens_32_zeichen" \
    KIOSK_DEVICE_SECRET="build_time_platzhalter" \
    SKIP_ENV_VALIDATION=1 \
    npm run build

# Worker separat nach CommonJS transpilieren, damit im Runtime-Image kein
# TypeScript-Toolchain mehr nötig ist.
RUN npx esbuild src/worker/index.ts \
    --bundle \
    --platform=node \
    --target=node22 \
    --format=cjs \
    --packages=external \
    --sourcemap \
    --outfile=dist/worker/index.js

# -----------------------------------------------------------------------------
# Stufe 3: Laufzeit
# -----------------------------------------------------------------------------
FROM node:${NODE_VERSION}-bookworm-slim AS runner
WORKDIR /app

RUN apt-get update \
    && apt-get install -y --no-install-recommends openssl ca-certificates tini \
    && rm -rf /var/lib/apt/lists/*

ENV NODE_ENV=production
ENV NEXT_TELEMETRY_DISABLED=1
ENV PORT=3000
ENV HOSTNAME=0.0.0.0
ENV TZ=Europe/Berlin

# Eigener, unprivilegierter Benutzer. Läuft NICHT als root.
RUN groupadd --system --gid 1001 florian \
    && useradd --system --uid 1001 --gid florian --home /app --shell /usr/sbin/nologin florian

# Standalone-Ausgabe von Next.js: enthält nur die tatsächlich benötigten Module.
COPY --from=builder --chown=florian:florian /app/.next/standalone ./
COPY --from=builder --chown=florian:florian /app/.next/static ./.next/static
COPY --from=builder --chown=florian:florian /app/public ./public

# Worker-Bundle und dessen Laufzeitabhängigkeiten.
COPY --from=builder --chown=florian:florian /app/dist ./dist

# Prisma: Schema und Migrationen fürs Deployment, plus erzeugter Client.
COPY --from=builder --chown=florian:florian /app/prisma ./prisma
COPY --from=builder --chown=florian:florian /app/node_modules/.prisma ./node_modules/.prisma
COPY --from=builder --chown=florian:florian /app/node_modules/@prisma ./node_modules/@prisma
COPY --from=builder --chown=florian:florian /app/node_modules/prisma ./node_modules/prisma

COPY --chown=florian:florian docker/entrypoint.sh /usr/local/bin/entrypoint.sh
COPY --chown=florian:florian docker/healthcheck.js /app/healthcheck.js
RUN chmod +x /usr/local/bin/entrypoint.sh

USER florian
EXPOSE 3000

# Prüft den Endpunkt /api/health — der fragt Datenbank und Redis mit ab.
HEALTHCHECK --interval=30s --timeout=5s --start-period=40s --retries=3 \
    CMD node /app/healthcheck.js || exit 1

# tini als PID 1, damit Signale sauber durchgereicht werden.
ENTRYPOINT ["/usr/bin/tini", "--", "/usr/local/bin/entrypoint.sh"]
CMD ["node", "server.js"]
