# syntax=docker/dockerfile:1.7
FROM debian:trixie-slim AS builder
ARG DOCKER_TAG
ARG BUILD_CONCURRENCY
# Pinned vcpkg baseline; keep in sync with vcpkg-configuration.json at the repo root.
ARG VCPKG_COMMIT=c3867e714dd3a51c272826eea77267876517ed99

RUN apt-get update && \
    apt-get -y --no-install-recommends --no-install-suggests install \
        autoconf \
        automake \
        build-essential \
        ca-certificates \
        ccache \
        cmake \
        curl \
        git \
        libtool \
        make \
        ninja-build \
        pkg-config \
        tar \
        unzip \
        zip && \
    rm -rf /var/lib/apt/lists/*

# NOTE: VCPKG_ROOT lives outside /opt so the runstage's COPY --from=builder /opt
# /opt doesn't drag the ~5 GB vcpkg tree along.
ENV VCPKG_ROOT=/vcpkg \
    VCPKG_FORCE_SYSTEM_BINARIES=1
RUN mkdir -p ${VCPKG_ROOT} && \
    curl -fsSL https://github.com/microsoft/vcpkg/archive/${VCPKG_COMMIT}.tar.gz | \
    tar -xz --strip-components=1 -C ${VCPKG_ROOT} && \
    ${VCPKG_ROOT}/bootstrap-vcpkg.sh -disableMetrics

WORKDIR /src

# Install manifest deps as their own layer so source-only changes don't
# invalidate the (expensive) vcpkg install. The three cache mounts persist
# across docker builds on the host:
#   - /root/.cache/vcpkg/archives : vcpkg's per-package binary cache (the big win)
#   - /vcpkg/downloads            : upstream tarball cache (avoids re-downloading boost, etc.)
#   - /vcpkg/buildtrees           : partial builds (helps when a single port fails)
COPY vcpkg.json vcpkg-configuration.json ./
COPY vcpkg-overlay-ports/ ./vcpkg-overlay-ports/
# TARGETARCH is auto-populated by BuildKit (amd64, arm64).  Map it to the
# matching vcpkg triplet so native ARM64 builds don't fail with a hardcoded
# x64-linux triplet (see docker/build-push-action platforms: linux/arm64).
ARG TARGETARCH
RUN --mount=type=cache,target=/root/.cache/vcpkg/archives,sharing=locked \
    --mount=type=cache,target=/vcpkg/downloads,sharing=locked \
    --mount=type=cache,target=/vcpkg/buildtrees,sharing=locked \
    export VCPKG_DEFAULT_BINARY_CACHE=/root/.cache/vcpkg/archives && \
    mkdir -p build/vcpkg_installed "$VCPKG_DEFAULT_BINARY_CACHE" && \
    case "${TARGETARCH}" in \
        amd64) VCPKG_TRIPLET=x64-linux ;; \
        arm64) VCPKG_TRIPLET=arm64-linux ;; \
        *) echo "Unsupported TARGETARCH: ${TARGETARCH}" >&2; exit 1 ;; \
    esac && \
    echo "Using vcpkg triplet: ${VCPKG_TRIPLET}" && \
    ${VCPKG_ROOT}/vcpkg install \
        --x-manifest-root=/src \
        --x-install-root=/src/build/vcpkg_installed \
        --triplet=${VCPKG_TRIPLET} \
        --no-print-usage \
        --clean-buildtrees-after-build \
        --clean-packages-after-build

# Now copy the rest of the source tree. This layer is the one that gets
# invalidated by code changes — everything above stays cached.
COPY . /src

RUN --mount=type=cache,target=/root/.ccache \
    NPROC=${BUILD_CONCURRENCY:-$(nproc)} && \
    export CXXFLAGS="-Wno-array-bounds -Wno-uninitialized -Wno-stringop-overflow" && \
    export CCACHE_DIR=/root/.ccache && \
    export CCACHE_MAXSIZE=2G && \
    export CCACHE_COMPRESSLEVEL=6 && \
    echo "Building OSRM ${DOCKER_TAG}" && \
    git show --format="%H" | head -n1 > /opt/OSRM_GITSHA && \
    echo "Building OSRM gitsha $(cat /opt/OSRM_GITSHA)" && \
    cd build && \
    BUILD_TYPE="Release" && \
    ENABLE_ASSERTIONS="Off" && \
    case ${DOCKER_TAG} in *"-debug"*) BUILD_TYPE="Debug";; esac && \
    case ${DOCKER_TAG} in *"-assertions"*) BUILD_TYPE="RelWithDebInfo" && ENABLE_ASSERTIONS="On";; esac && \
    echo "Building ${BUILD_TYPE} with ENABLE_ASSERTIONS=${ENABLE_ASSERTIONS}" && \
    cmake .. -G Ninja \
        -DCMAKE_TOOLCHAIN_FILE=${VCPKG_ROOT}/scripts/buildsystems/vcpkg.cmake \
        -DCMAKE_BUILD_TYPE=${BUILD_TYPE} \
        -DENABLE_ASSERTIONS=${ENABLE_ASSERTIONS} \
        -DENABLE_LTO=On \
        -DCMAKE_C_COMPILER_LAUNCHER=ccache \
        -DCMAKE_CXX_COMPILER_LAUNCHER=ccache && \
    ninja -j${NPROC} install && \
    ccache -s && \
    # Copy the TBB shared lib out of vcpkg so the runstage image can load it
    # without bringing in the whole vcpkg tree. Boost, expat, bzip2, lua, etc.
    #all link statically under the x64-linux triplet, so only TBB needs
    # runtime shipping. In manifest mode vcpkg installs per-build under
    # build/vcpkg_installed/<triplet>/, not $VCPKG_ROOT/installed/.
    mkdir -p /opt/vcpkg-runtime-libs && \
    find vcpkg_installed -name 'libtbb*.so*' -exec cp -a {} /opt/vcpkg-runtime-libs/ \; && \
    cd ../profiles && \
    cp -r * /opt && \
    strip /usr/local/bin/* && \
    rm -rf /src


# Multistage build to reduce image size - https://docs.docker.com/build/building/multi-stage/#use-multi-stage-builds
# Only the content below ends up in the image, this helps remove /src and vcpkg from the image.
FROM debian:trixie-slim AS runstage

COPY --from=builder /usr/local /usr/local
COPY --from=builder /opt /opt
COPY --from=builder /opt/vcpkg-runtime-libs/ /usr/local/lib/

RUN apt-get update && \
    apt-get install -y --no-install-recommends --no-install-suggests \
        libgcc-s1 \
        libstdc++6 && \
    rm -rf /var/lib/apt/lists/* && \
# Add /usr/local/lib to ldconfig so TBB (and any other shared vcpkg libs) load
    ldconfig /usr/local/lib

RUN /usr/local/bin/osrm-extract --help && \
    /usr/local/bin/osrm-routed --help && \
    /usr/local/bin/osrm-contract --help && \
    /usr/local/bin/osrm-partition --help && \
    /usr/local/bin/osrm-customize --help

WORKDIR /opt

EXPOSE 5000