# Multi-stage Dockerfile for sirius-ui with development and production stages
#
# system-monitor and administrator are built in this file (no external GHCR base image).

# ─────────────────────────────────────────────────────────────────────────────
# Utility binaries: system-monitor + administrator
# ─────────────────────────────────────────────────────────────────────────────
FROM golang:1.24-alpine AS utility-go-binaries

RUN apk add --no-cache git ca-certificates tzdata

RUN git clone https://github.com/SiriusScan/app-system-monitor.git /tmp/system-monitor && \
    cd /tmp/system-monitor && \
    go mod download && \
    CGO_ENABLED=0 GOOS=linux go build -ldflags="-w -s" -o /usr/local/bin/system-monitor main.go && \
    rm -rf /tmp/system-monitor

RUN git clone https://github.com/SiriusScan/app-administrator.git /tmp/administrator && \
    cd /tmp/administrator && \
    go mod download && \
    CGO_ENABLED=0 GOOS=linux go build -ldflags="-w -s" -o /usr/local/bin/administrator main.go && \
    rm -rf /tmp/administrator

# ─────────────────────────────────────────────────────────────────────────────
# Base stage: common Node.js dependencies
# ─────────────────────────────────────────────────────────────────────────────
FROM node:18-alpine AS base

# Install system and native build dependencies for all architectures.
# bcrypt may fall back to node-gyp compilation (notably on arm64/musl), which
# requires Python + make + g++ at install time.
RUN apk add --no-cache \
    libc6-compat \
    openssl \
    ca-certificates \
    git \
    python3 \
    make \
    g++

WORKDIR /app

# Copy package files
COPY package*.json ./
COPY bun.lockb* ./

# Replace bun commands with npm/npx equivalents for compatibility
COPY package.json package.json.bak
RUN sed -i 's/bunx prisma generate/npx prisma generate/g' package.json && \
    sed -i 's/bun next/npx next/g' package.json && \
    sed -i 's/bun run/npm run/g' package.json

# Clone sirius-nse repository for NSE scripts (needed by scanner profile management)
ARG SIRIUS_NSE_COMMIT_SHA=main
RUN mkdir -p /sirius-nse && \
    git clone https://github.com/SiriusScan/sirius-nse.git /sirius-nse && \
    cd /sirius-nse && \
    git checkout ${SIRIUS_NSE_COMMIT_SHA} && \
    echo "Cloned sirius-nse ($(git rev-parse --short HEAD))"

# ─────────────────────────────────────────────────────────────────────────────
# Development stage
# ─────────────────────────────────────────────────────────────────────────────
FROM base AS development

# Non-root user: chown /app while it is still small (package files only from base).
# Avoids chown -R over node_modules after npm install (very slow on Docker Desktop).
RUN addgroup --system --gid 1001 nodejs && \
    adduser --system --uid 1001 nextjs && \
    chown -R nextjs:nodejs /app

ENV NPM_CONFIG_CACHE=/app/.npm-cache

EXPOSE 3000

ENV NODE_ENV=development
ENV NEXT_TELEMETRY_DISABLED=1

USER nextjs

RUN npm install

COPY --chown=nextjs:nodejs . .

RUN npx prisma generate

# Ensure image start-dev.sh wins over build context and has unix line endings.
USER root
COPY start-dev.sh /app/start-dev.sh
RUN sed -i 's/\r$//' /app/start-dev.sh && chmod +x /app/start-dev.sh && \
    chown nextjs:nodejs /app/start-dev.sh

USER nextjs

CMD ["/bin/sh", "/app/start-dev.sh"]

# ─────────────────────────────────────────────────────────────────────────────
# Builder stage: compile Next.js application
# ─────────────────────────────────────────────────────────────────────────────
FROM base AS builder

ARG NEXT_PUBLIC_CLIENTVAR

COPY . .

# Remove .env files that interfere with Docker environment variables
RUN rm -f .env .env.local .env.development .env.production

# Install dependencies (production + dev for building)
RUN npm install

# Generate Prisma client
RUN npx prisma generate

ENV NEXT_TELEMETRY_DISABLED=1
ENV NEXT_PUBLIC_CLIENTVAR=${NEXT_PUBLIC_CLIENTVAR}
ENV SKIP_ENV_VALIDATION=1
ENV SIRIUS_BUILD_STAGE=docker-build

# Inject ignoreBuildErrors flags for Docker build so TS/ESLint errors don't block
RUN cp next.config.mjs next.config.mjs.bak && \
    node -e "const fs=require('fs');const p='next.config.mjs';let c=fs.readFileSync(p,'utf8');c=c.replace('  swcMinify: true,','  swcMinify: true,\n  typescript: { ignoreBuildErrors: true },\n  eslint: { ignoreDuringBuilds: true },');fs.writeFileSync(p,c);" && \
    npx next build

# ─────────────────────────────────────────────────────────────────────────────
# Production runtime stage
# ─────────────────────────────────────────────────────────────────────────────
FROM node:18-alpine AS production

RUN apk add --no-cache \
    libc6-compat \
    openssl \
    ca-certificates

# Non-root user
RUN addgroup --system --gid 1001 nodejs && \
    adduser --system --uid 1001 nextjs

WORKDIR /app

# Create system-monitor directory
RUN mkdir -p /system-monitor

COPY --chown=nextjs:nodejs --from=utility-go-binaries /usr/local/bin/system-monitor /system-monitor/system-monitor
COPY --chown=nextjs:nodejs --from=utility-go-binaries /usr/local/bin/administrator /app/administrator
RUN chmod +x /system-monitor/system-monitor /app/administrator

# Copy built Next.js application from builder stage (ownership set during copy — no full-tree chown)
COPY --chown=nextjs:nodejs --from=builder /app/public ./public
COPY --chown=nextjs:nodejs --from=builder /app/.next ./.next
COPY --chown=nextjs:nodejs --from=builder /app/node_modules ./node_modules
COPY --chown=nextjs:nodejs --from=builder /app/src ./src
COPY --chown=nextjs:nodejs --from=builder /app/prisma ./prisma
COPY --chown=nextjs:nodejs --from=builder /app/package.json ./package.json
COPY --chown=nextjs:nodejs --from=builder /app/next.config.mjs ./next.config.mjs

COPY --chown=nextjs:nodejs start-prod.sh /app/start-prod.sh
RUN sed -i 's/\r$//' /app/start-prod.sh && chmod +x /app/start-prod.sh

USER nextjs

EXPOSE 3000

ENV NODE_ENV=production
ENV NEXT_TELEMETRY_DISABLED=1

CMD ["/app/start-prod.sh"]
