#!/usr/bin/env bash
# 
declare -a LIST_MPIFWRAP
LIST_MPIFWRAP=( 'mpif90' 'mpifort' 'mpiifort' 'mpifc' 'mpixlf_r' 'mpixlf' 'mpif77' 'mpifrt' 'mpifrtpx' 'mpif90-mpich-mp' 'mpifort-mpich-mp' 'mpif90-openmpi-mp' 'mpifort-openmpi-mp')
export LIST_MPIFWRAP
declare -a LIST_MPICWRAP
LIST_MPICWRAP=( 'mpicc' 'mpixlc_r' 'mpixlc' 'mpigcc' 'mpiicc' 'mpifcc' 'mpifccpx' 'mpicc-mpich-mp' 'mpicc-openmpi-mp')
export LIST_MPICWRAP
function usage()
{
   cat <<EOF
Options:

  --help             usage
  --mpi_include      extracts MPI_INCLUDE
  --mpi_lib          extracts MPI_LIB
  --libmpi           extracts LIBMPI

EOF
}
function get_mpi_fortran_wrapper()
{
   # Apparently it is too easy to call the MPI Fortran compiler wrapper mpif90.
   # So now there is a variety of such scripts which may or may not be available
   # on your machine. This function tries to find a Fortran compiler wrapper
   # from a given list and returns the first one it finds.
   lib=""
   length=${#LIST_MPIFWRAP[*]}
   indx=0
   while [ "${indx}" -lt "${length}" ] ; do
     candidate="${LIST_MPIFWRAP[${indx}]}"
     ((indx++))
     if [ ${#wrapper} -eq 0 ] ; then
       wrapper=`which ${candidate} 2> /dev/null`
     fi
   done
   if [ ${#wrapper} -eq 0 ] ; then
     # We have not found anything suitable
     echo "notfound"
     exit 1
   fi
   echo ${wrapper}
}
function get_mpi_include ()
{
   # This shell function extracts the MPI include file directories
   # and returns them as a list for a compile line.
   # E.g.: /usr/include -I/usr/local/include
   #
   # Most support -show
   #
   inlist="`${NWCHEM_MPIF_WRAP} -show`"
   result=$?
   if [ ${result} -ne 0 ] ; then
     #
     # OPENMPI supports -showme
     #
     inlist="`${NWCHEM_MPIF_WRAP} -showme`"
     result=$?
   fi
   if [ ${result} -ne 0 ] ; then
     #
     # MPICH2 and MVAPICH2 support -link-info
     #
     inlist="`${NWCHEM_MPIF_WRAP} -link-info`"
     result=$?
   fi
   if [ ${result} -ne 0 ] ; then
     echo "ERROR: cannot get compile info from ${NWCHEM_MPIF_WRAP}" > /dev/stderr
     exit 1
   fi
   outlist=""
   for word in ${inlist} ; do
      len=`echo "${word}" | grep -o "^-I" 2>/dev/null | wc -c`
      if [ ${len} -ge 3 ] ; then
        outlist="${outlist} ${word}"
      fi
   done
#  len=`expr "${outlist}" : ' -I*'`
#  if [ ${len} -ge 3 ] ; then
#    outlist="${outlist:3}"
#  fi
   echo ${outlist} | cut -c 3-
}
function get_mpi_link ()
{
   # This shell function extracts the MPI library file directories
   # and returns them as a list for a link line.
   # E.g.: /usr/lib -L/usr/local/lib
   #
   # most support -show
   #
   inlist="`${NWCHEM_MPIF_WRAP} -show`"
   result=$?
   if [ ${result} -ne 0 ] ; then
     #
     # OPENMPI supports -showme
     #
     inlist="`${NWCHEM_MPIF_WRAP} -showme`"
     result=$?
   fi
   if [ ${result} -ne 0 ] ; then
     #
     # Otherwise try -link-info
     #
     inlist="`${NWCHEM_MPIF_WRAP} -link-info`"
     result=$?
   fi
   if [ ${result} -ne 0 ] ; then
     echo "ERROR: cannot get link info from ${NWCHEM_MPIF_WRAP}" > /dev/stderr
     exit 1
   fi
   outlist=""
   for word in ${inlist} ; do
      len=`echo "${word}" | grep -o "^-L" | wc -c`
      if [ ${len} -ge 3 ] ; then
        outlist="${outlist} ${word}"
      fi
   done
#  len=`expr "${outlist}" : ' -L*'`
#  if [ ${len} -ge 3 ] ; then
#    outlist="${outlist:3}"
#  fi
   echo ${outlist} | cut -c 3-
}
function get_mpi_lib ()
{
   # This shell function extracts the MPI libraries
   # and returns them as a list for a link line.
   # E.g.: -lmpich
   #
   # Most support -show
   #
   inlist="`${NWCHEM_MPIF_WRAP} -show`"
   result=$?
   if [ ${result} -ne 0 ] ; then
     #
     # OPENMPI supports -showme
     #
     inlist="`${NWCHEM_MPIF_WRAP} -showme`"
     result=$?
   fi
   if [ ${result} -ne 0 ] ; then
     #
     # MPICH2 and MVAPICH2 support -link-info
     #
     inlist="`${NWCHEM_MPIF_WRAP} -link-info`"
     result=$?
   fi
   if [ ${result} -ne 0 ] ; then
     echo "ERROR: cannot get library info from ${NWCHEM_MPIF_WRAP}" > /dev/stderr
     exit 1
   fi
   outlist=""
   for word in ${inlist} ; do
      len=`echo "${word}" | grep -o "^-l" | wc -c`
      if [ ${len} -ge 3 ] ; then
        outlist="${outlist} ${word}"
      fi
   done
   # homebrew hwloc
   if command -v pkg-config >& /dev/null ; then
    if pkg-config --exists hwloc; then
	outlist="${outlist} $(pkg-config --libs-only-L hwloc 2> /dev/null) -lhwloc"
    fi
   fi
   echo ${outlist}
}
function get_mpi_fortran ()
{
   # This shell function extracts the fortran compiler
   # and returns its name as a list for a compile line.
   # E.g.: gfortran
   #
   # Most support -show
   #
   inlist="`${NWCHEM_MPIF_WRAP} -show`"
   result=$?
   if [ ${result} -ne 0 ] ; then
     #
     # OPENMPI supports -showme
     #
     inlist="`${NWCHEM_MPIF_WRAP} -showme`"
     result=$?
   fi
   if [ ${result} -ne 0 ] ; then
     #
     # MPICH2 and MVAPICH2 support -compile-info
     #
     inlist="`${NWCHEM_MPIF_WRAP} -compile-info`"
     result=$?
   fi
   if [ ${result} -ne 0 ] ; then
     echo "ERROR: cannot get compile info from ${NWCHEM_MPIF_WRAP}" > /dev/stderr
     exit 1
   fi
   outlist=""
   length=${#LIST_COMPFLAGS[*]}
   for word in ${inlist} ; do
      echo "c23456 test program">/tmp/$$.f
      echo "       program test">>/tmp/$$.f
      echo "       write(6,'(\"hello world\")')">>/tmp/$$.f
      echo "       end">>/tmp/$$.f
      word=`basename ${word}`
      indx=0
      while [ "${indx}" -lt "${length}" ] ; do
         flags=${LIST_COMPFLAGS[$indx]}
         ((indx++))
         ${word} ${flags} -o /tmp/$$.x /tmp/$$.f
         result=$?
         if [ ${result} -eq 0 ] ; then
           /tmp/$$.x > /dev/null
           result=$?
           if [ ${result} -eq 0 ] ; then
             echo ${word}
             rm -f /tmp/$$.x /tmp/$$.o /tmp/$$.f
             return 0
           fi
         fi
      done
   done
   rm -f /tmp/$$.x /tmp/$$.o /tmp/$$.f
   echo "ERROR: could not find a valid Fortran compiler" > /dev/stderr
   exit 1
}
# args here
option=$1
if [ "$option" != "--help" ] ; then
  NWCHEM_MPIF_WRAP=`get_mpi_fortran_wrapper`
   if [ "${NWCHEM_MPIF_WRAP}" == "notfound" ] ; then
     echo 'mpif90notfound'
     exit
   fi
fi
if [ "$option" == "--help" ] ; then
  usage
  exit 1
elif [ "$option" == "" ] ; then
  echo > /dev/null
elif [ "$option" == "--mpi_include" ] ; then
  MPI_INCLUDE=`get_mpi_include`
echo ${MPI_INCLUDE}
exit 0
elif [ "$option" == "--mpi_lib" ] ; then
  MPI_LIB=`get_mpi_link`
echo ${MPI_LIB}
exit 0
elif [ "$option" == "--libmpi" ] ; then
  echo `get_mpi_lib`
exit 0
else
  usage
  exit 1
fi

#
  MPI_INCLUDE=`get_mpi_include`
  MPI_LIB=`get_mpi_link`
  LIBMPI=`get_mpi_lib`
echo "export MPI_INCLUDE="\"${MPI_INCLUDE}\"
#
echo "export MPI_LIB="\"${MPI_LIB}\"
#
echo "export LIBMPI="\"${LIBMPI}\"
#
