# Nextcraft — single-port docker image (v0.8 P2, REQ-8-002, R-16..R-19)
#
# Topology: uvicorn :8420 serves BOTH the API (/v1/*, /health) and the
# exported web UI (everything else) — the same single-port production
# shape as `nextcraft deploy` (D-039). Deps are pre-loaded in image
# layers; runtime is unprivileged by default (honest sandbox degrade:
# ai_service/sandbox/capability.py probes + api/sandboxes.py 503s with
# remediation — D-068/G-208).
#
# Build context is the repo root. Build args:
#   NEXTCRAFT_VERSION  — stamped into the embedded CLI (`--version`)
#
# Stages:
#   1. web-export — node:24-bookworm: pnpm workspace install, static
#      export (NEXT_PUBLIC_AI_SERVICE_URL=self), SEA CLI binary build
#   2. venv — python:3.11-bookworm: production deps only (no [dev])
#   3. runtime — python:3.11-slim-bookworm: non-root, venv + package +
#      export + CLI, /health healthcheck, state volume

# -- stage 1: web export + CLI binary ---------------------------------------
FROM node:24-bookworm AS web-export
ARG NEXTCRAFT_VERSION=0.0.0-dev
WORKDIR /repo

# Toolchain: corepack ships with node 24 (deprecated but present).
RUN corepack enable pnpm

# Workspace manifests first (layer-cacheable install).
COPY package.json pnpm-workspace.yaml pnpm-lock.yaml .npmrc tsconfig.json ./
COPY apps/web/package.json apps/web/
COPY apps/cli/package.json apps/cli/
COPY packages/types/package.json packages/types/
COPY packages/ui/package.json packages/ui/
COPY packages/mock-data/package.json packages/mock-data/
RUN pnpm install --frozen-lockfile

# Sources (web build needs all workspaces; CLI build needs its tree).
COPY apps ./apps
COPY packages ./packages

# Static export (same command as the deploy path): the export lands in
# apps/web/out and is served same-origin by uvicorn.
ENV NEXT_PUBLIC_AI_SERVICE_URL=self
RUN pnpm --filter web build

# Embedded CLI (D-066): doctor/verify/guide work in-container; the daemon
# commands refuse honestly (see apps/cli/src — NC_CONTAINER detection).
RUN pnpm --filter @nextcraft/cli build:binary "$NEXTCRAFT_VERSION"

# -- stage 2: python venv ----------------------------------------------------
FROM python:3.11-bookworm AS venv
WORKDIR /repo
# The full source tree installs the package (bootstrap.sh's mechanism
# without [dev]: production deps only — the image runs the app, it never
# lints/tests it; the runner lanes own that).
COPY apps/ai-service /repo/apps/ai-service
RUN python3 -m venv /opt/venv && \
    /opt/venv/bin/pip install --no-cache-dir --upgrade pip && \
    /opt/venv/bin/pip install --no-cache-dir /repo/apps/ai-service

# -- stage 3: runtime --------------------------------------------------------
FROM python:3.11-slim-bookworm AS runtime
WORKDIR /opt/nextcraft

# Non-root user; home carries the state volume (~/.nextcraft semantics —
# config.py anchors db/sandboxes under $HOME/.nextcraft, R-17).
RUN useradd --create-home --uid 10001 nextcraft

# venv from stage 2 (production deps only).
COPY --from=venv /opt/venv /opt/venv
ENV PATH=/opt/venv/bin:$PATH

# The installed ai_service package is IN the venv's site-packages; the
# source tree rides along for transparency (PYTHONPATH prefers the
# installed package).
COPY --from=venv /repo/apps/ai-service /opt/nextcraft/ai-service-src
RUN rm -rf /opt/nextcraft/ai-service-src/.venv

# Web export from stage 1.
COPY --from=web-export /repo/apps/web/out /opt/nextcraft/web-out
ENV AI_WEB_STATIC_DIR=/opt/nextcraft/web-out

# Image marker: NC_CONTAINER=1 (context for the CLI container-mode
# branches and the degrade boot notice; the capability PROBE — not this
# marker — decides degrade, D-068).
ENV NC_CONTAINER=1

# Embedded CLI (D-066).
COPY --from=web-export /repo/apps/cli/dist/nextcraft-linux-x64 /usr/local/bin/nextcraft
RUN chmod 0755 /usr/local/bin/nextcraft

# App dir + state: db/sandboxes under /home/nextcraft/.nextcraft (R-17).
# The state root is pre-created with correct ownership BEFORE the VOLUME
# declaration — an anonymous volume copies the image's directory CONTENTS
# and ownership at first use, so the app (uid 10001) can mkdir its data/
# and sandboxes/ subdirs on a clean boot (rc5 smoke-gate finding: the
# bare useradd home did not carry a writable .nextcraft).
RUN mkdir -p /home/nextcraft/.nextcraft/data \
    && chown -R nextcraft:nextcraft /opt/nextcraft /home/nextcraft/.nextcraft
WORKDIR /opt/nextcraft/ai-service-src
USER nextcraft
ENV AI_HOST=0.0.0.0 AI_PORT=8420

EXPOSE 8420
# slim has no curl — the healthcheck speaks python (stdlib urllib).
HEALTHCHECK --interval=30s --timeout=5s --start-period=15s --retries=3 \
    CMD ["python3", "-c", "import urllib.request,sys; sys.exit(0 if urllib.request.urlopen('http://127.0.0.1:8420/health', timeout=4).status == 200 else 1)"]

VOLUME ["/home/nextcraft/.nextcraft"]

CMD ["python3", "-m", "uvicorn", "ai_service.main:app", "--host", "0.0.0.0", "--port", "8420"]
