# TimeSafari Docker Build
# Author: Matthew Raymer
# Description: Multi-stage Docker build for TimeSafari web application
# 
# Build Process:
# 1. Base stage: Node.js with build dependencies
# 2. Builder stage: Compile web assets with Vite
# 3. Production stage: Nginx server with optimized assets
#
# Security Features:
# - Non-root user execution
# - Minimal attack surface with Alpine Linux
# - Multi-stage build to reduce image size
# - No build dependencies in final image
#
# Usage:
#   Production: docker build -t timesafari:latest .
#   Staging: docker build --build-arg BUILD_MODE=staging -t timesafari:staging .
#   Development: docker build --build-arg BUILD_MODE=development -t timesafari:dev .
#
# Build Arguments:
#   BUILD_MODE: development, staging, or production (default: production)
#   NODE_ENV: node environment (default: production)
#   VITE_PLATFORM: vite platform (default: web)
#   VITE_PWA_ENABLED: enable PWA (default: true)
#   VITE_DISABLE_PWA: disable PWA (default: false)
#
# Environment Variables:
#   NODE_ENV: Build environment (development/production)
#   VITE_APP_SERVER: Application server URL
#   VITE_DEFAULT_ENDORSER_API_SERVER: Endorser API server URL
#   VITE_DEFAULT_IMAGE_API_SERVER: Image API server URL
#   VITE_DEFAULT_PARTNER_API_SERVER: Partner API server URL
#   VITE_DEFAULT_PUSH_SERVER: Push notification server URL
#   VITE_PASSKEYS_ENABLED: Enable passkeys feature

# =============================================================================
# BASE STAGE - Common dependencies and setup
# =============================================================================
FROM node:22-alpine3.20 AS base

# Install system dependencies for build process
RUN apk add --no-cache \
    bash \
    git \
    python3 \
    py3-pip \
    py3-setuptools \
    make \
    g++ \
    gcc \
    && rm -rf /var/cache/apk/*

# Create non-root user for security
RUN addgroup -g 1001 -S nodejs && \
    adduser -S nextjs -u 1001

# Set working directory
WORKDIR /app

# Copy package files for dependency installation
COPY package*.json ./

# Install dependencies with security audit
RUN npm ci --only=production --audit --fund=false && \
    npm audit fix --audit-level=moderate || true

# =============================================================================
# BUILDER STAGE - Compile web assets
# =============================================================================
FROM base AS builder

# Define build arguments with defaults
ARG BUILD_MODE=production
ARG NODE_ENV=production
ARG VITE_PLATFORM=web
ARG VITE_PWA_ENABLED=true
ARG VITE_DISABLE_PWA=false

# Set environment variables from build arguments
ENV BUILD_MODE=${BUILD_MODE}
ENV NODE_ENV=${NODE_ENV}
ENV VITE_PLATFORM=${VITE_PLATFORM}
ENV VITE_PWA_ENABLED=${VITE_PWA_ENABLED}
ENV VITE_DISABLE_PWA=${VITE_DISABLE_PWA}

# Install all dependencies (including dev dependencies)
RUN npm ci --audit --fund=false && \
    npm audit fix --audit-level=moderate || true

# Copy source code
COPY . .

# Build the application with proper error handling
RUN echo "Building TimeSafari in ${BUILD_MODE} mode..." && \
    npm run build:web || (echo "Build failed. Check the logs above." && exit 1)

# Verify build output exists
RUN ls -la dist/ || (echo "Build output not found in dist/ directory" && exit 1)

# =============================================================================
# PRODUCTION STAGE - Nginx server
# =============================================================================
FROM nginx:alpine AS production

# Define build arguments for production stage
ARG BUILD_MODE=production
ARG NODE_ENV=production

# Set environment variables
ENV BUILD_MODE=${BUILD_MODE}
ENV NODE_ENV=${NODE_ENV}

# Install security updates and clean cache
RUN apk update && \
    apk upgrade && \
    apk add --no-cache \
    curl \
    && rm -rf /var/cache/apk/*

# Create non-root user for nginx
RUN addgroup -g 1001 -S nginx && \
    adduser -S nginx -u 1001 -G nginx

# Copy appropriate nginx configuration based on build mode
COPY docker/nginx.conf /etc/nginx/nginx.conf
COPY docker/default.conf /etc/nginx/conf.d/default.conf

# Copy staging configuration if needed
COPY docker/staging.conf /etc/nginx/conf.d/staging.conf

# Copy built assets from builder stage
COPY --from=builder --chown=nginx:nginx /app/dist /usr/share/nginx/html

# Create necessary directories with proper permissions
RUN mkdir -p /var/cache/nginx /var/log/nginx /var/run && \
    chown -R nginx:nginx /var/cache/nginx /var/log/nginx /var/run && \
    chown -R nginx:nginx /usr/share/nginx/html

# Switch to non-root user
USER nginx

# Expose port 80
EXPOSE 80

# Health check
HEALTHCHECK --interval=30s --timeout=3s --start-period=5s --retries=3 \
    CMD curl -f http://localhost/ || exit 1

# Start nginx with proper signal handling
CMD ["nginx", "-g", "daemon off;"]

# =============================================================================
# DEVELOPMENT STAGE - For development with hot reloading
# =============================================================================
FROM base AS development

# Define build arguments for development stage
ARG BUILD_MODE=development
ARG NODE_ENV=development
ARG VITE_PLATFORM=web
ARG VITE_PWA_ENABLED=true
ARG VITE_DISABLE_PWA=false

# Set environment variables
ENV BUILD_MODE=${BUILD_MODE}
ENV NODE_ENV=${NODE_ENV}
ENV VITE_PLATFORM=${VITE_PLATFORM}
ENV VITE_PWA_ENABLED=${VITE_PWA_ENABLED}
ENV VITE_DISABLE_PWA=${VITE_DISABLE_PWA}

# Install all dependencies including dev dependencies
RUN npm ci --audit --fund=false && \
    npm audit fix --audit-level=moderate || true

# Copy source code
COPY . .

# Expose development port
EXPOSE 5173

# Start development server
CMD ["npm", "run", "dev", "--", "--host", "0.0.0.0"]

# =============================================================================
# STAGING STAGE - For staging environment testing
# =============================================================================
FROM production AS staging

# Define build arguments for staging stage
ARG BUILD_MODE=staging
ARG NODE_ENV=staging

# Set environment variables
ENV BUILD_MODE=${BUILD_MODE}
ENV NODE_ENV=${NODE_ENV}

# Copy staging-specific nginx configuration
COPY docker/staging.conf /etc/nginx/conf.d/default.conf

# Expose port 80
EXPOSE 80

# Health check for staging
HEALTHCHECK --interval=30s --timeout=3s --start-period=5s --retries=3 \
    CMD curl -f http://localhost/health || exit 1

# Start nginx
CMD ["nginx", "-g", "daemon off;"] 