# =============================================================================
# Dockerfile_rocky_deps
#
# Builds all AliceVision third-party dependencies on Rocky Linux + CUDA.
# Requires BuildKit:  DOCKER_BUILDKIT=1 docker build ...
#
# Build example:
#   DOCKER_BUILDKIT=1 docker build \
#     --build-arg CUDA_VERSION=12.1.1 \
#     --build-arg ROCKY_VERSION=9 \
#     --tag alicevision/alicevision-deps:<version>-rocky9-cuda12.1.1 \
#     -f docker/Dockerfile_rocky_deps .
# =============================================================================

# syntax=docker/dockerfile:1.4

ARG CUDA_VERSION
ARG ROCKY_VERSION
ARG CMAKE_VERSION=3.31.11

FROM nvidia/cuda:${CUDA_VERSION}-devel-rockylinux${ROCKY_VERSION}
LABEL maintainer="AliceVision Team alicevision-team@googlegroups.com"

# Re-declare ARGs after FROM so they are visible in this build stage
ARG CMAKE_VERSION
ARG CUDA_VERSION
ARG ROCKY_VERSION

# =============================================================================
# System packages + GCC 12 toolset
#
# Single RUN to minimise layers.
# BuildKit cache mount on /var/cache/dnf avoids re-downloading RPMs on rebuild.
#
# gcc-toolset-12 installs into /opt/rh/gcc-toolset-12 — it does NOT own
# /usr/bin/gcc which may already exist as a real file in the CUDA base image.
# We remove it first: Rocky 9 `alternatives` 1.20 has no --force flag.
# =============================================================================
RUN --mount=type=cache,target=/var/cache/dnf \
    dnf install -y 'dnf-command(config-manager)'                        && \
    dnf config-manager --set-enabled devel                              && \
    dnf install -y epel-release                                         && \
    dnf install -y                                                         \
        gcc-toolset-12-gcc-c++                                            \
        gcc-toolset-12-gcc-gfortran                                     && \
    rm -f /usr/bin/gcc /usr/bin/g++ /usr/bin/cpp                        && \
    alternatives --install /usr/bin/gcc gcc                               \
        /opt/rh/gcc-toolset-12/root/usr/bin/gcc    60                  && \
    alternatives --install /usr/bin/g++ g++                               \
        /opt/rh/gcc-toolset-12/root/usr/bin/g++    60                  && \
    alternatives --install /usr/bin/cpp cpp                               \
        /opt/rh/gcc-toolset-12/root/usr/bin/cpp    60                  && \
    dnf install -y                                                         \
        automake                                                          \
        bison                                                             \
        ca-certificates                                                   \
        diffutils                                                         \
        file                                                              \
        git                                                               \
        libasan                                                           \
        libtool                                                           \
        libubsan                                                          \
        openssl-devel                                                     \
        pcre2-devel                                                       \
        python3.11-devel                                                  \
        python3.11-pip                                                    \
        python3.11-pybind11-devel                                         \
        texinfo                                                           \
        unzip                                                             \
        wget                                                              \
        which                                                             \
        xerces-c-devel                                                    \
        yaml-cpp                                                          \
        yasm                                                              \
        ninja-build

# =============================================================================
# Compiler environment (GCC 12 toolset)
# =============================================================================
ENV PATH="/opt/rh/gcc-toolset-12/root/usr/bin:${PATH}" \
    CC="/opt/rh/gcc-toolset-12/root/usr/bin/gcc"       \
    CXX="/opt/rh/gcc-toolset-12/root/usr/bin/g++"      \
    FC="/opt/rh/gcc-toolset-12/root/usr/bin/gfortran"

RUN gcc --version && g++ --version && gfortran --version

# =============================================================================
# Python packages + convenience symlink
# BuildKit cache mount on pip avoids re-downloading wheels on rebuild.
# =============================================================================
RUN --mount=type=cache,target=/root/.cache/pip \
    python3.11 -m pip install "numpy==1.*"     && \
    ln -sf /usr/bin/python3.11 /usr/bin/python

# =============================================================================
# CMake — official binary distribution (avoids a full source build)
# =============================================================================
RUN wget -q "https://github.com/Kitware/CMake/releases/download/v${CMAKE_VERSION}/cmake-${CMAKE_VERSION}-linux-x86_64.sh" \
         -O /tmp/cmake-install.sh                              && \
    chmod +x /tmp/cmake-install.sh                            && \
    /tmp/cmake-install.sh --skip-license --prefix=/usr/local  && \
    rm /tmp/cmake-install.sh

