# Dockerfile — Python runner for the Day-2 Build-Your-Own-Guardrail lab
# Base image pinned by index-digest (ADR-6).
# Re-resolve: docker buildx imagetools inspect python:3.12-slim --format '{{.Manifest.Digest}}'
FROM python:3.12-slim@sha256:423ed6ab25b1921a477529254bfeeabf5855151dc2c3141699a1bfc852199fbf

WORKDIR /workspace

# curl: for debugging convenience (e.g. testing endpoints from inside the container).
RUN apt-get update \
    && apt-get install -y --no-install-recommends curl \
    && rm -rf /var/lib/apt/lists/*

# HuggingFace cache baked INTO the image (offline guarantee, ADR-5).
# This path must remain consistent between build and runtime.
ENV HF_HOME=/workspace/hf_cache

# Step 1: Install CPU-only PyTorch FIRST to prevent pip from pulling the large GPU
# version from PyPI when resolving llm-guard's torch>=2.4.0 dependency.
RUN pip install --no-cache-dir torch \
    --index-url https://download.pytorch.org/whl/cpu

# Step 2: Install remaining dependencies (torch is already present; pip won't re-pull it).
COPY app/requirements.txt ./requirements.txt
RUN pip install --no-cache-dir -r requirements.txt

# Step 3: Pre-bake the DeBERTa prompt-injection classifier at BUILD time.
#
# Why here: llm_guard.input_scanners.PromptInjection downloads
# protectai/deberta-v3-base-prompt-injection-v2 (~184 MB) from HuggingFace on first
# instantiation.  By triggering that download during `docker build` (which HAS internet
# access in pre-stage.sh), the weights land in HF_HOME (/workspace/hf_cache) inside
# the image layer.  At runtime, TRANSFORMERS_OFFLINE=1 / HF_HUB_OFFLINE=1 prevent any
# network fetch — the model is already there.
#
# IMPORTANT: TRANSFORMERS_OFFLINE / HF_HUB_OFFLINE are NOT set yet in the ENV at this
# point in the Dockerfile; they are set BELOW (Step 4).  The prebake_deberta.py script
# also pops them from os.environ as a belt-and-suspenders check.
COPY app/prebake_deberta.py /tmp/prebake_deberta.py
RUN python /tmp/prebake_deberta.py && rm /tmp/prebake_deberta.py

# Step 3b: Pre-cache the tiktoken cl100k_base encoding at BUILD time.
# llm_guard's TokenLimit scanner uses tiktoken, which otherwise downloads
# cl100k_base from openaipublic.blob.core.windows.net on first use — a runtime
# network call that breaks the offline guarantee (ADR-5). Baking it here (the
# build has internet) plus a persistent TIKTOKEN_CACHE_DIR (set at build AND
# runtime) makes the TokenLimit scanner fully offline.
ENV TIKTOKEN_CACHE_DIR=/workspace/tiktoken_cache
RUN python -c "import tiktoken; tiktoken.get_encoding('cl100k_base')"

# Step 4: Set offline mode for runtime containers.
# These env vars cause transformers and huggingface_hub to use only local cache.
# Any attempt to fetch a missing model raises an error instead of pulling from HF.
ENV TRANSFORMERS_OFFLINE=1
ENV HF_HUB_OFFLINE=1

# Bake app + data + prompts so the image works standalone (compose mounts override at runtime)
COPY app/ ./app/
COPY data/ ./data/
COPY prompts/ ./prompts/

CMD ["python", "app/guardrail.py"]
