# syntax=docker/dockerfile:1.7
# ECR account for the org parent images, used by the Python integration-test
# stage's FROM (declared at global scope so it is visible there).
ARG         AWS_ACCOUNT=086679231553

# Parent image is amd64-only and the protoc binary below is x86_64 — pin the platform
# explicitly. On Apple Silicon hosts, Rosetta translates the resulting image at runtime
# (see README for colima setup).
FROM        --platform=linux/amd64 086679231553.dkr.ecr.us-east-1.amazonaws.com/docker-parent-images:rust1.95 AS base
USER       root
# Install dependencies for building router binary
RUN         apt-get update && apt-get install -y \
                curl \
                cmake \
                gcc \
                g++ \
                openssl \
                libssl-dev \
                pkg-config \
                wget \
                unzip && \
                apt-get clean && \
                wget https://github.com/protocolbuffers/protobuf/releases/download/v3.8.0/protoc-3.8.0-linux-x86_64.zip && \
                unzip protoc-3.8.0-linux-x86_64.zip -d /usr/local && \
                rm protoc-3.8.0-linux-x86_64.zip

WORKDIR     /var/app

# Create service user (explicit UID so BuildKit cache mounts in the build stage
# can match ownership and avoid permission churn across builds).
RUN         /usr/sbin/useradd -u 1000 -c 'graphql-router user' -m -d /home/graphql-router -s /bin/bash graphql-router && \
            chown -R graphql-router:graphql-router /var/app

USER        graphql-router


FROM        base AS build

# Copy sources
COPY        --chown=graphql-router:graphql-router Cargo.toml Cargo.lock rust-toolchain.toml ./
COPY        --chown=graphql-router:graphql-router src/ src/

# BuildKit cache mounts: cargo registry + target/ persist across builds, so unchanged
# crates are not recompiled. Caches do NOT persist into the final image, so the binary
# must be copied out to a stable path before this RUN exits.
RUN         --mount=type=cache,target=/home/graphql-router/.cargo/registry,uid=1000,gid=1000,sharing=locked \
            --mount=type=cache,target=/var/app/target,uid=1000,gid=1000,sharing=locked \
            cargo build --release --locked && \
            cp target/release/router /var/app/router


FROM        base AS dev
# Copy graphql-router binary
COPY        --from=build /var/app/router ./router

# Copy generated config file
COPY        config-*.yaml ./
COPY        --chown=graphql-router:graphql-router scripts/dev.sh ./
COPY        --chown=graphql-router:graphql-router scripts/supergraph.yaml ./

# Generate the supergraph
RUN         curl -sSL https://rover.apollo.dev/nix/latest | sh
ENV         PATH="/home/graphql-router/.rover/bin:${PATH}"
ENV         APOLLO_ELV2_LICENSE=accept
RUN         rover supergraph compose --config ./supergraph.yaml > ./supergraph.graphql

EXPOSE      $PORT

CMD [ "/var/app/dev.sh" ]


FROM        build AS test

# Run clippy and tests
RUN         rustup component add clippy
CMD         ["sh", "-c", "cargo clippy --locked && cargo test --locked"]


FROM        base AS deploy
# Copy graphql-router binary
COPY        --from=build /var/app/router ./router

# Copy environment configs. Explicit list so a developer's local config-*.yaml
# (e.g. config-local.yaml) can never leak into a deploy image.
COPY        config-qa.yaml config-qa-internal.yaml config-qa-mcp.yaml config-uat.yaml config-prod.yaml config-prod-internal.yaml ./
COPY       --chown=graphql-router:graphql-router scripts/run.sh ./
RUN         chmod +x /var/app/run.sh
ENV         PORT=8080

EXPOSE      8080

CMD [ "/var/app/run.sh" ]


########################################
### JWT auth enforcement integration tests ###
########################################
# Independent Python/uv stage — has no dependency on the Rust stages above, so
# building `deploy` never builds this and vice versa. The tests are black-box:
# they hit the deployed QA routers over the network and mint a real QA token
# via AWS Secrets Manager + Auth0, so no router runs in this image. AWS
# credentials and any token overrides are supplied at run time (see
# docker-compose.yaml / `make ci_test_integration`).
FROM        ${AWS_ACCOUNT}.dkr.ecr.us-east-1.amazonaws.com/docker-parent-images:python313 AS integration-test
USER        root
WORKDIR     /var/app/tests

# Drive the test project's uv.lock with the image's system Python 3.13 — never
# download a separate interpreter.
ENV         UV_PYTHON_DOWNLOADS=never \
            UV_LINK_MODE=copy
RUN         pip install --no-cache-dir uv

# Resolve dependencies from the lockfile first so this layer caches unless the
# lock changes.
COPY        tests/pyproject.toml tests/uv.lock ./
RUN         --mount=type=cache,target=/root/.cache/uv \
            uv sync --locked --no-install-project

COPY        tests/ ./

ENTRYPOINT  ["uv", "run", "--no-sync", "pytest", "-rA"]
