#!/bin/csh -f

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

#------------------------------------------------------------
#  check op sys
#------------------------------------------------------------
set op_sys = `uname -s | tr '[a-z]' '[A-Z]'`
set os     = $op_sys
#------------------------------------------------------------
#  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

#------------------------------------------------------------
#  check for gnu make utility
#------------------------------------------------------------
foreach file (gmake gnumake)
  which $file >& /dev/null
  if( ! $status ) then
    set gmake_cmd = `which $file` 
  endif
end
if( ! $?gmake_cmd ) then
  echo "$prog can't find gnu make utility; terminating"
  exit -1
endif

set cfg_file = `pwd`
set cfg_file = $cfg_file:h
set cfg_file = $cfg_file/configure/MZ4.cfg
#------------------------------------------------------------
#  get configuration parameters and set mz4 root directory
#------------------------------------------------------------
if( ! -e $cfg_file ) then
  echo " "
  echo "*** Can't find configuration file $cfg_file ***"
  echo " "
  cat << EOM
  If you have run the configuration utility, cfg_mz4, then check

  (1) are you in the MZ4ROOT/model directory

  or

  (2) run the configuration utility, cfg_mz4, in MZ4ROOT/configuration;

  $prog terminating
EOM
  echo " "
  exit -1
else
  set cfgs = `cat $cfg_file`
  set MZ4ROOT = $cfgs[4]
endif

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.make
    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 command arguments
#------------------------------------------------------------
  foreach argument ($args)
    foreach keyword (MODEL EXE USR_SRC SITE NT)
      echo $argument | grep "$keyword=" >& /dev/null
      if( ! $status ) then
        if( $keyword == MODEL ) then
          set model = `echo $argument | cut -d= -f2`
        else if( $keyword == EXE ) then
          set exename = `echo $args1[1] | cut -d= -f2`
        else if( $keyword == USR_SRC ) then
          set srcs = `echo $args1[1] | cut -d= -f2`
          if( "$srcs" != "" ) then
            set srcdirs = `echo $srcs | sed 's/,/ /g'`
          endif
        else if( $keyword == SITE ) then
          set site = `echo $argument | cut -d= -f2`
        else if( $keyword == NT ) then
          set nt = `echo $argument | cut -d= -f2`
        endif
        break
      else
        continue
      endif
    end
    shift args1
  end
endif

#------------------------------------------------------------
#  set code_dir
#------------------------------------------------------------
set code_dir = `pwd`
#------------------------------------------------------------
#  if set check the srcdirs for existence
#------------------------------------------------------------
if( $?srcdirs ) then
  foreach dir ($srcdirs)
     if( ! -e $dir ) then
        echo "user src directory, $dir, doesn't exist; $prog terminating"
        exit -1
     endif
  end
endif

#------------------------------------------------------------
#  check the site
#------------------------------------------------------------
if( ! $?site ) then
  set site = $cfgs[5]
endif
#------------------------------------------------------------
#  check for executable mode; default to hyb (hybrid)
#------------------------------------------------------------
model_test:
if( $?model ) then
  switch( $model )
    case HYB:
      set model=hyb
      set mode=HYBRID
      breaksw
    case MPI:
      set model=mpi
      set mode=PURE_MPI
      breaksw
    case OMP:
      set model=omp
      set mode=PURE_OMP
      breaksw
    case SNG:
      set model=sng
      set mode=SNG
      breaksw
    default:
      echo "$model is not in set {SNG,OMP,MPI,HYB}; $prog terminating"
      exit -1
  endsw
else
  set model = $cfgs[6]
  goto model_test
endif

#------------------------------------------------------------
#  check compiler
#------------------------------------------------------------
if( $cfgs[1] == NONE ) then
  echo "$prog can't build executable; no fortran90 compiler"
  exit -1
endif

set compiler = $cfgs[1]:t
if( $op_sys == LINUX ) then
  set match_comp = (pgf9 ifort lf9 gfor)
else
  set match_comp = xlf
endif
foreach comp ($match_comp)
  echo $compiler | grep $comp >& /dev/null
  if( ! $status ) then
    if( $comp == pgf9 ) then
      set comp_hndl = PGI
    else if( $comp == ifort ) then
      set comp_hndl = Intel
    else if( $comp == lf9 ) then
      set comp_hndl = Lahey
    else if( $comp == gfor ) then
      set comp_hndl = GNU
    else if( $comp == xlf ) then
      set comp_hndl = "IBM xlf"
    else
      echo "$compiler not a supported compiler; $prog terminating"
      exit -1
    endif
    break
  else
    continue
  endif
end

echo " "
echo "$prog using $comp_hndl f90 compiler"
if( $op_sys == LINUX ) then
  set compiler = $comp_hndl
endif

#------------------------------------------------------------
#  netcdf directory; check for directory using following
#  1) - command line argument
#  2) - configuration file MZ4.cfg && != NONE
#  3) - environment variable NCD_DIR
#------------------------------------------------------------
if( $cfgs[2] == NONE ) then
  echo "$prog can't build executable; no netcdf directory"
  exit -1
else
  set ncd_dir = $cfgs[2]:h
endif
#------------------------------------------------------------
#  check for netcdf directory
#------------------------------------------------------------
if( ! -d $ncd_dir ) then
  echo "$prog can't build executable; can't find netcdf directory ($ncd_dir)"
  exit -1
endif
#------------------------------------------------------------
#  setup netcdf archive lib files
#------------------------------------------------------------
set ar_libs = -lnetcdf
if( -e $ncd_dir/lib/libnetcdff.a ) then
  set ar_libs = "$ar_libs -lnetcdff"
