# StemeDB API Docker Build
#
# Four-stage build using cargo-chef for efficient dependency caching:
#   chef     -> base image with cargo-chef installed
#   planner  -> generate recipe.json (cache key for deps)
#   cacher   -> compile dependencies only (cached until Cargo.lock changes)
#   builder  -> compile service binary using cached deps (FROM cacher)
#   runtime  -> minimal image: stripped binary, non-root user, no dev tools
#
# Cache behavior:
#   - Cold build:  ~15-20 min (deps + binary)
#   - Warm build (source-only change): ~2-5 min (deps cached, binary only)
#   - Dep change: full rebuild of cacher + builder (~15-20 min)

# Stage 0: Base image with cargo-chef installed
# Cached independently — only rebuilds when the chef version pin changes.
FROM rust:bookworm AS chef
RUN cargo install cargo-chef --locked
WORKDIR /app

# Stage 1: Planner — generate recipe.json from workspace manifests
# COPY . . is intentional: cargo chef prepare only reads Cargo.toml files.
# BuildKit content-addresses recipe.json, so the cacher layer stays cached
# even if this stage rebuilds due to a .rs source change.
FROM chef AS planner
COPY . .
RUN cargo chef prepare --recipe-path recipe.json

# Stage 2: Cacher — compile dependencies only
# This layer is invalidated only when Cargo.toml or Cargo.lock changes.
# protobuf-compiler is required by stemedb-rpc/build.rs (compiles sync.proto).
FROM chef AS cacher
RUN apt-get update && \
    apt-get install -y --no-install-recommends protobuf-compiler && \
    rm -rf /var/lib/apt/lists/*
COPY --from=planner /app/recipe.json recipe.json
# Proto files must be present for stemedb-rpc/build.rs to run during dep compilation
COPY crates/stemedb-rpc/proto/ crates/stemedb-rpc/proto/
RUN cargo chef cook --release --recipe-path recipe.json

# Stage 3: Builder — compile the service binary using cached deps
# Inherits compiled deps from cacher; only workspace source is compiled here.
FROM cacher AS builder
COPY . .
RUN cargo build --release -p stemedb-api -p stemedb-cluster
# Strip debug symbols before copying to runtime image
RUN strip target/release/stemedb-api target/release/stemedb-node

# Stage 4: Runtime — minimal production image
FROM debian:bookworm-slim AS runtime

RUN apt-get update && \
    apt-get install -y --no-install-recommends \
        ca-certificates \
        curl \
    && rm -rf /var/lib/apt/lists/*

# Non-root user for security
RUN useradd --system --no-create-home --shell /bin/false stemedb

COPY --from=builder /app/target/release/stemedb-api /usr/local/bin/stemedb-api
COPY --from=builder /app/target/release/stemedb-node /usr/local/bin/stemedb-node
COPY scripts/entrypoint.sh /usr/local/bin/entrypoint.sh

RUN chmod +x /usr/local/bin/entrypoint.sh && \
    mkdir -p /data/wal /data/db && chown -R stemedb:stemedb /data

USER stemedb

ENV STEMEDB_WAL_DIR=/data/wal \
    STEMEDB_DB_DIR=/data/db \
    STEMEDB_BIND_ADDR=0.0.0.0:18180 \
    RUST_LOG=stemedb_api=info,stemedb_cluster=info

EXPOSE 18180 18181 18182 18183

HEALTHCHECK --interval=5s --timeout=3s --start-period=15s --retries=3 \
    CMD curl -f http://localhost:18180/v1/health || exit 1

ENTRYPOINT ["entrypoint.sh"]
