# Use Ubuntu 24.04 as base image.  Pinned to linux/amd64: ifx and the
# ifx_linux-64 conda package are x86_64-only, but ubuntu:24.04 is
# multi-arch, so on an arm64 host (e.g. Apple Silicon) an unpinned `docker
# build` silently pulls the arm64 variant and the Anaconda installer later
# crashes trying to unpack an x86_64 payload into it.
FROM --platform=linux/amd64 ubuntu:24.04

# Set environment variables
ENV DEBIAN_FRONTEND=noninteractive

# Version of the repository to build: leave unset (default) to build from
# this local checkout, including any uncommitted changes; set to a tag or
# commit hash (--build-arg GIT_REF=v0.9.0) to instead clone and check out
# that exact revision from GitHub, ignoring the local checkout.
ARG GIT_REF=""

# Install necessary packages.
# gcc is required by ifx, which gathers its GNU toolchain install paths
# from it (ifx error #10417 without it); no GNU Fortran is needed.
RUN apt-get update && apt-get install -y \
    wget \
    bzip2 \
    ca-certificates \
    curl \
    gcc \
    git \
    nano \
    vim \
    && apt-get clean \
    && rm -rf /var/lib/apt/lists/*

# Set up working directory
WORKDIR /app

# Install Anaconda
RUN wget https://repo.anaconda.com/archive/Anaconda3-2024.10-1-Linux-x86_64.sh -O /tmp/anaconda.sh \
    && bash /tmp/anaconda.sh -b -p /opt/anaconda \
    && rm /tmp/anaconda.sh

# Add Anaconda to PATH
ENV PATH="/opt/anaconda/bin:${PATH}"

# Initialize conda for bash shell
RUN echo ". /opt/anaconda/etc/profile.d/conda.sh" >> ~/.bash_profile
RUN echo ". /opt/anaconda/etc/profile.d/conda.sh" >> ~/.bashrc

# Copy environment.yaml file
COPY environment.yaml .

# Create conda environment from the yaml file (fpm and the python packages;
# no compiler -- environment.yaml is shared by every container, including
# the llvm/jupyter ones, which must never pull Intel's ifx), then add ifx on
# top of it specifically for this image.
RUN conda env create -f environment.yaml
RUN conda install -n band -c https://software.repos.intel.com/python/conda ifx_linux-64 --yes
RUN echo "conda activate band" >> ~/.bash_profile
RUN echo "conda activate band" >> ~/.bashrc

# Source - https://stackoverflow.com/a/39777387
# Posted by Ahmad Abdelghany, modified by community. See post 'Timeline' for change history
# Retrieved 2025-11-09, License - CC BY-SA 4.0
# this command, together with putting conda activation in .bash_profile, means we have
# enabled the conda environment for every command
SHELL ["/bin/bash", "--login", "-c"] 

# Stage the source: defaults to this local checkout; if GIT_REF is set,
# the RUN step below discards this and clones that revision instead.
COPY src /tmp/band_src/src/
COPY test /tmp/band_src/test
COPY app /tmp/band_src/app/
COPY fpm.toml /tmp/band_src/
COPY python /tmp/band_src/python/
COPY scripts /tmp/band_src/scripts/

RUN if [ -n "$GIT_REF" ]; then \
        echo "Building band_distribution @ $GIT_REF (overriding local checkout)" && \
        rm -rf /tmp/band_src && \
        git clone https://github.com/det-lab/band_distribution.git /tmp/band_src && \
        cd /tmp/band_src && git checkout "$GIT_REF"; \
    else \
        echo "Building band_distribution from the local checkout"; \
    fi

RUN mkdir -p /app/src /app/test /app/app /app/python /app/scripts \
    && cp -r /tmp/band_src/src/. /app/src/ \
    && cp -r /tmp/band_src/test/. /app/test/ \
    && cp -r /tmp/band_src/app/. /app/app/ \
    && cp -r /tmp/band_src/python/. /app/python/ \
    && cp -r /tmp/band_src/scripts/. /app/scripts/ \
    && cp /tmp/band_src/fpm.toml /app/ \
    && rm -rf /tmp/band_src

# version.f90.inc (PpqFort_version(); not committed, see the script) must
# exist before fpm build/test -- it is a plain `include` in src/PpqFort_m.f90
RUN python scripts/generate_version_include.py

# Link the Intel OpenMP runtime into everything fpm builds here (including
# interactive fpm invocations inside the container).  The ifx-compiled
# shared library references __kmpc_* symbols, and without -liomp5 the
# Python ctypes load of libband_distribution.so fails.  This lives here
# rather than in fpm.toml because libiomp5 is Intel-specific: the gfortran
# build uses libgomp (linked automatically by -fopenmp).
ENV FPM_LDFLAGS="-liomp5"

# Build the Fortran library and copy all shared objects to /app/lib so the
# Python ctypes wrapper can find them via LD_LIBRARY_PATH.
RUN fpm build --compiler ifx --flag "-fpp -O3 -qopenmp -DHAVE_MULTI_IMAGE_SUPPORT=0" --profile release \
    && mkdir -p /app/lib \
    && find /app/build -name "*.so" -exec cp {} /app/lib/ \;

# Needed to find the shared objects from within Python
# /opt/anaconda/envs/band/lib is where the ifx install above puts
# libiomp5.so (the Intel OpenMP runtime FPM_LDFLAGS=-liomp5 links against);
# without it here, this image's own CMD (fpm test, below) fails at startup
# with "libiomp5.so: cannot open shared object file" -- found and fixed
# 2026-09-30, pre-existing, unrelated to any of this file's other changes.
ENV LD_LIBRARY_PATH=/app/lib:/opt/anaconda/envs/band/lib:${LD_LIBRARY_PATH}

# Published normalization tables (python/cli/table_registry.json), fetched and
# hash-checked at build time -- HPC compute nodes often have no internet.
# python/cli/normtables.py (and so PpqPDF(ppqn_table=NAME)) finds them here.
ENV BAND_TABLES_DIR=/app/tables
RUN mkdir -p /app/tables && python /app/python/cli/normtables.py fetch --all

CMD fpm test --compiler ifx --flag "-fpp -O3 -qopenmp -DHAVE_MULTI_IMAGE_SUPPORT=0" --profile release \
    && echo "--- profile_driver output ---" \
    && fpm run profile_driver --compiler ifx --flag "-fpp -O3 -qopenmp -DHAVE_MULTI_IMAGE_SUPPORT=0" --profile release \
    && echo "--- chi-square smoke test (100 throws) ---" \
    && python /app/test/python/test_chisquare_nr_simulator.py 100
