FROM nvidia/cuda:13.3.0-devel-rockylinux9
LABEL authors="leonarski_f"

ARG OPENSSL_VERSION=3.5.4
ARG QT_VERSION=6.11.1
ARG DBUS_VERSION=1.14.10
ARG NODE_MAJOR=22
ARG EIGEN_VERSION=3.4.0
# HDF5, libtiff and libjpeg-turbo are built by the jungfraujoch CMake itself (FetchContent /
# ExternalProject). Eigen is an external find_package(Eigen3 3.4) dependency, installed from source
# below (3.4.x is required; Eigen's same-major-version rule rejects 5.x).
ARG DIALS_VERSION=3.27.0
ARG DIALS_TARBALL_URL=https://github.com/dials/dials/releases/download/v3.27.0/dials-v3-27-0-linux-x86_64.tar.xz
ARG DIALS_PREFIX=/opt

# Update base, enable CRB (RHEL/Rocky 9), and install toolchain + Qt deps
RUN dnf -y update && \
    dnf -y install \
      'dnf-command(config-manager)' && \
    dnf config-manager --set-enabled crb && \
    dnf -y install --enablerepo=devel \
      dnf-plugins-core \
      epel-release \
      git \
      which \
      ca-certificates \
      wget \
      tar \
      xz \
      make \
      gcc-toolset-13 \
      gcc-toolset-13-gcc \
      gcc-toolset-13-gcc-c++ \
      gcc-toolset-13-gdb \
      rpm-build \
      rpmdevtools \
      numactl-devel \
      redhat-rpm-config \
      python3 \
      python3.12 \
      perl \
      nasm \
      pkgconf-pkg-config \
      xcb-util-devel \
      xcb-util-*-devel \
      libxcb-devel \
      libxkbcommon-devel \
      libxkbcommon-x11-devel \
      libX11-devel \
      libXext-devel \
      libXrender-devel \
      libXi-devel \
      libXrandr-devel \
      libXcursor-devel \
      libXfixes-devel \
      libXinerama-devel \
      mesa-libGL-devel \
      mesa-libEGL-devel \
      expat-devel \
      krb5-devel \
      zlib-devel \
      zlib-static \
      fontconfig-devel \
      mesa-dri-drivers \
      libdrm-devel \
      libglvnd-core-devel \
      libglvnd-devel \
      glibc-langpack-en \
      glibc-locale-source \
      freetype-devel && \
    dnf clean all && rm -rf /var/cache/dnf

# Everything built from source below is identical in all four build images, so it lives in
# docker/common/ and is run from there -- one copy to change, not four. The build context is
# docker/ (see build_images.sh), which is what puts common/ in reach of this COPY.
ARG CMAKE_VERSION=3.31.8
ARG CMAKE_SHA256=630615d8e98ac33eba7fbe472626dff5c899c85af3c024585ae109166a6909d0
ARG NINJA_VERSION=1.13.2
ARG NINJA_SHA256=5749cbc4e668273514150a80e387a957f933c6ed3f5f11e03fb30955e2bbead6
COPY common/ /opt/jfjoch-common/
RUN /opt/jfjoch-common/install-cmake.sh
RUN /opt/jfjoch-common/install-ninja.sh
# Ahead of the distro path: these are the CMake and Ninja every later step and every CI build uses.
ENV PATH=/opt/cmake-${CMAKE_VERSION}/bin:/opt/ninja-${NINJA_VERSION}/bin:${PATH}

RUN /opt/jfjoch-common/build-openssl.sh

# Expose static OpenSSL to CMake/pkg-config
ENV OPENSSL_ROOT_DIR=/opt/openssl-${OPENSSL_VERSION}
ENV PKG_CONFIG_PATH=${OPENSSL_ROOT_DIR}/lib/pkgconfig:${OPENSSL_ROOT_DIR}/lib64/pkgconfig:${PKG_CONFIG_PATH}

# Install a recent Node.js (NodeSource). Change NODE_MAJOR if you want another major version.
RUN curl -fsSL https://rpm.nodesource.com/setup_${NODE_MAJOR}.x | bash - && \
    dnf -y install nodejs && \
    dnf clean all && rm -rf /var/cache/dnf && \
    node --version && npm --version && (corepack enable || true)

# Make GCC/G++ 13 the default for builds
ENV GCC_TOOLSET_ROOT=/opt/rh/gcc-toolset-13/root
ENV PATH=${GCC_TOOLSET_ROOT}/usr/bin:${PATH}
ENV CC=${GCC_TOOLSET_ROOT}/usr/bin/gcc
ENV CXX=${GCC_TOOLSET_ROOT}/usr/bin/g++