endif

#------------------------------------------------------------
#  if using mpi then check for mpif90 script
#  if not using mpi then check for fortran90 compiler
#------------------------------------------------------------
set mpif90_lnk = 0
if( $mode == "HYBRID" || $mode == "PURE_MPI" ) then
  if( $cfgs[3] == 'NONE' ) then
    if( $?MPI_DIR ) then
      set $cfgs[3] = $MPI_DIR
    else
      echo "$prog can't build HYBRID or PURE_MPI executable; no mpif90 script"
      exit -1
    endif
  endif
  if( $cfgs[3]:t == $mpi_cmd ) then
    set cfgs[3] = $cfgs[3]:h
  endif
  if( ! -d $cfgs[3] ) then
    echo "$prog can't build HYBRID or PURE_MPI executable; can't find mpif90 script ($cfgs[3])"
    exit -1
  endif
  set cfgs[3] = $cfgs[3]/$mpi_cmd
  set mpif90_lnk = 1
endif

#------------------------------------------------------------
#  if mpi then set environment variables
#------------------------------------------------------------
if( $mpif90_lnk ) then
  setenv MPI_DIR $cfgs[3]:h
endif

set pwd = `pwd`
set blddir = $pwd

set objdir=$blddir/OBJ
if( -e $objdir ) then
  rm -f $objdir/* >& /dev/null
else
  mkdir -p $objdir || echo "failed to create $objdir" && exit -1
endif

set bindir=$pwd
if( ! -e $bindir/bin ) then
  mkdir -p $bindir/bin || echo "failed to create $bindir/bin" && exit -1
endif 

#------------------------------------------------------------
#  if executable name not in arguments then set default
#------------------------------------------------------------
if( ! $?exename ) then
  set exename = mz4_$model
endif

set ppdir="$pwd/pp"

#------------------------------------------------------------
#  check for additional user source directories
#------------------------------------------------------------
if( ! $?srcdirs ) then
    set srcdirs="$pwd/pp"
else
  set cnt = 1
  set list = ($srcdirs)
  set limit = $#list
  set src_lst = ()
  while ( $cnt <= $limit )
    set usr_src = $list[$cnt]
    if( "$usr_src" == "$usr_src:t" ) then
      set srcs = $pwd/$usr_src
    else
      set srcs = $usr_src
    endif
    set src_lst = ($src_lst $srcs)
    @ cnt++
  end
  set src_lst = ($src_lst $pwd/pp)
  set srcdirs = `echo $src_lst`
endif

cd $objdir

#------------------------------------------------------------
#  set thread count for gmake
#------------------------------------------------------------
if( ! $?nt ) then
  set nt = 8
endif
set jswitch=-j$nt

if( $mpif90_lnk ) then
  ln -s $cfgs[3] . || echo "Mozart4 failed to link $cfgs[3]" && exit -2
endif
ln -s $pwd/Makefile . || echo "Mozart4 failed to link $pwd/Makefile" && exit -2
ln -s $ppdir/params.h . || echo "Mozart4 failed to link $ppdir/params.h" && exit -2

echo " "
echo "============================================================================"
echo "$prog building $exename in $bindir/bin"
echo "$prog begins compiling on "`date`

$gmake_cmd $jswitch OP_SYS="$op_sys" COMPILER="$compiler" SITE=$site CODEDIR="$code_dir" SRCDIRS="$srcdirs" MODEL_MODE=$mode OBJDIR=$objdir MODEL_EXEDIR="$bindir/bin" NCD_DIR="$ncd_dir" AR_LIBS="$ar_libs" EXENAME=$exename >&! $pwd/MAKE.mz4.out || echo "$prog bld failed; see MAKE.mz4.out" && exit -1

rm -f *.mod *.o

echo "$prog ends   compiling on "`date`
echo "$prog successfully built $bindir/bin/$exename"
echo "============================================================================"
echo " "

#------------------------------------------------------------
#  update build database
#------------------------------------------------------------
set filepath = (`cat $objdir/Filepath`)
foreach fp ($filepath)
  ls $fp/mo_grid.F90 >& /dev/null
  if( ! $status ) then
    set sfile = $fp/mo_grid.F90
    break
  endif
end

if( $?sfile ) then
  set plon = `grep -i plon $sfile | grep '[0-9][0-9]' | awk '{print $3}' | sed 's/,//'`
  set retcode = $status
  if( ! $retcode ) then
    set plat = `grep -i plat $sfile | grep '[0-9][0-9]' | awk '{print $3}' | sed 's/,//'`
    set retcode = $status
  endif
  if( ! $retcode ) then
    set filenm = exe_db
    set record = ($exename $plon $plat)
    if( ! -d $pwd/.make_mz_db ) then
      mkdir $pwd/.make_mz_db
      if( $status ) then
        echo "failed to create db directory"
        exit 0 
      endif
      cd $pwd/.make_mz_db >& /dev/null
      echo $record > $filenm
      cd .. >& /dev/null
    else 
      cd $pwd/.make_mz_db >& /dev/null
      if( -e $filenm ) then
        set lineno = `grep -n $exename $filenm | cut -d: -f1`
        echo $record >> $filenm
      else
        set lineno = ""
        echo $record > $filenm
      endif
      if( "$lineno" != "" ) then
        set tmp_flnm = tmp.$$
        set sed_cmd = $lineno"d"
        sed $sed_cmd < $filenm > $tmp_flnm
        mv $tmp_flnm $filenm
      endif
      cd .. >& /dev/null
    endif
  endif
endif

exit 0
