# H33 Node.js Service Dockerfile
# Multi-stage build with Rust native bindings support
#
# Build: docker build -t h33-node:latest .
# Run:   docker run -p 9000:9000 --env-file .env h33-node:latest
#
# SECURITY NOTICE:
# ============================================================================
# - Production stage excludes all devDependencies
# - Rust native bindings are built with release optimizations
# - Non-root user for runtime security
# - Read-only filesystem compatible
#
# Verification:
#   docker build --target production -t h33-node:prod .
#   docker run --rm h33-node:prod npm ls elliptic  # Should be empty
#   docker run --rm h33-node:prod npm audit --omit=dev  # 0 vulnerabilities
# ============================================================================

# =============================================================================
# Stage 1: Rust Builder - Build h33-node-bindings
# =============================================================================
FROM rust:1.82-alpine AS rust-builder

# Install build dependencies for Alpine
RUN apk add --no-cache \
    musl-dev \
    openssl-dev \
    openssl-libs-static \
    pkgconfig \
    clang \
    llvm \
    cmake \
    make \
    perl \
    linux-headers \
    git

# Install Node.js for napi-rs build
RUN apk add --no-cache nodejs npm

# Set environment for static linking
ENV OPENSSL_STATIC=1
ENV OPENSSL_LIB_DIR=/usr/lib
ENV OPENSSL_INCLUDE_DIR=/usr/include

WORKDIR /build

# Copy h33-node-bindings source
COPY h33-node-bindings ./h33-node-bindings

WORKDIR /build/h33-node-bindings

# Install napi-rs CLI and build dependencies
RUN npm install

# Build the native bindings for Linux (musl)
RUN npm run build

# Verify build output exists
RUN test -f *.node && echo "Native binding built successfully" || (ls -la && exit 1)

# =============================================================================
# Stage 2: Node.js Dependencies
# =============================================================================
FROM node:20-alpine AS deps

WORKDIR /app

# Install build dependencies for native modules
RUN apk add --no-cache python3 make g++ libc6-compat

# Copy package files
COPY h33-node/package*.json ./

# Install production dependencies only
RUN npm ci --only=production --ignore-scripts && npm cache clean --force

# =============================================================================
# Stage 3: Builder
# =============================================================================
FROM node:20-alpine AS builder

WORKDIR /app

# Install build tools
RUN apk add --no-cache python3 make g++

# Copy package files
COPY h33-node/package*.json ./

# Install all dependencies (including dev for build steps)
RUN npm ci --ignore-scripts

# Copy source code
COPY h33-node/src ./src
COPY h33-node/database ./database

# Build TypeScript if applicable
RUN npm run build 2>/dev/null || echo "No TypeScript build step"

# =============================================================================
# Stage 4: Production Runtime
# =============================================================================
FROM node:20-alpine AS production

# Security: Create non-root user
RUN addgroup -g 1001 -S h33 && \
    adduser -S h33 -u 1001 -G h33

WORKDIR /app

# Install runtime dependencies and security updates
RUN apk add --no-cache \
    curl \
    dumb-init \
    ca-certificates \
    libstdc++ \
    && apk upgrade --no-cache

# Copy production dependencies from deps stage
COPY --from=deps /app/node_modules ./node_modules

# Copy h33-node-bindings from rust builder
RUN mkdir -p ./node_modules/@h33/node-bindings
COPY --from=rust-builder /build/h33-node-bindings/index.js ./node_modules/@h33/node-bindings/
COPY --from=rust-builder /build/h33-node-bindings/index.d.ts ./node_modules/@h33/node-bindings/
COPY --from=rust-builder /build/h33-node-bindings/package.json ./node_modules/@h33/node-bindings/
COPY --from=rust-builder /build/h33-node-bindings/*.node ./node_modules/@h33/node-bindings/

# Copy built application from builder stage
COPY --from=builder --chown=h33:h33 /app/src ./src
COPY --from=builder --chown=h33:h33 /app/database ./database
COPY h33-node/package.json ./

# Create necessary directories
RUN mkdir -p /app/logs /app/tmp /app/data && \
    chown -R h33:h33 /app

# Switch to non-root user
USER h33

# Expose ports
EXPOSE 9000 9001

# Health check
HEALTHCHECK --interval=30s --timeout=10s --start-period=15s --retries=3 \
    CMD curl -f http://localhost:${PORT:-9000}/health || exit 1

# Environment variables
ENV NODE_ENV=production \
    PORT=9000 \
    HOST=0.0.0.0 \
    WS_PORT=9001

# Use dumb-init to handle signals properly
ENTRYPOINT ["/usr/bin/dumb-init", "--"]

# Start the application
CMD ["node", "src/server.js"]

# =============================================================================
# Stage 5: Development
# =============================================================================
FROM node:20-alpine AS development

WORKDIR /app

# Install development tools
RUN apk add --no-cache \
    curl \
    git \
    python3 \
    make \
    g++ \
    linux-headers

# Copy package files
COPY h33-node/package*.json ./

# Install all dependencies
RUN npm ci

# Copy h33-node-bindings from rust builder (if available)
# In dev mode, we might use local bindings instead
COPY --from=rust-builder /build/h33-node-bindings/*.node ./node_modules/@h33/node-bindings/ 2>/dev/null || true
COPY --from=rust-builder /build/h33-node-bindings/index.js ./node_modules/@h33/node-bindings/ 2>/dev/null || true
COPY --from=rust-builder /build/h33-node-bindings/index.d.ts ./node_modules/@h33/node-bindings/ 2>/dev/null || true
COPY --from=rust-builder /build/h33-node-bindings/package.json ./node_modules/@h33/node-bindings/ 2>/dev/null || true

# Copy source code
COPY h33-node/ .

# Expose ports (including debug port)
EXPOSE 9000 9001 9229

# Environment
ENV NODE_ENV=development \
    PORT=9000 \
    HOST=0.0.0.0 \
    WS_PORT=9001

# Start with nodemon for hot reload
CMD ["npm", "run", "dev"]
