# syntax = docker/dockerfile:1.19.0
# check=error=true
# https://hub.docker.com/r/docker/dockerfile
# https://docs.docker.com/build/dockerfile/release-notes/
ARG IMAGE=python:3.14-slim-trixie

# These arguments are used to more easily assure a consistent version
# with dev.py validate state
ARG UV=0.11.3

# Intermediate layer to be able to use a build argument in COPY --from below:
#   https://stackoverflow.com/a/63472135
FROM ghcr.io/astral-sh/uv:$UV AS uv

FROM $IMAGE AS base
WORKDIR /usr/src/django-ca

RUN --mount=target=/var/lib/apt/lists,type=cache,sharing=locked \
    --mount=target=/var/cache/apt,type=cache,sharing=locked \
    rm -f /etc/apt/apt.conf.d/docker-clean &&  \
    apt-get update && \
    DEBIAN_FRONTEND=noninteractive apt-get install -y \
         lsb-release netcat-openbsd postgresql-client mariadb-client

# Add user (some tests check if it's impossible to write a file)
RUN adduser --system --uid=9000 --group --disabled-login django-ca

# Activate the virtual environment (even if it's not created yet).
ENV PATH="/usr/src/django-ca/.venv/bin:$PATH"
ENV VIRTUAL_ENV=/usr/src/django-ca/.venv

FROM base AS build

RUN --mount=target=/var/lib/apt/lists,type=cache,sharing=locked \
    --mount=target=/var/cache/apt,type=cache,sharing=locked \
    rm -f /etc/apt/apt.conf.d/docker-clean &&  \
    apt-get update && \
    DEBIAN_FRONTEND=noninteractive apt-get install -y \
         build-essential libpq-dev libmariadb-dev pkg-config softhsm2

# Install uv: https://docs.astral.sh/uv/guides/integration/docker/
COPY --from=uv /uv /uvx /bin/
ENV UV_PYTHON_PREFERENCE=only-system
ENV UV_LINK_MODE=copy
ENV UV_COMPILE_BYTECODE=1
ENV UV_LOCKED=1

RUN --mount=type=cache,target=/root/.cache/uv,id=django-ca-uv-debian \
    --mount=type=bind,source=uv.lock,target=uv.lock \
    --mount=type=bind,source=pyproject.toml,target=pyproject.toml \
    uv sync --all-extras --no-default-groups --group gunicorn --group DjangoLTS --no-install-project

COPY ca/django_ca/__init__.py ca/django_ca/
COPY pyproject.toml uv.lock ./
COPY docs/source/intro.rst docs/source/intro.rst

ARG DJANGO_CA_VERSION
ENV SETUPTOOLS_SCM_PRETEND_VERSION_FOR_DJANGO_CA=$DJANGO_CA_VERSION
RUN --mount=type=cache,target=/root/.cache/uv,id=django-ca-uv-debian \
    uv sync --all-extras --no-default-groups --group gunicorn --group DjangoLTS

##############
# Test stage #
##############
FROM build AS test
ENV SKIP_SELENIUM_TESTS=y
ENV SQLITE_NAME=:memory:

# Install additional requirements for testing:
RUN --mount=type=cache,target=/root/.cache/uv \
    uv sync --all-extras --no-default-groups  --group dev

# Copy sources (doctests are run by test suite, CA files are used in tests)
COPY ca/ ca/
COPY docs/source/django_ca_sphinx/ docs/source/django_ca_sphinx/
COPY docs/source/_files/ docs/source/_files/
COPY docs/source/python/ docs/source/python/

# Run tests as normal user to assert that no write-access is required.
USER django-ca:django-ca

# Finally run tests
ARG FAIL_UNDER=100
ARG COVERAGE_ARGS="--cov-report=html:/tmp/coverage --cov-report term-missing --cov-fail-under=$FAIL_UNDER"
ENV COVERAGE_FILE=/tmp/.coverage
RUN pytest -vx $COVERAGE_ARGS --no-selenium
RUN touch /tmp/.coverage-sentinel

###############
# Build stage #
###############
FROM build AS prepare

COPY ca/ ca/
COPY conf/ ca/conf/
COPY gunicorn/ gunicorn/
COPY nginx/ nginx/
RUN mkdir ca/conf/local/

COPY devscripts/standalone/ devscripts/standalone/

RUN rm -rf ca/django_ca/tests ca/ca/test_settings.py ca/ca/localsettings.py.example

# Test that imports are working
RUN python devscripts/standalone/clean.py
RUN DJANGO_CA_SECRET_KEY=dummy devscripts/standalone/test-imports.py --all-extras

# Finally, clean up to minimize the image
RUN python devscripts/standalone/clean.py
RUN rm -rf pyproject.toml ca/django_ca/migrations/pyproject.toml devscripts/pyproject.toml docs/
RUN python devscripts/standalone/check-clean-docker.py --ignore-devscripts
RUN rm -rf devscripts/

# With BuildKit, the test stage is never executed unless we depend on it
COPY --from=test /tmp/.coverage-sentinel /tmp

###############
# final stage #
###############
FROM base

RUN mkdir -p /usr/share/django-ca/static /usr/share/django-ca/media /var/lib/django-ca/ \
             /var/lib/django-ca/certs/ca/shared /var/lib/django-ca/certs/ocsp \
             /var/lib/django-ca/shared /var/lib/django-ca/nginx/templates/ \
             /run/django-ca && \
    chown -R django-ca:django-ca /usr/share/django-ca/ /var/lib/django-ca/ /run/django-ca/ && \
    chmod 0700 /run/django-ca/

COPY --from=prepare /usr/src/django-ca/ ./
RUN ln -s /usr/src/django-ca/ca/manage.py /usr/local/bin/manage

COPY scripts/ /usr/src/django-ca/scripts/
RUN ln -s /usr/src/django-ca/scripts/*.sh /usr/local/bin/

USER django-ca:django-ca
EXPOSE 8000
VOLUME ["/var/lib/django-ca/", "/usr/share/django-ca/media/"]
WORKDIR /usr/src/django-ca/ca/

ENV DJANGO_CA_SETTINGS=conf/:conf/local

CMD [ "gunicorn.sh" ]
