# Use the official Node.js 20 image
FROM node:20-alpine3.20 AS base
# Check https://github.com/nodejs/docker-node/tree/b4117f9333da4138b03a546ec926ef50a31506c3#nodealpine to understand why libc6-compat might be needed.
RUN apk add bash && apk add --no-cache libc6-compat wget coreutils
COPY ./infrastructure/docker/common/wait-for-it.sh /usr/local/bin/wait-for-it
COPY ./infrastructure/docker/common/docker-entrypoint.sh /usr/local/bin/docker-entrypoint.sh
RUN chmod +x /usr/local/bin/wait-for-it
RUN chmod +x /usr/local/bin/docker-entrypoint.sh
# Install pnpm
RUN npm install -g pnpm

# Install dependencies only when needed
FROM base AS deps
# Check https://github.com/nodejs/docker-node/tree/b4117f9333da4138b03a546ec926ef50a31506c3#nodealpine to understand why libc6-compat might be needed.
WORKDIR /app

# Install dependencies based on the preferred package manager
COPY package.json pnpm-lock.yaml ./
RUN pnpm install --frozen-lockfile --prod --dangerously-allow-all-builds

# Rebuild the source code only when needed
FROM base AS builder
WORKDIR /app

COPY --from=deps /app/node_modules ./node_modules
COPY package.json pnpm-lock.yaml ./
# Install all dependencies (including devDependencies) for building
RUN pnpm install --frozen-lockfile --dangerously-allow-all-builds
COPY . .

# Accept build arguments
ARG BETTER_AUTH_SECRET
ARG BETTER_AUTH_URL
ARG BETTER_AUTH_EMAIL
ARG NEXT_PUBLIC_APP_URL

# Environment variables for build process
ENV NEXT_TELEMETRY_DISABLED 1

# Set environment variables for build (will be overridden at runtime)
ENV DATABASE_URL=postgresql://dummy:dummy@dummy:5432/dummy
ENV BETTER_AUTH_SECRET=${BETTER_AUTH_SECRET:-buildpwwyux6f6i3xljxn6fzkl4wcd31}
ENV BETTER_AUTH_URL=${BETTER_AUTH_URL:-http://localhost:3000}
ENV BETTER_AUTH_EMAIL=${BETTER_AUTH_EMAIL:-build@example.com}
ENV NEXT_PUBLIC_APP_URL=${NEXT_PUBLIC_APP_URL:-http://localhost:3000}

# Ensure BETTER_AUTH_SECRET is set for build
RUN if [ -z "$BETTER_AUTH_SECRET" ]; then echo "ERROR: BETTER_AUTH_SECRET is not set" && exit 1; fi

# Build the application
# Use pnpm to run next build directly since we set environment variables above
RUN pnpm exec next build

# Production image, copy all the files and run next
FROM base AS runner
WORKDIR /app

ENV NODE_ENV production
ENV NEXT_TELEMETRY_DISABLED 1

RUN addgroup --system --gid 1001 nodejs
RUN adduser --system --uid 1001 nextjs

# Automatically leverage output traces to reduce image size
# https://nextjs.org/docs/advanced-features/output-file-tracing
COPY --from=builder --chown=nextjs:nodejs /app/.next/standalone ./
COPY --from=builder --chown=nextjs:nodejs /app/public ./public
COPY --from=builder --chown=nextjs:nodejs /app/.next/static ./.next/static

# Copy migration files and package.json for migrations
COPY --from=builder --chown=nextjs:nodejs /app/drizzle ./drizzle
COPY --from=builder --chown=nextjs:nodejs /app/package.json ./package.json
COPY --from=builder --chown=nextjs:nodejs /app/pnpm-lock.yaml ./pnpm-lock.yaml
COPY --from=builder --chown=nextjs:nodejs /app/migrate.js ./migrate.js
COPY --from=builder --chown=nextjs:nodejs /app/drizzle.config.ts ./drizzle.config.ts

# Copy source files needed for migrations
COPY --from=builder --chown=nextjs:nodejs /app/src/lib/database ./src/lib/database

# Install pnpm and dependencies for migrations
RUN npm install -g pnpm
RUN pnpm install --frozen-lockfile --prod --dangerously-allow-all-builds

# Set the correct permission for prerender cache
RUN mkdir -p .next && chown nextjs:nodejs .next

# Switch to root to install wait-for-it and entrypoint
USER root

# Copy wait-for-it and entrypoint scripts
COPY ./infrastructure/docker/common/wait-for-it.sh /usr/local/bin/wait-for-it
COPY ./infrastructure/docker/common/docker-entrypoint.sh /usr/local/bin/docker-entrypoint.sh
RUN chmod +x /usr/local/bin/wait-for-it
RUN chmod +x /usr/local/bin/docker-entrypoint.sh

# Switch back to nextjs user
USER nextjs

EXPOSE 3000

ENV PORT ${APP_PORT:-3000}
ENV HOSTNAME ${APP_HOST:-0.0.0.0}

# Use entrypoint script for migrations and then start the application
ENTRYPOINT ["/usr/local/bin/docker-entrypoint.sh"]
CMD ["node", "server.js"]
