FROM debian:trixie-slim

# Metadata
LABEL maintainer="jmbatto"
LABEL description="Julia 1.12 (Source Build) on Debian Trixie with PDI/GTK - Optimized for stability"

# Build Arguments
ARG USER_ID=1001
ARG GROUP_ID=1001
ARG USER_NAME=coder
ARG JULIA_VERSION=v1.12.4
ARG PDI_VERSION=1.10.0

# -----------------------------------------------------------------------------
# 1. System Dependencies Installation
# -----------------------------------------------------------------------------
# Rationale:
# - 'neowofetch': Replaces 'neofetch' which has been removed from Debian Trixie repos.
# - 'python3-setuptools': REQUIRED for PDI compilation. Python 3.12+ (shipped with Trixie)
#   removed 'distutils', causing CMake/PDI detection scripts to fail without setuptools.
# - 'dbus-x11' & 'xvfb': Essential for running GTK applications in a headless Docker environment.
RUN apt-get update && apt-get install -y --no-install-recommends \
    # Build tools and base utilities
    build-essential cmake git pkg-config \
    gfortran which perl gawk m4 vim libatomic1 \
    nano sudo lsof jq neowofetch curl wget \
    gdb valgrind clang-format \
    ca-certificates iputils-ping colordiff \
    # Python Environment (with setuptools fix for Py3.12)
    python3 python3-dev python3-numpy python3-setuptools \
    # Scientific Libraries (MPI/PDI/HDF5)
    mpi-default-dev libhdf5-dev libz-dev \
    # Graphics Stack (X11, GTK4, OpenGL, DBus)
    libx11-6 libxext6 libxrender1 libxtst6 xauth xvfb dbus-x11 \
    libgl1-mesa-dri libgl1 \
    libgtk-4-1 libgtk-3-0 libglib2.0-0 libcairo2 \
    libpango-1.0-0 libharfbuzz0b \
    libgdk-pixbuf-2.0-0 libgdk-pixbuf2.0-bin \
    libgraphene-1.0-0 librsvg2-common \
    shared-mime-info \
    adwaita-icon-theme-full hicolor-icon-theme fonts-liberation \
    graphviz \
    && rm -rf /var/lib/apt/lists/*

# Fix: Generate machine-id to prevent GLib/GTK runtime errors regarding missing D-Bus UUID.
RUN dbus-uuidgen > /etc/machine-id

# Fix: Update GDK pixbuf loaders cache.
# Prevents runtime warnings/errors about missing image format loaders.
RUN LOADER_PATH=$(find /usr/lib -name gdk-pixbuf-query-loaders | head -n 1) && \
    ln -s $LOADER_PATH /usr/bin/gdk-pixbuf-query-loaders && \
    gdk-pixbuf-query-loaders --update-cache

# -----------------------------------------------------------------------------
# 2. JULIA COMPILATION
# -----------------------------------------------------------------------------
WORKDIR /tmp/julia-build
RUN git clone --depth 1 --branch ${JULIA_VERSION} https://github.com/JuliaLang/julia.git .

# Build Configuration (Make.user) - CRITICAL FIXES FOR DEBIAN TRIXIE
# 1. USE_SYSTEM_LIBUNWIND=0: Forces internal libunwind. System libunwind on Trixie causes Segfaults.
# 2. noexecstack: Security flag required by modern Linux kernels.
# 3. -gdwarf-4: CRITICAL FIX. GCC 13+ defaults to DWARF-5 debug format, which is incompatible
#    with Julia's current unwinder, leading to immediate Segfaults on startup.
RUN echo "prefix=/usr/local/julia" > Make.user && \
    echo "MARCH=x86-64" >> Make.user && \
    echo "USE_SYSTEM_LIBUNWIND=0" >> Make.user && \
    echo "LDFLAGS=-Wl,-z,noexecstack" >> Make.user && \
    echo "CFLAGS=-Wa,--noexecstack -gdwarf-4" >> Make.user && \
    echo "CXXFLAGS=-Wa,--noexecstack -gdwarf-4" >> Make.user

# Compile, Install, and Cleanup
# Cleanup is performed immediately to reduce final image size (~1GB saved).
ENV JULIA_PATH=/usr/local/julia
ENV PATH=$JULIA_PATH/bin:$PATH
RUN make -j$(nproc) && \
    make install && \
    rm -rf /tmp/julia-build

# -----------------------------------------------------------------------------
# 3. PDI INSTALLATION
# -----------------------------------------------------------------------------
ENV PDI_DIR=/usr/local
ENV LD_LIBRARY_PATH=/usr/local/lib:/usr/lib/x86_64-linux-gnu
ENV CPATH=/usr/local/include
ENV PREFIX=/usr/local

WORKDIR /tmp/pdi-build
# Build Configuration:
# - BUILD_PYTHON=ON & BUILD_PYCALL_PLUGIN=ON: Explicitly enabled to generate
#   'libpdi_pycall_plugin.so'. Required to prevent 'plugin not found' errors
#   when interacting with Python from Julia/PDI.
RUN git clone --depth 1 --branch ${PDI_VERSION} https://github.com/pdidev/pdi.git . && \
    mkdir build && cd build && \
    cmake \
        -DBUILD_MPI=OFF \
        -DBUILD_DECL_HDF5_PLUGIN=ON \
        -DBUILD_SHARED_LIBS=ON \
        -DBUILD_FORTRAN=OFF \
        -DBUILD_HDF5_PARALLEL=OFF \
        -DBUILD_PYTHON=ON \
        -DBUILD_PYCALL_PLUGIN=ON \
        -DBUILD_NETCDF_PARALLEL=OFF \
        -DCMAKE_INSTALL_PREFIX=/usr/local \
        .. && \
    make -j$(nproc) && \
    make install && \
    ldconfig && \
    cd / && rm -rf /tmp/pdi-build

# -----------------------------------------------------------------------------
# 4. USER CONFIGURATION & RUNTIME ENVIRONMENT
# -----------------------------------------------------------------------------
RUN groupadd -g ${GROUP_ID} ${USER_NAME} && \
    useradd -m -u ${USER_ID} -g ${USER_NAME} -s /bin/bash ${USER_NAME} && \
    echo "${USER_NAME} ALL=(ALL) NOPASSWD:ALL" >> /etc/sudoers

# RUNTIME ENVIRONMENT VARIABLES - CRITICAL SETTINGS
# 1. LD_LIBRARY_PATH: STRICTLY excludes '/usr/lib/x86_64-linux-gnu'.
#    Reason: Preventing "DLL Hell". Including system paths forces Julia to load system
#    libraries (e.g., system libglib) instead of its own Artifacts, causing undefined
#    symbol errors (e.g., 'g_string_copy'). We prioritize Julia and PDI libs.
ENV LD_LIBRARY_PATH=/usr/local/julia/lib:/usr/local/julia/lib/julia:/usr/local/lib

# 2. GTK_A11Y=none: Disables GTK Accessibility Bus to suppress "org.a11y.Bus" warnings in logs.
ENV GTK_A11Y=none

# 3. Graphics & Julia settings
ENV GKSwstype=100
ENV JULIA_PKG_PRECOMPILE_AUTO=0
ENV JULIA_PKG_USE_CLI_GIT=true
ENV DISPLAY=host.docker.internal:0.0
ENV PYTHONPATH=/usr/local/lib/python3/dist-packages

# Switch to non-root user for Package Installation
# Ensures ~/.julia permissions are correctly set for the user 'coder'.
USER ${USER_NAME}
WORKDIR /home/${USER_NAME}/project

# -----------------------------------------------------------------------------
# 5. JULIA PACKAGES INSTALLATION
# -----------------------------------------------------------------------------
# Optimization:
# - Operations are consolidated into a single RUN instruction to reduce Docker layer count.
# - xvfb-run: Executes in a virtual framebuffer. Essential for 'Pkg.precompile()'
#   of Gtk4 and ProfileView, which require a display server even during installation.




ENV LD_LIBRARY_PATH=/usr/local/julia/lib:/usr/local/julia/lib/julia:/usr/local/lib

RUN julia -e 'import Pkg; \
    Pkg.add([ \
		"Pkg", \
        "AbstractTrees", \
		"BenchmarkTools", \ 
		"Cairo_jll", \
		"Documenter", \ 
		"GeoInterface", \
		"GeometryBasics", \ 
		"HDF5", \ 
		"Interpolations", \ 
		"IterativeSolvers", \ 
		"JLD", \ 
		"LibGEOS", \ 
		"LinearAlgebra", \ 
		"LsqFit", \ 
		"MPI", \ 
		"MUMPS", \
		"MethodAnalysis", \ 
		"OffsetArrays", \ 
		"PProf", \
		"PackageCompiler", \ 
		"Parameters", \ 
		"Peaks", \
		"Polynomials", \
		"Printf", \ 
		"Profile", \ 
		"PropertyDicts", \
		"Revise", \ 
		"Roots", \ 
		"SnoopCompileCore", \
		"SparseArrays", \ 
		"SpecialFunctions", \
		"StaticArrays", \
		"Statistics", \ 
		"Test", \
		"YAML" \
	])'
RUN xvfb-run --auto-servernum --server-args="-screen 0 1920x1080x24 -nolisten tcp" \
	julia -e 'import Pkg; \
       Pkg.add([ \		
        "DataFrames", \
        "Gtk4", \
        "Gtk", \
        "ProfileView", \
        "PProf", \
        "Reexport" \
    ])'


ENV LD_LIBRARY_PATH=""
# hack to install julia package
RUN xvfb-run --auto-servernum --server-args="-screen 0 1920x1080x24 -nolisten tcp" \
    julia -e 'import Pkg; Pkg.precompile()'
RUN xvfb-run --auto-servernum --server-args="-screen 0 1920x1080x24 -nolisten tcp" \
    julia -e 'import Pkg; Pkg.update(); Pkg.precompile()'
ENV LD_LIBRARY_PATH=/usr/local/julia/lib:/usr/local/julia/lib/julia:/usr/local/lib



CMD ["/bin/bash"]