#!/bin/bash

# ===========================================================================================================
# title         : install_spack_env.sh
# usage         : ./install_spack_env.sh $INSTALLATION_ROOT $SPACK_VERSION $EBRAINS_REPO $EBRAINS_SPACK_ENV
# description   : installs or updates the spack environment defined in the EBRAINS spack repo
#                 (if the specified spack instance doesn't exist, it also creates it)
# ===========================================================================================================

INSTALLATION_ROOT=$1  # where to set up the installation
SPACK_VERSION=$2      # which spack version to use
EBRAINS_REPO=$3       # location of ebrains-spack-builds repository
EBRAINS_SPACK_ENV=$4  # name of EBRAINS Spack environment to be created/updated

# specify location of .spack dir (by default in ~)
# this is where cache and configuration settings are stored
export SPACK_USER_CACHE_PATH=$INSTALLATION_ROOT/spack/.spack
export SPACK_USER_CONFIG_PATH=$INSTALLATION_ROOT/spack/.spack

# initial setup: clone spack if spack dir doesn't already exist
if [ ! -d $INSTALLATION_ROOT/spack ]
then
  git clone --depth 1 -c advice.detachedHead=false -c feature.manyFiles=true --branch $SPACK_VERSION https://github.com/spack/spack $INSTALLATION_ROOT/spack
  # SPACK PATCH: the post-build logs on install-time-test-logs.txt gets ovewritten by the post-install logs.
  # quick fix for that: (TODO: investigate more and open PR)
  sed -i "s/self.file_like, \"w\"/self.file_like, \"a\"/g" $INSTALLATION_ROOT/spack/lib/spack/llnl/util/tty/log.py
fi

# activate Spack
source $INSTALLATION_ROOT/spack/share/spack/setup-env.sh

# install platform compiler (extract version from packages.yaml)
if [ $SYSTEMNAME == ebrainslab ]
then
  EBRAINS_SPACK_COMPILER=$(grep 'compiler' $EBRAINS_REPO/site-config/$SYSTEMNAME/packages.yaml | awk -F'[][]' '{ print $2 }')
  spack compiler find
  spack install $EBRAINS_SPACK_COMPILER
  spack load $EBRAINS_SPACK_COMPILER
fi

spack compiler find

# add repo if it does not exist
if [[ ! $(spack repo list | grep $EBRAINS_REPO) ]]
then
  spack repo add $EBRAINS_REPO
fi

# create environment if it does not exist
if [ ! -d "$SPACK_ROOT/var/spack/environments/$EBRAINS_SPACK_ENV" ]
then
  spack env create $EBRAINS_SPACK_ENV
fi

# activate environment
spack env activate $EBRAINS_SPACK_ENV
# update environment site-configs
rm -rf $SPACK_ENV/site-config && cp -r $EBRAINS_REPO/site-config $SPACK_ENV
# update spack.yaml: merge top-level and site-specific spack.yaml files
# TODO: find a more robust way to do this (maybe with yq? but we need to download the binary)
# TODO: or add pyyaml to dependencies and use python script
spack-python $EBRAINS_REPO/site-config/ymerge.py $EBRAINS_REPO/spack.yaml $EBRAINS_REPO/site-config/$SYSTEMNAME/spack.yaml > /tmp/spack.yaml
cp /tmp/spack.yaml $SPACK_ENV/

# There is a known spack bug (https://github.com/spack/spack/issues/29447) in installing test dependencies
# for installation tests. The workaround suggested in the issue is to NOT concretize separately, but simply
# remove the .lock file and let the environment be concretized by the spack install command:
rm $SPACK_ROOT/var/spack/environments/$EBRAINS_SPACK_ENV/spack.lock || echo "No spack.lock file"
# install the environment, use 2 jobs to reduce the amount of required RAM
spack install -y -j2 --fresh --test root

# rebuild spack's database
spack reindex

# create load script that when sourced activates and loads the installed spack environment, using views
# this needs deactivating the environment first:
spack env deactivate
unset SPACK_LD_LIBRARY_PATH
spack env activate --sh $EBRAINS_SPACK_ENV > $SPACK_ROOT/var/spack/environments/$EBRAINS_SPACK_ENV/load_env.sh

# create modules files with spack
# spack module tcl refresh -y
# create loads script that when sourced activates and loads the installed spack environment, using modules
# spack env loads -r
