function _install_spack() {
  if [ ! -e ${SPACK_ROOT} ]; then
    echo "Cloning to ${SPACK_ROOT}"
    git clone --depth 1 ${SPACK_URL} -b ${SPACK_BRANCH} ${SPACK_ROOT}
  fi

  _init_spack "$SPACK_INIT_CMD" "$SPACK_ROOT"

  if [ ! -z "${SPACK_UPSTREAMS}" ]; then
    UPSTREAMS_CONFIG=${SPACK_ROOT}/etc/spack/upstreams.yaml
    echo "upstreams:" > $UPSTREAMS_CONFIG
    i=0
    for UP in ${SPACK_UPSTREAMS}; do
      echo "Adding upstream repo to config $UPSTREAMS_CONFIG <= $UP"
      i=$((i+1))
      cat << EOF >> $UPSTREAMS_CONFIG
  spack-instance-$i:
      install_tree: $UP/spack/opt/spack
      modules:
        tcl: $UP/spack/share/spack/modules
EOF
    done
  fi

  if [ ! -z "${SPACK_EXTERNALS}" ] ; then
    for ext in ${SPACK_EXTERNALS}; do
      spack external find $ext
    done
  fi

  if [[ $(spack compiler info ${SPACK_COMPILER}) ]]; then
    echo "Found Compiler $(spack compiler info ${SPACK_COMPILER})"
  else
    if [[ $(spack load ${SPACK_COMPILER}) ]]; then
      echo "found the compiler ${SPACK_COMPILER} as a spack package at $(spack location --install-dir $SPACK_COMPILER)"
    else
      echo "could not find compiler, will now try to install it... this may take a while"
      spack install --reuse ${SPACK_COMPILER}
    fi
    spack compiler add $(spack location --install-dir $SPACK_COMPILER)
  fi
}

function _init_spack() {
  SPACK_INIT_CMD=$1
  SPACK_ROOT=$2
  if [ -z "$SPACK_INIT_CMD" ] && [ ! -z "${SPACK_ROOT}" ]; then
    echo "Empty SPACK_INIT_CMD -> trying to source config file of spack root: $SPACK_ROOT/share/spack/setup-env.sh"
    . $SPACK_ROOT/share/spack/setup-env.sh
  else
    echo "Executing SPACK_INIT_CMD: $SPACK_INIT_CMD"
    $SPACK_INIT_CMD
  fi
}

function load_spack() {
  export SPACK_INIT_CMD=$1
  export SPACK_ROOT=$2                 # i.e.: spack
  export SPACK_URL=$3                  # i.e.: https://github.com/spack/spack.git
  export SPACK_BRANCH=$4               # i.e.: develop
  export SPACK_EXTERNALS=$5            # i.e.: slurm
  export SPACK_COMPILER=$6             # i.e.: gcc@12.2.0
  export SPACK_DISABLE_LOCAL_CONFIG=$7 # i.e.: true
  export SPACK_USER_CACHE_PATH=$8      # i.e.: ${SPACK_ROOT}/spack_user_cache_path
  export SPACK_USER_CONFIG_PATH=$9     # i.e.: ${SPACK_ROOT}/spack_user_config_path
  export SPACK_UPSTREAMS=${10}         # i.e.: pre-existing spack installs to use as upstream repos

  if [ "$SPACK_DISABLE_LOCAL_CONFIG" != "True" ]; then
    unset SPACK_DISABLE_LOCAL_CONFIG
  fi

  echo "SPACK_INIT_CMD                = $SPACK_INIT_CMD"
  echo "SPACK_ROOT                    = $SPACK_ROOT"
  echo "SPACK_URL                     = $SPACK_URL"
  echo "SPACK_BRANCH                  = $SPACK_BRANCH"
  echo "SPACK_EXTERNALS               = $SPACK_EXTERNALS"
  echo "SPACK_COMPILER                = $SPACK_COMPILER"
  echo "SPACK_DISABLE_LOCAL_CONFIG    = ${SPACK_DISABLE_LOCAL_CONFIG:-False}"
  echo "SPACK_USER_CACHE_PATH         = $SPACK_USER_CACHE_PATH"
  echo "SPACK_USER_CONFIG_PATH        = $SPACK_USER_CONFIG_PATH"
  echo "SPACK_UPSTREAMS               = $SPACK_UPSTREAMS"

  if [ -z "$SPACK_USER_CACHE_PATH" ]; then
    unset SPACK_USER_CACHE_PATH
  fi

  if [ ! -z "${SPACK_ROOT}" ] ; then _install_spack; fi

  if [ -z "$SPACK_USER_CONFIG_PATH" ]; then
    unset SPACK_USER_CONFIG_PATH
  fi

  _init_spack "$SPACK_INIT_CMD" "$SPACK_ROOT"

  echo "Using spack from $(which spack)"
}
