# ============================================================================
# STAGE 1: Build Frontend (React 18 + Bun)
# ============================================================================
# This stage builds the React SPA with TypeScript, Tailwind CSS, and Vite
# Output: frontend/dist/ with optimized static assets
# ============================================================================
FROM oven/bun:latest AS frontend-builder

WORKDIR /app/frontend

# Copy frontend source
COPY frontend/ .

# Install dependencies and build frontend
# - bun install: Fast package installation
# - bun run build: TypeScript type check + Vite optimization
RUN bun install && \
    bun run build

# Verify build output exists
RUN test -f dist/index.html || (echo "Frontend build failed!" && exit 1)

# ============================================================================
# STAGE 2: Build Backend (Go 1.25) with embedded frontend
# ============================================================================
# This stage builds the Go server with the React SPA embedded
# Uses Go's embed package to include all static assets
# Output: filebrowser binary (statically linked, no dependencies)
# ============================================================================
FROM golang:1.25-alpine AS backend-builder

WORKDIR /app

# Install build dependencies
RUN apk add --no-cache git ca-certificates

# Copy the entire project
COPY . .

# Copy built frontend from stage 1 into the frontend Go package
# The frontend/frontend.go file uses //go:embed dist to include these files
COPY --from=frontend-builder /app/frontend/dist ./frontend/dist

# Download Go dependencies
RUN go mod download

# Build the Go binary with embedded frontend
# - CGO_ENABLED=0: Static linking (no libc dependency)
# - GOOS=linux: Linux target
# - GOARCH=amd64: 64-bit x86 architecture
# - The frontend/dist directory is embedded via the //go:embed directive
RUN CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -o filebrowser .

# Verify binary was created and contains embedded assets
RUN test -f filebrowser || (echo "Go build failed!" && exit 1) && \
    strings filebrowser | grep -q "index.html" || (echo "Frontend not embedded!" && exit 1)

# ============================================================================
# STAGE 3: Fetch dependencies and base tools
# ============================================================================
FROM alpine:3.23 AS fetcher

# install and copy ca-certificates, mailcap, and tini-static; download JSON.sh
RUN apk update && \
    apk --no-cache add ca-certificates mailcap tini-static && \
    wget -O /JSON.sh https://raw.githubusercontent.com/dominictarr/JSON.sh/0d5e5c77365f63809bf6e77ef44a1f34b0e05840/JSON.sh

# ============================================================================
# STAGE 4: Final Runtime Image (Minimal)
# ============================================================================
# Lightweight runtime using busybox (~50MB total image size)
# Only includes the compiled binary and essential runtime dependencies
# ============================================================================
FROM busybox:1.37.0-musl

# Define non-root user UID and GID for security
ENV UID=1000
ENV GID=1000

# Create unprivileged user and group
RUN addgroup -g $GID user && \
    adduser -D -u $UID -G user user

# Copy compiled binary from backend builder
# The binary includes the React SPA (frontend/dist) via Go's embed package
COPY --chown=user:user --from=backend-builder /app/filebrowser /bin/filebrowser

# Copy initialization and configuration scripts
COPY --chown=user:user docker/common/ /
COPY --chown=user:user docker/alpine/ /

# Copy runtime dependencies from fetcher stage
COPY --chown=user:user --from=fetcher /sbin/tini-static /bin/tini
COPY --from=fetcher /JSON.sh /JSON.sh
COPY --from=fetcher /etc/ca-certificates.conf /etc/ca-certificates.conf
COPY --from=fetcher /etc/ca-certificates /etc/ca-certificates
COPY --from=fetcher /etc/mime.types /etc/mime.types
COPY --from=fetcher /etc/ssl /etc/ssl

# Create persistent data directories with proper ownership
RUN mkdir -p /config /database /srv && \
    chown -R user:user /config /database /srv && \
    chmod +x /healthcheck.sh /init.sh

# Health check configuration
# Verifies the frontend is being served correctly
HEALTHCHECK --start-period=2s --interval=5s --timeout=3s CMD /healthcheck.sh

# Run as non-root user
USER user

# Define persistent volumes
# /srv: User file storage
# /config: Configuration files
# /database: SQLite database
VOLUME /srv /config /database

# Expose port 80 (internal server runs on 8080, init.sh proxies if needed)
EXPOSE 80

# Use tini as init process for proper signal handling
# Then run init.sh which starts the filebrowser binary
ENTRYPOINT [ "tini", "--", "/init.sh" ]
