#!/bin/csh

set prog = $0
set prog = $prog:t

set log_file = cfg.log
if( -e $log_file ) then
  rm -f $log_file >& /dev/null
endif

#------------------------------------------------------------
#  set temp work file
#------------------------------------------------------------
@ flno = $$
set tmp_flsp = mz.cfg.$flno

#------------------------------------------------------------
#  check op sys
#------------------------------------------------------------
set op_sys = `uname -s | tr '[a-z]' '[A-Z]'`
echo " " > $log_file
echo "=======================================================================" >> $log_file
echo "======================================================================="
echo "The operating system is : "$op_sys >> $log_file
#------------------------------------------------------------
#  make_mz4 only handles linux, unix, OS X, or AIX op sys
#------------------------------------------------------------
if( $op_sys == LINUX || $op_sys == UNIX || $op_sys == DARWIN ) then
  set op_sys = LINUX
  set mpi_cmd = mpif90
else if( $op_sys == AIX ) then
  set mpi_cmd = mpxlf95_r
else
  echo "$prog only works for Linux, Unix, OS X, or AIX op systems"
  exit 1
endif

set data_dir_opt = 0

if( $#argv > 0 ) then
#---------------------------------------
#  process arguments
#---------------------------------------
  set args1 = ($argv)
  set args = `echo $args1 | tr '[a-z]' '[A-Z]'`
#---------------------------------------
#  check for command information
#---------------------------------------
  if( $args[1] == HELP ) then
    set help_file = docs/README.cfg
    echo " "
    which less >& /dev/null
    if( ! $status ) then
      cat $help_file | less
    else
      which more >& /dev/null
      if( ! $status ) then
        cat $help_file | more
      else
        cat $help_file
      endif
    endif
    echo " "
    exit 0
  endif
#---------------------------------------
#  iterate over arguments
#---------------------------------------
  foreach argument ($args)
    foreach keyword (NCD_DIR MPI_DIR SITE MODEL DATA_DIR QUE_CMD)
      echo $argument | grep "$keyword=" >& /dev/null
      if( ! $status ) then
        if( $keyword == NCD_DIR ) then
          set ncd_dir = `echo $args1[1] | cut -d= -f2`
          if( ! -d $ncd_dir ) then
            unset ncd_dir
          endif
        else if( $keyword == MPI_DIR ) then
          set mpi_dir = `echo $args1[1] | cut -d= -f2`
          if( ! -d $mpi_dir ) then
            unset mpi_dir
          endif
        else if( $keyword == DATA_DIR ) then
          set data_dir = `echo $args1[1] | cut -d= -f2`
          if( ! -d $data_dir ) then
            set data_dir_opt = 1
            set inp_data_dir = $data_dir
            unset data_dir
          endif
        else if( $keyword == SITE ) then
          set site = `echo $args1[1] | cut -d= -f2`
        else if( $keyword == MODEL ) then
          set model = `echo $argument | cut -d= -f2`
        else if( $keyword == QUE_CMD ) then
          set que = `echo $args1[1] | cut -d= -f2`
        endif
        break
      else
        continue
      endif
    end
    shift args1
  end
endif

echo " " >> $log_file
#------------------------------------------------------------
#  check for gnu make (gmake)
#------------------------------------------------------------
set found_gmake = 0
foreach file (gmake gnumake)
  which $file >& /dev/null
  if( ! $status ) then
    if( $file == "gnumake" ) then
      set gmake_flsp = `which $file` 
    endif
    set found_gmake = 1
  endif
end

if( $found_gmake ) then
  echo "gmake is in the execution path" >> $log_file
else
  echo "gmake is NOT in the execution path" >> $log_file
endif

#------------------------------------------------------------
#  check default model if set
#------------------------------------------------------------
if( $?model ) then
  set found = 0
  foreach mode (HYB MPI OMP SNG)
    if( $model == $mode ) then
      set found = 1
      break
    endif
  end
  if( ! $found ) then
    cat << EOM

    $prog option "model=$model" not in set {HYB,MPI,OMP,SNG}

    (1) hybrid -(combination mpi & openmp)
    (2) mpi only
    (3) openmp only
    (4) single cpu
    (5) quit $prog

EOM
    echo -n "Enter number of one of above options : "
    set ans = $<
    if( $ans < 1 || $ans > 5 ) then
      echo "response, $ans, not in range [1..5]; $prog terminating"
      exit -1
    endif
    switch ($ans)
      case 1
        set model = HYB
        breaksw
      case 2
        set model = MPI
        breaksw
      case 3
        set model = OMP
        breaksw
      case 4
        set model = SNG
        breaksw
      case 5
        exit 0
    endsw

    
  endif
endif


echo " " >> $log_file

if( ! $?mpi_dir ) then
#------------------------------------------------------------
#  mpi_dir not set via argument, check for mpif90 script in $PATH
#------------------------------------------------------------
  which $mpi_cmd >& /dev/null
  if( ! $status ) then
    set mpif90_flspec = `which $mpi_cmd`
  endif
else
#------------------------------------------------------------
#  mpi_dir set via argument, check for existence
#------------------------------------------------------------
  set mpif90_flspec = "$mpi_dir/$mpi_cmd"
  if( ! -e $mpif90_flspec ) then
    unset mpif90_flspec
  endif
endif

if( $?mpif90_flspec ) then
  echo "$mpi_cmd filepath : "$mpif90_flspec:h >> $log_file
else
#------------------------------------------------------------
#  mpif90 script either not in $PATH or input argument,
#  "mpi_dir=" didn't exist; check usual location(s)
#------------------------------------------------------------
  set nonomatch
  foreach tst_dir (/usr/local/*mpich2* /usr/*mpich2* /opt/*mpich2* /usr/local/*mpi* /usr/local /usr /opt)
    if( -d $tst_dir ) then
      ../utils/mzloc $tst_dir $mpi_cmd $tmp_flsp
      set cstatus = $status
      if( ! $cstatus ) then
        echo "$mpi_cmd script found in $tst_dir/.." >> $log_file
        break
      endif
    endif
  end
#------------------------------------------------------------
#  if mpif90 found set full filespec
#------------------------------------------------------------
  if( -e $tmp_flsp && ! -z $tmp_flsp ) then
    set paths = `cat $tmp_flsp`
    if( $#paths > 0 ) then
      echo "$mpi_cmd paths :" >> $log_file
      echo $paths >> $log_file
      set mpif90_flspec = $paths[1]
    endif
  endif
endif

#------------------------------------------------------------
#  if mpif90 found check that it is an executable, plain file
#------------------------------------------------------------
if( $?mpif90_flspec && $op_sys == LINUX ) then
  if( -x $mpif90_flspec ) then
    file $mpif90_flspec | grep -i link >& /dev/null
    set gstatus = $status
    if( $gstatus ) then
      file $mpif90_flspec | grep -i script >& /dev/null
      set gstatus = $status
      if( $gstatus ) then
        file $mpif90_flspec | grep -i ascii >& /dev/null
        set gstatus = $status
        if( $gstatus ) then
          echo " " ; echo " " >> $log_file
          set string = "Warning: $mpif90_flspec is not a script file"
          echo $string ; echo $string >> $log_file
          unset mpif90_flspec
        endif
      endif
    endif
  else
    echo " " ; echo " " >> $log_file
    set string = "Warning: $mpif90_flspec is not an executable file"
    echo $string ; echo $string >> $log_file
    unset mpif90_flspec
  endif
endif

if( -e $tmp_flsp ) then
  rm -f $tmp_flsp >& /dev/null
endif

echo " " >> $log_file
set comp_tags = (pgf9 ifort lf9)
set comp_ndx  = 0
@ flno++
set tmp1_flsp = mz.cfg.$flno
#------------------------------------------------------------
#  if mpif90 found then get fortran90 compiler from mpif90 script
#------------------------------------------------------------
if( $?mpif90_flspec && $op_sys == LINUX ) then
  foreach comp ($comp_tags)
    set string = 'F90="'"$comp"
    grep $string $mpif90_flspec > $tmp_flsp
    set gstatus=$status
    if( ! $gstatus ) then
      sed 's/"//g' $tmp_flsp > $tmp1_flsp
      set compiler = `grep $comp $tmp1_flsp | cut -d= -f2`
      switch( "$comp" )
        case pgf9
          set comp_ndx  = 1
          breaksw
        case ifort
          set comp_ndx  = 2
          breaksw
        case lf9
          set comp_ndx = 3
          breaksw
      endsw
      break
    else
      rm -f $tmp_flsp >& /dev/null
    endif
  end
endif

if( -e $tmp_flsp ) then
  rm -f $tmp_flsp >& /dev/null
endif
if( -e $tmp1_flsp ) then
  rm -f $tmp1_flsp >& /dev/null
endif

if( $comp_ndx > 0 ) then
  echo " "
  set string = "compiler is : $compiler"
  echo $string ; echo $string >> $log_file
endif

echo " " >> $log_file
if( $comp_ndx == 0 ) then
#------------------------------------------------------------
#  if couldn't find mpif90 then check for fortran90 compiler(s)
#  in execution path; AIX will automatically do this
#------------------------------------------------------------
  foreach comp (pgf90 ifort lf95 xlf95_r)
    which $comp >& /dev/null
    if( ! $status ) then
      switch( "$comp" )
        case pgf90
          set comp_ndx = 1
          breaksw
        case ifort
          set comp_ndx = 2
          breaksw
        case lf95
          set comp_ndx = 3
          breaksw
        case xlf95_r
          set comp_ndx = 4
      endsw
      break
    endif
  end

  if( $comp_ndx > 0 ) then
    set compiler = `which $comp`
    set compiler = $compiler:t
  endif
else
#------------------------------------------------------------
#  found compiler from mpif90 script
#  check to make sure its in the execution path
#------------------------------------------------------------
  which $compiler > /dev/null
  if( $status ) then
    set comp_ndx = 0
    echo "$compiler is NOT in the execution path" >> $log_file
  endif
endif

if( $comp_ndx > 0 ) then
  set compilers=("Portland Group pgf90" "Intel ifort" "Lahey lf95" "IBM xlf")
  switch( $comp_ndx )
    case 1
      set string="$compilers[1]"
      breaksw
    case 2
      set string="$compilers[2]"
      breaksw
    case 3
      set string="$compilers[3]"
      breaksw
    case 4
      set string="$compilers[4]"
      breaksw
    endsw
    echo "$string is in the execution path" >> $log_file
endif

#------------------------------------------------------------
#  simple compiler check
#------------------------------------------------------------
if( $comp_ndx > 0 ) then
  set tmp_flsp = "test.F90"
  if( -e $tmp_flsp ) then
    rm -f $tmp_flsp >& /dev/null
  endif
  cat > $tmp_flsp << EOT
      program test
      implicit none
      real :: pi
      pi = atan(1.)
      end program test
EOT
  if( -e test ) then
    rm -f test >& /dev/null
  endif
  if( $op_sys == LINUX ) then
    set cmp_args = ""
  else
    set cmp_args = "-qfree -qsuffix=f=f90:cpp=F90"
  endif
  $compiler -o test $tmp_flsp $cmp_args >& /dev/null
  set cstatus = $status
  echo " " >> $log_file
  if( $cstatus ) then
    echo "$compiler test failed" >> $log_file
    unset compiler
  else
    echo "$compiler test successful" >> $log_file
  endif
  rm -f $tmp_flsp >& /dev/null
else
  set cstatus = 1
endif

#------------------------------------------------------------
#  simple mpi compilation script check
#------------------------------------------------------------
if( ! $cstatus && $?mpif90_flspec ) then
  cat > $tmp_flsp << EOT
      program test
      implicit none
      integer :: iret
      real    :: pi
#include <mpif.h>
      pi = atan(1.)
      call mpi_init( iret )
      end program test
EOT
  echo " " >> $log_file
  if( $op_sys == LINUX ) then
    set cmp_args = ""
  else
    set cmp_args = "-qfree -qsuffix=f=f90:cpp=F90"
  endif
  $mpif90_flspec -o test $tmp_flsp $cmp_args >& /dev/null
  set cstatus = $status
  if( $cstatus ) then
    echo "!!! $mpi_cmd test failed !!!" >> $log_file
    unset mpif90_flspec
    if( $?model ) then
      set model = OMP
    else if( $model != SNG ) then
      set model = OMP
    endif
  else
    echo "$mpi_cmd test successful" >> $log_file
  endif
  if( -e test ) then
    rm -f test >& /dev/null
  endif
endif

if( -e $tmp_flsp ) then
  rm -f $tmp_flsp >& /dev/null
endif

echo " " >> $log_file

set ncf_pass = 0
set found_ncf_lib = 0
if( ! $?ncd_dir ) then
#------------------------------------------------------------
#  check for netcdf library
#------------------------------------------------------------
  foreach tst_dir (/usr/local /usr /opt)
    foreach tst_lib (lib64 lib netcdf)
      if( -e $tst_dir/$tst_lib/libnetcdf.a ) then
         set found_ncf_lib = 1
         break
      endif
    end
    if( $found_ncf_lib ) then
      break
    endif
  end
else
  set tst_dir = $ncd_dir
  if( -e $tst_dir/libnetcdf.a ) then
    set found_ncf_lib = 1
    set tst_lib = $tst_dir:t
    set tst_dir = $tst_dir:h
  endif
endif

if( $found_ncf_lib ) then
  echo "Netcdf library in "$tst_dir"/$tst_lib" >> $log_file
endif

if( -e $tmp_flsp ) then
  rm -f $tmp_flsp >& /dev/null
endif
if( -e $tmp1_flsp ) then
  rm -f $tmp1_flsp >& /dev/null
endif

set found_ncf_inc=0
if( $found_ncf_lib ) then
#------------------------------------------------------------
#  check for netcdf include file
#------------------------------------------------------------
  set flsp = $tst_dir/include/netcdf.inc
  if( -e $flsp ) then
     set found_ncf_inc=1
  endif
  if( $found_ncf_inc ) then
#------------------------------------------------------------
#  check netcdf library for large file support
#------------------------------------------------------------
    grep -i 'nf_64bit_offset' $flsp >& /dev/null
    if( $status ) then
      echo "Netcdf library does NOT support large files" >> $log_file
    else
      echo "Netcdf library supports large files" >> $log_file
    endif
  else
    echo "Can not locate Netcdf include file netcdf.inc" >> $log_file
  endif
else
  echo "Can not locate Netcdf library libnetcdf.a" >> $log_file
endif

#------------------------------------------------------------
#  simple netcdf test
#------------------------------------------------------------
if( $?compiler && $found_ncf_lib && $found_ncf_inc ) then
  set tmp_flsp = "test.F90"
  if( -e $tmp_flsp ) then
    rm -f $tmp_flsp >& /dev/null
  endif
  cat > $tmp_flsp << EOT
       program test
       implicit none
       integer :: ret
       character(len=80) :: version
#include "netcdf.inc"
       version = nf_inq_libvers( )
       write(*,*) 'netcdf version = ',trim(version)
       end program test
EOT
  if( -e test ) then
    rm -f test >& /dev/null
  endif
  set cmp_args = "-I$tst_dir/include -L$tst_dir/$tst_lib -lnetcdf"
  if( $op_sys == AIX ) then
    set cmp_args = "-qfree -qsuffix=f=f90:cpp=F90 $cmp_args"
  endif
  $compiler -o test $tmp_flsp $cmp_args >& /dev/null
  set cstatus = $status
  echo " " >> $log_file
  if( $cstatus ) then
    echo " "
    foreach dev_out (/dev/tty $log_file)
      echo "netcdf test failed" >> $dev_out
      echo "This is most likey due to netcdf.inc being non-fortran90 compliant" >> $dev_out
      echo "Should be using netcdf version 3.6.1 or greater" >> $dev_out
    end
  else
    echo "netcdf test successful" >> $log_file
    set ncf_pass = 1
  endif
  if( -e test ) then
    rm -f test >& /dev/null
  endif
  if( -e $tmp_flsp ) then
    rm -f $tmp_flsp >& /dev/null
  endif
endif

#------------------------------------------------------------
#  if no valid data_dir then prompt
#------------------------------------------------------------
if( ! $?data_dir ) then
  echo " "
  if( $data_dir_opt == 0 ) then
    echo '$prog option "data_dir=..." not set'
  else
    echo "$prog option 'data_dir=$inp_data_dir' non-existant"
  endif
  echo " "
  echo "(Do not use environment variables such as HOME in response)"
  echo -n "Enter mozart input data directory : "
  set data_dir = $<
  set data_dir = `echo $data_dir | sed 's/\/$//'`
  if( ! -d $data_dir ) then
    echo "response, $data_dir, does not exist; $prog terminating"
    exit -1
  endif
endif
#------------------------------------------------------------
#  batch queue check
#------------------------------------------------------------
if( ! $?que ) then
#------------------------------------------------------------
#  batch queue not a command argument
#------------------------------------------------------------
  if( $op_sys == LINUX ) then
    set que_cmds = (qsub bsub)
  else
    set que_cmds = (llsubmit bsub qsub)
  endif
  foreach que_cmd ($que_cmds)
    which $que_cmd >& /dev/null
    if( ! $status ) then
      set que = `which $que_cmd`
      set que = $que:t
      break
    endif
  end
else
#------------------------------------------------------------
#  batch queue specified via command argument
#------------------------------------------------------------
  if( ! -e $que ) then
    unset que
  endif
endif

#------------------------------------------------------------
#  if compiler, mpif90, netcdf lib directory are defined
#  write to file configureation file
#  Also output configuration summary
#------------------------------------------------------------
set cfg_ofile = "MZ4.cfg"
if( -e $cfg_ofile ) then
  rm -f $cfg_ofile >& /dev/null
endif
echo " " ; echo " " >> $log_file
set string = "... Writing configuration file : $cfg_ofile"
echo $string
echo " " >> $log_file ; echo " "
echo $string >> $log_file
set string = "mz4 configuration summary"
echo $string ; echo $string >> $log_file
set string = "----------------------------------------------------------"
echo $string ; echo $string >> $log_file
set err_cnt = 0
set err_msk = (0 0 0 0 0)
if( $?compiler ) then
  echo $compiler > $cfg_ofile
else
  @ err_cnt++
  @ err_msk[1]++
  echo "NONE" > $cfg_ofile
  set string = "Can't locate fortran 90 compiler"
  echo $string ; echo $string >> $log_file
  echo " " ; echo " " >> $log_file
  set string = "Supported fortran90 compilers are :"
  echo $string ; echo $string >> $log_file
  set string = "  (1) Portland Group"
  echo $string ; echo $string >> $log_file
  set string = "  (2) Intel (version 10.x or greater highly advised)"
  echo $string ; echo $string >> $log_file
  set string = "  (3) Lahey"
  echo $string ; echo $string >> $log_file
  set string = " "
  echo $string ; echo $string >> $log_file
endif
if( $ncf_pass ) then
  echo $tst_dir/$tst_lib >> $cfg_ofile
else
  @ err_cnt++
  @ err_msk[2]++
  echo "NONE" >> $cfg_ofile
endif
if( $?mpif90_flspec ) then
  echo $mpif90_flspec >> $cfg_ofile
else
  @ err_cnt++
  @ err_msk[3]++
  echo "NONE" >> $cfg_ofile
endif
if( ! $found_gmake ) then
  @ err_cnt++
  @ err_msk[4]++
endif
set mz4root = `pwd`
set mz4root = $mz4root:h
echo $mz4root  >> $cfg_ofile
if( ! $?site ) then
  set site = Local
endif
echo $site  >> $cfg_ofile
if( ! $?model ) then
  set model = HYB
endif
echo $model  >> $cfg_ofile
if( $?data_dir ) then
  echo $data_dir  >> $cfg_ofile
else
  @ err_msk[5]++
  echo NONE >> $cfg_ofile
endif
if( ! $?que ) then
  set que = NONE
endif
echo $que  >> $cfg_ofile

if( $err_cnt == 0 ) then
  set string = "mz4 configuration is SUCCESSFUL"
  echo $string ; echo $string >> $log_file
  set string = "mz4 can build executable for all modes"
  echo $string ; echo $string >> $log_file
  set string = "(hybrid, mpi, openmp, single cpu)"
  echo $string ; echo $string >> $log_file
else if( $err_msk[1] == 0 && $err_msk[2] == 0 && $err_msk[4] == 0 ) then
  set string = "mz4 configuration is partially SUCCESSFUL"
  echo $string ; echo $string >> $log_file
  set string = "mz4 can build executable for single cpu and openmp modes"
  echo $string ; echo $string >> $log_file
  set string = "Can't locate mpif90 script for compiling executable with mpi;(hybrid or mpi mode)"
  echo $string ; echo $string >> $log_file
else
  echo " " ; echo " " >> $log_file
  set string = "Can NOT build mz4 executable for the following reason(s):"
  echo "$string" ; echo "$string" >> $log_file
  @ err_cnt = 0
  set letter = (a b c d)
  foreach err ($err_msk)
    @ err_cnt++
    set string = ""
    if( $err == 1 ) then
      switch ($err_cnt)
        case 1
          set string = "($letter[1])  Can't locate fortran 90 compiler"
          shift letter
          breaksw
        case 2
          if( ! $found_ncf_lib ) then
            set string = "($letter[1])  Can't locate netcdf library libnetcdf.a"
          else if( ! $found_ncf_inc ) then
            set string = "($letter[1])  Can't locate netcdf include file netcdf.inc"
          else if( ! $ncf_pass ) then
            set string = "($letter[1])  Either netcdf.inc failed to compile or libnetcf.a failed to link"
          endif
          shift letter
          breaksw
        case 4
          set string = "($letter[1])  Can't locate gnu make utility gmake"
      endsw
      if( "$string" != "" ) then
        echo $string ; echo $string >> $log_file
      endif
    endif
  end
  if( $err_msk[3] == 1 ) then
    echo " " ; echo " " >> $log_file
    set string = "Additionally ..."
    echo $string ; echo $string >> $log_file
    set string = "(a)  Can't locate mpif90 script for compiling executable with mpi;(hybrid or mpi mode)"
    echo $string ; echo $string >> $log_file
  endif
  echo " " ; echo " " >> $log_file
  set string = "If you have configuration questions send email to : stacy@ucar.edu"
  echo $string ; echo $string >> $log_file
  set string = "(It would helpful to attach the cfg.log file to the email)"
  echo $string ; echo $string >> $log_file
endif

echo " " ; echo " " >> $log_file
if( $err_msk[5] ) then
  set string = "WARNING: mozart data directory not specified"
  echo $string ; echo $string >> $log_file
  set string = "         You will not be able to run a simulation with the run_mz4 script"
  set string = '         You must include the argument "data_dir=..." in the run_mz4 command'
  echo $string ; echo $string >> $log_file
  set string = "         Rerun $prog with the data_dir keyword set to the mozart input data directory"
  echo $string ; echo $string >> $log_file
endif

echo " " ; echo " " >> $log_file
if( $que == NONE ) then
 set string = "FYI: this computing environment does NOT have batch queueing"
else
 set string = "FYI: this computing environment does have batch queueing via the $que command"
endif
echo $string ; echo $string >> $log_file

#------------------------------------------------------------
#  write config settings to log file
#------------------------------------------------------------
cat >> $log_file << EOM

        Configuration settings
        ----------------------
(1) Compiler              : $compiler
(2) Netcdf directory      : $tst_dir/$tst_lib
(3) mpif90 script         : $mpif90_flspec
(4) mz4 root directory    : $mz4root
(5) computing site        : $site
(6) default model         : $model
(7) input data directory  : $data_dir
(8) batch queue command   : $que

EOM


set string = "----------------------------------------------------------"
echo $string ; echo $string >> $log_file
echo " " ; echo " " >> $log_file

echo "=======================================================================" >> $log_file
echo " " >> $log_file

echo "... mz4 configuration details are in file $log_file"
echo " "
echo "======================================================================="

exit 0