# Static libdbus: link D-Bus into the viewer (Qt6::DBus) instead of pulling libdbus-1.so.3 at runtime.
# A distro libdbus-1.so drags in libsystemd (-> libzstd/liblz4/libcap/libgcrypt/libgpg-error) and
# libselinux (-> libpcre2). Disabling those integrations makes libdbus-1.a depend on ~libc alone, so
# that whole runtime .so tail disappears while the viewer keeps its single-instance / remote-control
# D-Bus feature -- it is a pure session-bus client (registers a name + exports an adaptor), so the
# daemon-side systemd/selinux features are irrelevant. Static-only install (no .so); the Qt build
# finds it through find_package(DBus1) via the -DDBus1_DIR hint (the CMake package config dbus
# installs, which imports libdbus-1.a). Built -fPIC (--with-pic) so the archive links into Qt's PIE
# tools (qdbusxml2cpp). expat is only a configure-time dep of the dbus daemon; the client libdbus-1
# links neither expat nor systemd.
RUN /opt/jfjoch-common/build-dbus.sh

# Put the static libdbus pkgconfig ahead of the system one so Qt6::DBus resolves to the .a
ENV PKG_CONFIG_PATH=/opt/dbus-${DBUS_VERSION}-static/lib/pkgconfig:${PKG_CONFIG_PATH}

# Build and install static Qt 6.9 with Core, Gui, Widgets, Charts, DBus
ARG QT_PREFIX=/opt/qt-${QT_VERSION}-static
RUN /opt/jfjoch-common/build-qt.sh

# Install DIALS using the official binary tarball workflow
RUN set -eux; \
    cd /tmp; \
    curl -fL -o dials.tar.xz "${DIALS_TARBALL_URL}"; \
    tar -xJf dials.tar.xz; \
    cd dials-installer; \
    ./install --prefix="${DIALS_PREFIX}"; \
    cd /; \
    rm -rf /tmp/dials.tar.xz /tmp/dials-*-linux-x86_64

RUN set -eux; \
        mkdir -p /opt/xds; \
        cd /tmp; \
        curl -fL -o XDS-gfortran_Linux_x86_64.tar.gz https://xds.mr.mpg.de/XDS-gfortran_Linux_x86_64.tar.gz; \
        tar -xzf XDS-gfortran_Linux_x86_64.tar.gz; \
        cp -a /tmp/XDS-gfortran_Linux_x86_64/. /opt/xds/

RUN set -eux; \
    cd /tmp; \
    curl -fL -o dectris-neggia-1.2.0.el7.tar.gz \
      https://github.com/dectris/neggia/files/6585943/dectris-neggia-1.2.0.el7.tar.gz; \
    tar -xzf dectris-neggia-1.2.0.el7.tar.gz; \
    find . -name 'dectris-neggia*.so' -print; \
    mkdir -p /opt/xds; \
    cp -av "$(find . -name 'dectris-neggia*.so' | head -n 1)" /opt/xds/dectris-neggia.so; \
    chmod 755 /opt/xds/dectris-neggia.so; \
    rm -rf /tmp/dectris-neggia-1.2.0.el7.tar.gz /tmp/*

RUN dnf -y install python3-Cython python3-pip python3-devel && dnf clean all

RUN set -eux; \
     wget --tries=5 --waitretry=5 \
          -O /opt/xds/durin-plugin.so \
          https://gitea.psi.ch/mx/durin/releases/download/1.0.0/libdurin-plugin.so.1.0.0

# Eigen 3.4 (header-only) -- external find_package(Eigen3 3.4) dependency, installed to /opt/eigen-3.4.
RUN /opt/jfjoch-common/install-eigen.sh

# Make Qt, the static libdbus, and Eigen discoverable by CMake. The static libdbus prefix is
# required here (not only at Qt build time): every Qt6::DBus consumer re-runs find_package(DBus1)
# through Qt's exported config, so DBus1Config.cmake must be on CMAKE_PREFIX_PATH for the viewer build.
ENV CMAKE_PREFIX_PATH=/opt/qt-${QT_VERSION}-static:/opt/dbus-${DBUS_VERSION}-static:/opt/eigen-3.4

ENV LANG=en_US.UTF-8
ENV LANGUAGE=en_US:en
ENV LC_ALL=en_US.UTF-8

# Set workdir for your project
WORKDIR /workspace

# Default entrypoint: interactive shell
CMD ["/bin/bash", "-l"]

RUN rm -rf /opt/jfjoch-common
