# syntax=docker/dockerfile:1

# ---- Stage 1: emit the OpenAPI document from the real FastAPI app -----------
FROM python:3.12-slim AS schema
WORKDIR /src
COPY requirements.txt ./
RUN pip install --no-cache-dir -r requirements.txt
COPY app ./app
COPY scripts ./scripts
COPY VERSION ./
RUN python scripts/gen_openapi.py /src/openapi.json

# ---- Stage 2: generate the TS client, then build the SPA -------------------
# Node exists ONLY here. No Node at runtime (react.md, held line).
FROM node:22-slim AS frontend
WORKDIR /fe
COPY frontend/package.json frontend/package-lock.json* ./
RUN npm install --no-audit --no-fund
COPY frontend/ ./
COPY --from=schema /src/openapi.json ./openapi.json
RUN npx openapi-typescript ./openapi.json -o ./src/api/schema.d.ts \
    && npm run build

# ---- Stage 3: the runtime - one Python process -----------------------------
FROM python:3.12-slim AS runtime
ENV PYTHONUNBUFFERED=1 PYTHONDONTWRITEBYTECODE=1
WORKDIR /app

# The app runs as a NON-ROOT user whose uid/gid match the host owner of the
# bind-mounted media directory. This is the same deliberate uid-matching the
# gateway uses for WordPress (www-data 33) so host and container can share
# files without loosening permissions. Override at build time if the host
# owner differs.
ARG APP_UID=1000
ARG APP_GID=1122
RUN groupadd --gid ${APP_GID} coachpapa \
    && useradd --uid ${APP_UID} --gid ${APP_GID} --no-create-home --shell /usr/sbin/nologin coachpapa

COPY requirements.txt ./
RUN pip install --no-cache-dir -r requirements.txt

COPY app ./app
COPY alembic ./alembic
COPY alembic.ini ./
COPY scripts ./scripts
COPY seed ./seed
COPY VERSION ./
COPY entrypoint.sh ./
# vite.config.ts sets outDir "../static", which from WORKDIR /fe is /static.
COPY --from=frontend /static ./static

RUN mkdir -p /data/media /backups && chown -R coachpapa:coachpapa /data /backups /app
USER coachpapa

EXPOSE 3000
HEALTHCHECK --interval=30s --timeout=5s --start-period=25s --retries=3 \
  CMD python -c "import urllib.request;urllib.request.urlopen('http://127.0.0.1:3000/healthz',timeout=3)"

ENTRYPOINT ["./entrypoint.sh"]
