#!/bin/bash
# Don't clobber/overwrite existing files
# Write the new file .rpmnew
testfile() {
	if [ -e "$1" ]; then
		echo "$1.rpmnew"
	else
		echo "$1"
	fi
}

# Remove .rpmnew files if they are identical
# otherwise record in manifest
modprocess() {
	if [ "${1/.rpmnew/}" != "$1" ]; then
		if cmp "${1/.rpmnew/}" "$1"; then
			rm "$1"
			return
		fi
	fi
	md5sum "${modname}" >>/opt/ohpc/pub/moduledeps/intel/impi/.rpm-manifest
}

# Create an OpenHPC module file for each version found in compilers
rm -f /opt/ohpc/pub/moduledeps/intel/impi/.rpm-manifest

# Regenerate the oneAPI modules directory (since MPI may have just been added)
echo "Generating new oneAPI modulefiles"
/opt/intel/oneapi/modulefiles-setup.sh --ignore-latest --force --output-dir=/opt/ohpc/pub/moduledeps/oneapi/ >/dev/null
if [ ! -d /opt/ohpc/pub/moduledeps/oneapi/compiler ]; then
	echo "ERROR: Failed to create oneAPI module directory"
	exit 1
fi

# Set system defaults for default OBS oneAPI modules
# shellcheck disable=SC2043
for tool in compiler/2025.0.0 mkl/2025.0 compiler-rt/2025.0.0 debugger/2025.0.0 tbb/2022.0.0; do
	filename="/opt/ohpc/pub/moduledeps/oneapi/${tool%%/*}/.version"
	echo "#%Module1.0" >"${filename}"
	echo "set ModulesVersion \"${tool##*/}\"" >>"${filename}"
done

# Create an OpenHPC module file for each MPI version found
echo "Creating OpenHPC-style modulefiles for local oneAPI MPI installation(s)."
for mpis in /opt/ohpc/pub/moduledeps/oneapi/mpi/2*; do
	ver=$(basename "${mpis}")
	echo "--> Installing modulefile for version=${ver}"
	modname=$(testfile /opt/ohpc/pub/moduledeps/intel/impi/"${ver}")

	# Get value for MPI_DIR
	eval "$(/opt/ohpc/admin/lmod/lmod/libexec/lmod --expert use /opt/ohpc/pub/moduledeps/oneapi)"
	# shellcheck disable=SC2086
	eval "$(/opt/ohpc/admin/lmod/lmod/libexec/lmod --expert load mpi/"${ver}")"
	MPIDIR=${I_MPI_ROOT}
	# shellcheck disable=SC2086
	eval "$(/opt/ohpc/admin/lmod/lmod/libexec/lmod --expert unload mpi/"${ver}")"
	eval "$(/opt/ohpc/admin/lmod/lmod/libexec/lmod --expert unuse /opt/ohpc/pub/moduledeps/oneapi)"

	cat <<EOF >"${modname}"
#%Module1.0#####################################################################

set version "${ver}"

proc ModulesHelp { } {
global version
puts stderr "\nThis module loads the Intel MPI environment.\n"
puts stderr "   mpiifort  (Fortran source)"
puts stderr "   mpiicc    (C   source)"
puts stderr "   mpiicpc   (C++ source)"
puts stderr "\nVersion \$version\n"
}

module-whatis "Name: Intel MPI"
module-whatis "Version: \$version"
module-whatis "Category: library, runtime support"
module-whatis "Description: Intel MPI Library (C/C++/Fortran for x86_64)"
module-whatis "URL: http://software.intel.com/en-us/articles/intel-mpi-library"

# For convenience, redirect standard mpicc/mpicxx/mpifort
# to use oneAPI icc/icpc/ifort instead of gcc/g++/gfortran
setenv I_MPI_CC   icx
setenv I_MPI_CXX  icpx
setenv I_MPI_FC   ifx
setenv I_MPI_F77  ifx
setenv I_MPI_F90  ifx

setenv MPI_DIR    "${MPIDIR}"

prepend-path      MODULEPATH       /opt/ohpc/pub/moduledeps/oneapi
prepend-path      MODULEPATH       /opt/ohpc/pub/moduledeps/intel-impi

module load "mpi/\$version"

prepend-path    LIBRARY_PATH    "${MPIDIR}/libfabric/lib"
prepend-path    LIBRARY_PATH    "${MPIDIR}/lib"

family "MPI"
EOF

	modprocess "${modname}"

	modname=$(testfile /opt/ohpc/pub/moduledeps/gnu/impi/"${ver}")

	cat <<EOF >"${modname}"
#%Module1.0#####################################################################

set version "${ver}"

proc ModulesHelp { } {
global version
puts stderr "\nThis module loads the Intel MPI environment for use with the GNU"
puts stderr "compiler toolchain\n"
puts stderr "mpif90       (Fortran source)"
puts stderr "mpicc        (C   source)"
puts stderr "mpicxx       (C++ source)"
puts stderr "\nVersion \$version\n"
}

module-whatis "Name: Intel MPI"
module-whatis "Version: \$version"
module-whatis "Category: library, runtime support"
module-whatis "Description: Intel MPI Library (C/C++/Fortran for x86_64)"
module-whatis "URL: http://software.intel.com/en-us/articles/intel-mpi-library/"

setenv MPI_DIR    "${MPIDIR}"

prepend-path    MODULEPATH      /opt/ohpc/pub/moduledeps/oneapi
prepend-path    MODULEPATH      /opt/ohpc/pub/moduledeps/gnu-impi

module load "mpi/\$version"

prepend-path    LIBRARY_PATH    "${MPIDIR}/libfabric/lib"
prepend-path    LIBRARY_PATH    "${MPIDIR}/lib"

family "MPI"
EOF

	modprocess "${modname}"

	# support for gnu major version
	orig_modname=${modname/.rpmnew/}
	modname=$(testfile /opt/ohpc/pub/moduledeps/gnu15/impi/"${ver}")
	cp "${orig_modname}" "${modname}"
	sed -i "s,/opt/ohpc/pub/moduledeps/gnu-impi,/opt/ohpc/pub/moduledeps/gnu15-impi," "${modname}"
	modprocess "${modname}"

done

# Default Intel(R) MPI Versions to match OpenHPC build version
modname=$(testfile /opt/ohpc/pub/moduledeps/intel/impi/.version)

cat <<EOF >"${modname}"
#%Module1.0#####################################################################
set     ModulesVersion      "2021.14"
EOF

modprocess "${modname}"

modname=$(testfile /opt/ohpc/pub/moduledeps/gnu/impi/.version)

cat <<EOF >"${modname}"
#%Module1.0#####################################################################
set     ModulesVersion      "2021.14"
EOF

modprocess "${modname}"

# support for gnu major version
orig_modname=${modname/.rpmnew/}
modname=$(testfile /opt/ohpc/pub/moduledeps/gnu15/impi/.version)
cp "${orig_modname}" "${modname}"
modprocess "${modname}"
