##### base stage #####

# Massage python image into the shape that we’ll need for most later
# stages.

FROM python:3.8-slim AS base

# Allow Jenkins to override with internal mirror
ARG PYPI_INDEX_URL=https://pypi.org/simple

# We need to recreate the /usr/share/man/man{1..8} directories first
# because they were clobbered by a parent image
RUN seq 1 8 | xargs -I{} mkdir -p /usr/share/man/man{} \
    && apt-get update \
    && pip install --upgrade --no-cache-dir --index-url ${PYPI_INDEX_URL} \
    pip

WORKDIR /core-notifications


##### requirements stage #####

# Generate requirements text files for later invocations of pip
# install. Latter stages are expected to copy requirements.txt and
# requirements-dev.txt as needed. Latter stages are _not_ expected to
# need pipfile-requirements or Pipfile.lock

FROM base AS requirements

# Allow Jenkins to override with internal mirror
ARG PYPI_INDEX_URL=https://pypi.org/simple

# Install tool to convert from pipenv to pip
RUN pip install --no-cache-dir --index-url ${PYPI_INDEX_URL} \
    pipfile-requirements

# Pipfile.lock is authoritative and generated by pipenv
COPY Pipfile.lock Pipfile.lock

# Create separate requirements files for deploy and test
RUN pipfile2req > /opt/requirements.txt \
    && pipfile2req -d > /opt/requirements-dev.txt


##### virtualenv stage #####

# Generate a Python virtual env to be used in latter stages. Latter
# stages are expected to copy /opt/venv, possibly adding to it. Latter
# stages are _not_ expected to need OS build deps.

FROM base AS virtualenv

# Allow Jenkins to override with internal mirror
ARG PYPI_INDEX_URL=https://pypi.org/simple

# Install OS build deps
RUN DEBIAN_FRONTEND=noninteractive \
    apt-get install -y --no-install-recommends \
    build-essential \
    # Create virtualenv to house Python run-time dependencies
    && python -m venv /opt/venv

# Make sure we use the virtualenv
ENV PATH="/opt/venv/bin:$PATH"

# Pip is assumed to be out-of-date
RUN pip install --upgrade --no-cache-dir --index-url ${PYPI_INDEX_URL} \
    pip wheel

# Pip requirements generated in requirements stage
COPY --from=requirements /opt/requirements.txt /opt/requirements.txt

# Install only PyPI packages needed for deployment (which are assumed
# to also be needed for testing)
RUN pip install --no-cache-dir --index-url ${PYPI_INDEX_URL} \
    -r /opt/requirements.txt


##### ready stage #####

# Latter stages are expected to start from this stage. This stage is
# expected to include everything necessary to execute the app directly
# from the command line _without_ any of the expected deployment
# technologies.

FROM base AS ready

# Virtualenv generated in virtualenv stage
COPY --from=virtualenv /opt/venv /opt/venv

# Make sure we use the virtualenv
ENV PATH="/opt/venv/bin:$PATH"


##### deploy-base stage #####

# This stage is expected to include all necessary binaries and
# configuration for a deployable image, _except_ the source tree,
# which is added in the terminal deploy stage to make better use of
# Docker’s layer cache.

FROM ready as deploy-base

ARG VERSION
ARG REVISION
ARG BUILDTIME

LABEL com.datadoghq.tags.service=core-notifications
LABEL com.datadoghq.tags.version=${VERSION}

ENV DD_SERVICE=core-notifications
ENV DD_VERSION=${VERSION}

# Create user for the App
ARG APP_USER=app
RUN useradd --no-create-home ${APP_USER}

# Configure Gunicorn
COPY gunicorn_config.py /etc/gunicorn/

# App will listen on this port
EXPOSE 8000

# run uwsgi
CMD ["/opt/venv/bin/ddtrace-run", "/opt/venv/bin/gunicorn", \
        "core_notifications.wsgi:application", \
        "-c", "/etc/gunicorn/gunicorn_config.py"]


##### test stage #####

# Configure and run unit tests, and set up everything necessary in
# this image for running multi-container test suites. It is _not_
# expected that latter stages will start from this stage. This image
# assumes an available Postgres database to use, and will attempt to
# migrate that database. *Never configure this image to use a live
# database, as it _will be wiped_.* Test suites depending on
# additional containers should instead be configured to use this stage
# in Docker Compose.

FROM ready AS test

# Allow Jenkins to override with internal mirror
ARG PYPI_INDEX_URL=https://pypi.org/simple

# Pip dev requirements generated in requirements stage
COPY --from=requirements /opt/requirements.txt /opt/requirements.txt
COPY --from=requirements /opt/requirements-dev.txt /opt/requirements-dev.txt

# Install only PyPI packages needed for testing in existing venv
RUN pip install --no-cache-dir --index-url $PYPI_INDEX_URL \
    -r /opt/requirements-dev.txt

COPY core_notifications core_notifications

# Copy in test directories
COPY tests tests
COPY .coveragerc ./
COPY pyproject.toml ./

# Run tests that don’t depend on other containers or services
CMD ["pytest"]


##### deploy stage #####

# This is expected to be the terminal stage, and the stage that
# provides a deployment image.

FROM deploy-base AS deploy

# Copy in source
COPY core_notifications core_notifications
