#!/bin/bash
set -e -u  # exit on most (not all!) error codes, and error on unset variables

# Installs xios
# Rewritten 02/2024 A. Barral

function read_args {
  ## Defaults
  install_dir=$(pwd)

  xios_branch="2.6"
  xios_rev="2568"
  arch="local"
  make_j="8"
  # Not inputs
  hdf5_home=$(dirname "$(dirname "$(readlink -f "$(which h5pcc)")")")
  mpi_home=$(dirname "$(dirname "$(readlink -f "$(which mpif90)")")")

  while (($# > 0)); do
    case $1 in
      "-h") cat <<eof
      $0 [ -prefix path ]       where (path) to install (default: $install_dir)
      [ -branch branch]         XIOS branch trunk|2.5|2.6 (default: $xios_branch)
      [ -rev number ]           XIOS revision (default: $xios_rev)
      [ -arch ARCH ]            Use ARCH file (provided by XIOS) (default: make/use a local arch file)
      [ -make_j N ]             Number of procs for compilation
eof
      exit;;
      "-prefix") install_dir=$2; shift; shift;;
      "-branch") xios_branch=$2; shift; shift;;
      "-rev") xios_rev=$2; shift; shift;;
      "-arch") arch=$2; shift; shift;;
      "-make_j") make_j=$2; shift; shift;;
      *) echo "Error, bad argument $1"; $0 -h; exit
    esac
  done
}

function download_xios {
  # Install directory (get full path)
  mkdir -p "$install_dir"
  install_dir=$(cd "$install_dir" || exit 1; pwd -P)

  local xios_http
  case $xios_branch in
    "trunk") xios_http="http://forge.ipsl.jussieu.fr/ioserver/svn/XIOS/trunk";;
    "2.5") xios_http="http://forge.ipsl.jussieu.fr/ioserver/svn/XIOS/branchs/xios-2.5";;
    "2.6") xios_http="http://forge.ipsl.jussieu.fr/ioserver/svn/XIOS2/branches/xios-2.6";;
    *) echo "Error, bad argument for -branch ! Did not expect $xios_branch"; exit 1;;
  esac

  cd "$install_dir" || exit 1
  svn co --revision "$xios_rev" "$xios_http" XIOS
}

function create_local_arch {
  cd "$install_dir/XIOS/arch" || exit 1

  cat <<eof > arch-local.env
export MPI_LIB="-L${mpi_home}/lib -lmpi"

export NETCDFC_INC="\$(nc-config --includedir)"
export NETCDFC_LIB="\$(nc-config --libdir)"

export NETCDFF_INC="\$(nf-config --includedir)"
export NETCDFF_LIB="\$(nf-config --prefix)/lib"

export NETCDFCXX_INC="\$(ncxx4-config --includedir)"
export NETCDFCXX_LIB="\$(ncxx4-config --libdir)"
eof

  cat <<eof > arch-local.fcm
%CCOMPILER      "$(which mpicc)"
%FCOMPILER      "$(which mpif90)"
%LINKER         "$(which mpif90)"

%BASE_CFLAGS    -w -std=c++11 -D__XIOS_EXCEPTION
%PROD_CFLAGS    -O3 -D BOOST_DISABLE_ASSERTS
%DEV_CFLAGS     -g -O2
%DEBUG_CFLAGS   -g -DBZ_DEBUG

%BASE_FFLAGS    -D__NONE__ -ffree-line-length-none
%PROD_FFLAGS    -O3
%DEV_FFLAGS     -g -O2
%DEBUG_FFLAGS   -g

%BASE_INC       -D__NONE__
%BASE_LD        -lstdc++ -Wl,-rpath=${mpi_home}/lib

%CPP            $(which mpicc) -EP
%FPP            cpp -P
%MAKE           make
eof
  cat <<eof > arch-local.path
NETCDF_INCDIR="-I\${NETCDFC_INC} -I\${NETCDFF_INC} -I\${NETCDFCXX_INC}"
NETCDF_LIBDIR="-L\${NETCDFC_LIB} -L\${NETCDFF_LIB} -L\${NETCDFCXX_LIB}"
NETCDF_LIB="-lnetcdf -lnetcdff -lnetcdf_c++4"

HDF5_INCDIR="-I${hdf5_home}/include"
HDF5_LIBDIR="-L${hdf5_home}/lib"
HDF5_LIB="-lhdf5_hl -lhdf5 -lz -lcurl"
eof
}

function make_xios {
  cd "$install_dir/XIOS"
  echo "Compiling xios, see $(pwd)/make_xios.out"
  ./make_xios --arch "$arch" --job "$make_j" >make_xios.out 2>&1
}

read_args "$@"
download_xios
if [[ $arch = "local" ]]; then create_local_arch; fi
make_xios