# =============================================================================
# AliceVision paths
# =============================================================================
ENV AV_DEV="/opt/AliceVision_git"         \
    AV_BUILD="/tmp/AliceVision_build"     \
    AV_INSTALL="/opt/AliceVision_install" \
    PATH="/usr/local/bin:${PATH}"

# =============================================================================
# Static ML / data assets + environment variables
# Grouped into one RUN to avoid one layer per echo.
# =============================================================================
COPY dl/vlfeat_K80L3.SIFT.tree                 ${AV_INSTALL}/share/aliceVision/
COPY dl/sphereDetection_Mask-RCNN.onnx         ${AV_INSTALL}/share/aliceVision/
COPY dl/fcn_resnet50.onnx                      ${AV_INSTALL}/share/aliceVision/
COPY dl/ColorChartDetectionModel               ${AV_INSTALL}/share/aliceVision/ColorChartDetectionModel/

RUN { \
    echo "export ALICEVISION_VOCTREE=${AV_INSTALL}/share/aliceVision/vlfeat_K80L3.SIFT.tree"                                 ; \
    echo "export ALICEVISION_SPHERE_DETECTION_MODEL=${AV_INSTALL}/share/aliceVision/sphereDetection_Mask-RCNN.onnx"          ; \
    echo "export ALICEVISION_SEMANTIC_SEGMENTATION_MODEL=${AV_INSTALL}/share/aliceVision/fcn_resnet50.onnx"                  ; \
    echo "export ALICEVISION_COLORCHARTDETECTION_MODEL_FOLDER=${AV_INSTALL}/share/aliceVision/ColorChartDetectionModel"      ; \
    } >> /etc/profile.d/alicevision.sh

# =============================================================================
# CPU core detection helper
# =============================================================================
COPY docker/check-cpu.sh ${AV_DEV}/docker/check-cpu.sh
RUN CPU_CORES=$(${AV_DEV}/docker/check-cpu.sh) && \
    echo "Build multithreading number of cores: ${CPU_CORES}"

# =============================================================================
# AliceVision CMake sources + pre-fetched dependency archives
# COPY instructions ordered from least to most frequently changed to maximise
# Docker layer cache reuse.
# =============================================================================
COPY CMakeLists.txt                        ${AV_DEV}/
COPY src/cmake/                            ${AV_DEV}/src/cmake/
COPY src/cmake/deps/                       ${AV_DEV}/src/cmake/deps/
COPY src/cmake/OFA/                        ${AV_DEV}/src/cmake/OFA/
COPY dl/deps                               ${AV_BUILD}/external/download/

# =============================================================================
# Configure + build all dependencies
#
# Grouped into one RUN so the large build artefacts (AV_BUILD) are removed
# in the same layer, keeping the final image size minimal.
# =============================================================================
WORKDIR "${AV_BUILD}"

RUN mkdir -p "${AV_INSTALL}/bin"                 \
    && mkdir -p "${AV_INSTALL}/lib"                  \
    && cmake "${AV_DEV}"                               \
        -DCMAKE_BUILD_TYPE=Release                  \
        -DALICEVISION_BUILD_DEPENDENCIES:BOOL=ON    \
        -DAV_BUILD_ALICEVISION:BOOL=OFF             \
        -DAV_BUILD_ZLIB:BOOL=ON                     \
        -DAV_BUILD_CCTAG:BOOL=ON                    \
        -DCMAKE_INSTALL_PREFIX="${AV_INSTALL}"      \
        -DAV_BUILD_DEPENDENCIES_PARALLEL=0          \
    && ln -sf lib "${AV_INSTALL}/lib64"             \
    && { test -e /usr/local/cuda/lib64/libcublas.so \
         || ln -s /usr/lib/x86_64-linux-gnu/libcublas.so \
                  /usr/local/cuda/lib64/libcublas.so; }  \
    && CPU_CORES=$(${AV_DEV}/docker/check-cpu.sh)   \
    && cmake --build . --parallel 1    \
    && mv "${AV_INSTALL}/bin" "${AV_INSTALL}/bin-deps" \
    && rm -rf "${AV_BUILD}"
