# --- Build stage: install dependencies ---
FROM python:3.12-slim AS builder

ENV PYTHONDONTWRITEBYTECODE=1

WORKDIR /app

COPY --from=ghcr.io/astral-sh/uv:latest /uv /usr/local/bin/uv

# Install dependencies first (cached layer — only reruns when pyproject.toml/uv.lock change).
# OB_EXTRA selects which optional-dependency group to install:
#   - flight-duckdb-only (default) — pyarrow + ob-flight-extension + ob-duckdb
#     only. Smallest image; used by the Cloud Run demo which only needs
#     the baked-in DuckDB seed.
#   - flight — pyarrow + ob-flight-extension + all 8 vendor drivers
#     (BigQuery, ClickHouse, Databricks, Dremio, DuckDB, MySQL, Postgres,
#     Snowflake). Required for integration tests that execute against a
#     non-DuckDB backend (e.g. the Dremio Stage-2 suite).
#
# Copy the workspace members (drivers/ and packages/) before the sync so uv
# can resolve the workspace graph. The flight* extras pull the osi-orionbelt
# member under packages/, so it must be present at this first sync.
ARG OB_EXTRA=flight-duckdb-only
COPY pyproject.toml uv.lock README.md ./
COPY drivers/ drivers/
COPY packages/ packages/
RUN uv sync --no-dev --no-install-project --frozen --extra ${OB_EXTRA}

# Copy source and install the project itself (osi-orionbelt vendors its own
# schemas; schema/ here is for the main package's reference endpoints).
COPY src/ src/
COPY schema/ schema/
RUN uv sync --no-dev --no-editable --frozen --extra ${OB_EXTRA}

# --- Runtime stage: minimal image ---
FROM python:3.12-slim

ENV PYTHONDONTWRITEBYTECODE=1 \
    PYTHONUNBUFFERED=1

WORKDIR /app

# Install IANA tzdata so Python's zoneinfo can resolve names like
# Europe/Berlin. python:3.12-slim has no /usr/share/zoneinfo, and without
# it ZoneInfo("Europe/Berlin") raises ZoneInfoNotFoundError — the timezone
# resolver then silently falls back to UTC. Belt-and-suspenders alongside
# the tzdata Python dep.
RUN apt-get update \
    && apt-get install -y --no-install-recommends tzdata \
    && rm -rf /var/lib/apt/lists/*

# Create non-root user
RUN groupadd -r app && useradd -r -g app -d /app -s /sbin/nologin app

# Copy installed virtualenv from builder
COPY --from=builder --chown=app:app /app/.venv /app/.venv
ENV PATH="/app/.venv/bin:$PATH"

# Copy schema (needed at runtime for validation)
COPY --from=builder --chown=app:app /app/schema schema/

# The OSI <-> OBML converter is installed into the venv as the osi-orionbelt
# package (with its schemas bundled), so no separate copy is needed here.

# Bake the matching OBML model into the image, plus the public-demo dataset
# when it is present in the build context, so the Cloud Run service can
# answer /v1/query/execute without external infra. The .duckdb file is
# gitignored and pre-generated by scripts/build_demo_duckdb.py before the
# docker build (see deploy-gcloud.sh). The trailing glob on the .duckdb makes
# that source optional: the public Docker Hub build has no seed and ships
# without it, while the .yaml (always present) keeps the COPY source set
# non-empty so the build never fails.
COPY --chown=app:app examples/orionbelt_1_commerce.yaml examples/orionbelt_1_commerce.duckdb* /app/data/

USER app

# Cloud Run injects PORT (default 8080)
ENV PORT=8080 \
    API_SERVER_HOST=0.0.0.0 \
    LOG_LEVEL=INFO \
    LOG_FORMAT=json \
    DISABLE_SESSION_LIST=true \
    EXPOSE_API_DOCS=true \
    EXPOSE_OPENAPI_SCHEMA=true \
    DB_VENDOR=duckdb \
    DUCKDB_DATABASE=/app/data/orionbelt_1_commerce.duckdb \
    MODEL_DIR=/app/data \
    MODEL_FILES=orionbelt_1_commerce.yaml

EXPOSE ${PORT}

# Health check for local Docker / Compose (Cloud Run uses its own probes)
HEALTHCHECK --interval=30s --timeout=5s --start-period=10s --retries=3 \
    CMD python -c "import urllib.request; urllib.request.urlopen(f'http://localhost:{__import__(\"os\").environ[\"PORT\"]}/health')"

# Single worker — Cloud Run scales by adding container instances, not workers
CMD ["sh", "-c", "uvicorn orionbelt.api.app:create_app --factory --host 0.0.0.0 --port $PORT --log-level info --proxy-headers --forwarded-allow-ips='*' --no-access-log"]
