# OCCT builder image — a compiler appliance, not a base for the wheel.
#
# Wheel builds `docker run` this with the repo mounted (see ../Makefile); they
# never `FROM` it, so iterating on the binding never re-layers the kernel.
# Rebuild only when this file changes, and bump the image tag's -N when you do.
#
# The production host (4 cores) can never compile OCCT, which is the whole
# reason this exists: the kernel is compiled once here and shipped inside the
# wheel by `auditwheel repair`.

FROM quay.io/pypa/manylinux_2_28_x86_64@sha256:f854c50adf7b7a325bc4794316f3758d387a41d61f9e2ebca0f26c7dc8f761d4

# FreeType + fontconfig are the only optional OCCT dependencies we keep — the
# text-emboss feature builds glyph outlines through Font_BRepFont (TKService).
# ccache/ninja serve the wheel build that runs in this image later.
RUN dnf install -y freetype-devel fontconfig-devel ninja-build ccache valgrind \
    && dnf clean all

ARG OCCT_TAG=V8_0_1
ARG OCCT_SHA256=0d6913eae4bcc09a3653ceced6dda1aec11c35a1513d4c06762c9b002092c68a

RUN curl -fsSL -o /tmp/occt.tar.gz \
      "https://github.com/Open-Cascade-SAS/OCCT/archive/refs/tags/${OCCT_TAG}.tar.gz" \
    && echo "${OCCT_SHA256}  /tmp/occt.tar.gz" | sha256sum -c - \
    && mkdir -p /src \
    && tar -xzf /tmp/occt.tar.gz -C /src --strip-components=1 \
    && rm /tmp/occt.tar.gz

# Conservative FP flags are deliberate: OCCT's version is a determinism input
# for assay's committed goldens, so a different optimizer could shift last-ulp
# results against the upstream wheel we are proving parity with.  -O2 (not the
# Release default -O3), no -ffast-math, no -march=native.
RUN cmake -G Ninja -S /src -B /build \
      -DCMAKE_BUILD_TYPE=Release \
      -DCMAKE_CXX_FLAGS_RELEASE="-O2 -DNDEBUG" \
      -DCMAKE_C_FLAGS_RELEASE="-O2 -DNDEBUG" \
      -DBUILD_LIBRARY_TYPE=Shared \
      -DINSTALL_DIR=/opt/occt \
      -DBUILD_MODULE_FoundationClasses=ON \
      -DBUILD_MODULE_ModelingData=ON \
      -DBUILD_MODULE_ModelingAlgorithms=ON \
      -DBUILD_MODULE_Visualization=ON \
      -DBUILD_MODULE_DataExchange=ON \
      -DBUILD_MODULE_ApplicationFramework=ON \
      -DBUILD_MODULE_Draw=OFF \
      -DUSE_FREETYPE=ON \
      -DUSE_VTK=OFF -DUSE_TK=OFF -DUSE_TCL=OFF \
      -DUSE_XLIB=OFF -DUSE_OPENGL=OFF -DUSE_GLES2=OFF \
      -DUSE_TBB=OFF -DUSE_RAPIDJSON=OFF -DUSE_DRACO=OFF \
      -DUSE_FREEIMAGE=OFF -DUSE_FFMPEG=OFF -DUSE_OPENVR=OFF \
    && ninja -C /build -j"$(nproc)" \
    && ninja -C /build install \
    && find /opt/occt/lib -name '*.so*' -type f -exec strip --strip-debug {} + \
    && rm -rf /build /src

# Assert the headless build actually produced what the app needs.  Text emboss
# imports OCP.StdPrs.StdPrs_BRepFont, which is a deprecated typedef of
# Font_BRepFont living in TKService/TKV3d — those toolkits must exist even with
# OpenGL and Xlib off, and must not have picked up a libGL/libX11 DT_NEEDED
# (dropping those two runtime packages from the app image is a phase goal).
RUN test -f /opt/occt/lib/libTKService.so \
    && test -f /opt/occt/lib/libTKV3d.so \
    && test -f /opt/occt/lib/libTKDESTEP.so \
    && ! ldd /opt/occt/lib/libTKService.so | grep -qE 'libGL\.|libX11\.' \
    && ! ldd /opt/occt/lib/libTKV3d.so | grep -qE 'libGL\.|libX11\.' \
    && ldd /opt/occt/lib/libTKService.so | grep -q libfreetype

ENV OCCT_ROOT=/opt/occt \
    CMAKE_PREFIX_PATH=/opt/occt \
    LD_LIBRARY_PATH=/opt/occt/lib \
    PATH=/opt/python/cp312-cp312/bin:$PATH

WORKDIR /io

# Sanitizer runtime for `make test-asan`, the handle-model memory-safety check.
# Deliberately the last layer: adding it never invalidates the kernel build
# above, so the ~40 minute compile is not repeated for a test dependency.
RUN dnf install -y gcc-toolset-14-libasan-devel && dnf clean all
