# The matching lock records the tag provenance, platform, Python, PyTorch,
# CUDA, and cuDNN compatibility. Never replace this with a mutable tag.
ARG BASE_IMAGE=docker.io/pytorch/pytorch@sha256:639b8229ccfd8a3aa803cf49c33d6d6fe406750d79aaf723fe8c0eb1060d8cff
FROM ${BASE_IMAGE}

ARG BASE_IMAGE
ARG PYTHON_VERSION=3.11
LABEL org.opencontainers.image.title="jr-wakeword-training" \
      org.opencontainers.image.description="Offline LiveKit WakeWord 0.2.1 training lane" \
      org.opencontainers.image.source="https://github.com/livekit/livekit-wakeword" \
      org.opencontainers.image.revision="1ec7f680df30ff4ca0ebae6b5983441e94b10980" \
      org.opencontainers.image.version="0.2.1"

ENV PYTHONDONTWRITEBYTECODE=1 \
    PYTHONUNBUFFERED=1 \
    PIP_NO_CACHE_DIR=1 \
    PIP_DISABLE_PIP_VERSION_CHECK=1 \
    NLTK_DATA=/usr/local/share/nltk_data

RUN case "${BASE_IMAGE}" in *@sha256:*) ;; *) echo "BASE_IMAGE must be digest-pinned" >&2; exit 64;; esac \
    && apt-get update \
    && apt-get install -y --no-install-recommends espeak-ng libsndfile1 ffmpeg sox time \
    && rm -rf /var/lib/apt/lists/* \
    && python -c "import sys; assert sys.version_info[:2] == (${PYTHON_VERSION%.*}, ${PYTHON_VERSION#*.})"

WORKDIR /opt/jr-wakeword

# The complete hash lock is generated with uv and reviewed in source control.
# Network access is permitted only at image build time; a launched training
# container is network-isolated and never resolves or installs dependencies.
COPY --chmod=0644 deploy/wakeword-training/requirements.wheelhouse.lock ./requirements.wheelhouse.lock
RUN python -m pip install --require-hashes -r requirements.wheelhouse.lock \
      && python -c "from importlib.metadata import version; assert version('livekit-wakeword') == '0.2.1'; assert version('torch') == version('torchaudio')" \
      && python -c "import nltk; assert nltk.download('cmudict', download_dir='/usr/local/share/nltk_data', quiet=True, raise_on_error=True)"

COPY --chmod=0644 scripts/wakeword_training_image.py ./wakeword_training_image.py
COPY --chmod=0644 scripts/wakeword_training_assets.py ./prepare-training-assets.py
COPY --chmod=0644 deploy/wakeword-training/assets-manifest-v1.json ./assets-manifest-v1.json
COPY --chmod=0644 deploy/wakeword-training/run-commercial-pipeline.py ./run-commercial-pipeline.py
COPY --chmod=0644 deploy/wakeword-training/run-local-experiment.py ./run-local-experiment.py
COPY --chmod=0644 deploy/wakeword-training/run-quarantined-smoke.py ./run-quarantined-smoke.py
COPY --chmod=0644 deploy/wakeword-training/stage_evidence.py ./stage_evidence.py
COPY --chmod=0644 deploy/wakeword-training/record-image-provenance.py ./record-image-provenance.py
COPY --chmod=0644 deploy/wakeword-training/finalize-run.py ./finalize-run.py

# Do not add listener extras, microphone SDK packages, gateway source, gateway credentials,
# Docker socket access, or published ports in this one-shot image.
# DockerTrainingExecutor supplies the explicit commercial/quarantined wrapper
# as argv. CMD keeps that argv from being appended to a fixed ENTRYPOINT.
CMD ["python", "/opt/jr-wakeword/run-commercial-pipeline.py", "/run/resolved-config.yaml"]
