#!/bin/ksh

# ICON
#
# ------------------------------------------
# Copyright (C) 2004-2026, DWD, MPI-M, DKRZ, KIT, ETH, MeteoSwiss
# Contact information: icon-model.org
# See AUTHORS.TXT for a list of authors
# See LICENSES/ for license information
# SPDX-License-Identifier: BSD-3-Clause
# ------------------------------------------

#-------------------------------------------------------------------------------------=
# ICON testbed
# Creates the setup for a given target
#
# Leonidas Linardakis, MPI-M, 2010-11-24
#
#
#-------------------------------------------------------------------------------------=

set -x

#-------------------------------------------------------------------------------------
create_build_command()
{
  build_command_file="build_command"

  echo "#!$use_shell" > $build_command_file
  if [ x$use_load_modules_script != x ] ; then
    echo ". $use_load_modules_script" >> $build_command_file
  fi

  if [[ "x${use_target}" == "xblizzard" ]]; then
    echo "export LDR_CNTRL=MAXDATA=0xD0000000@DSA"  >> $build_command_file
  fi

  echo "$use_make_command" >> $build_command_file
  chmod +x $build_command_file
}

#-------------------------------------------------------------------------------------
create_config_h()
{
  cd config
  cp $use_config_h config.h
  cd ..
}

#-------------------------------------------------------------------------------------
create_setup_info()
{
echo Creating set-up.info...
cat > run/set-up.info << EOF
#############################
# set-up.info created by configure
# do not modify this file
#############################
use_site="${use_site}"
use_target="${use_target}"
use_fortran="${use_fortran}"
use_mpi="${use_mpi}"
use_openmp="${use_openmp}"
use_builddir="$use_builddir"
use_mpi_startrun="${use_mpi_startrun}"
use_load_modules_script="$use_load_modules_script"
use_load_profiles="$use_load_profiles"
use_load_library_path="$use_load_library_path"
use_make_command="$use_make_command"
use_submit="$use_submit"
use_sync_submit="$use_sync_submit"
use_shell="$use_shell"
#############################
EOF
}

#-------------------------------------------------------------------------------------
create_make()
{
#fill the object_folders from the source_folders
object_folders=""
for folder in $source_folders
do
  object_folders="${object_folders} ${use_builddir}/${folder}"
done

cat > Makefile << EOF

export

SHELL = $use_shell

TARGET = $use_target
OS = $use_os

HOST = $use_host
SITE = $use_site

srcdir = .

prefix = .
builddir = $use_builddir

bindir = ${builddir}/bin
libdir = ${builddir}/lib

NETCDF_LIB     = $NETCDF_LIB
NETCDF_INC     = $NETCDF_INC

HDF5_LIB       = $HDF5_LIB
HDF5_INCLUDE   = $HDF5_INCLUDE

SZIP_LIB       = $SZIP_LIB
SZIP_INCLUDE   = $SZIP_INCLUDE

ZLIB_LIB       = $ZLIB_LIB
ZLIB_INCLUDE   = $ZLIB_INCLUDE

MPI_LIB        = $MPI_LIB
MPI_INC        = $MPI_INC

PROFILE_LIB     = $PROFILE_LIB
PROFILE_INCLUDE = $PROFILE_INCLUDE

LAPACK_LIB     = -L../lib -llapack -lblas

LIBS           = -L../lib -lsupport \$(LAPACK_LIB) \$(NETCDF_LIB) \$(HDF5_LIB) \$(SZIP_LIB) \$(ZLIB_LIB) \$(MPI_LIB) \$(PROFILE_LIB) $LD_LIBS

INCLUDE        = -I../include -I../../../src/include \$(NETCDF_INC) \$(HDF5_INCLUDE) \$(SZIP_INCLUDE) \$(ZLIB_INCLUDE) \$(MPI_INC) \$(PROFILE_INCLUDE)

AS             = as

CC             = $CC
CFLAGS         = \$(INCLUDE) $CFLAGS

FC             = $FC
FFLAGS         = \$(INCLUDE) $FFLAGS

F77            = $F77
F77FLAGS       = $F77FLAGS

AR             = ar
ARFLAGS        = crv

LDFLAGS        = $LDFLAGS

SRCDIRS        =  ${source_folders}
OBJDIRS        =  ${object_folders}

.PHONY: doc

all:
	@for DIR in \$(OBJDIRS) ;\\
	  do \\
	    back=`pwd`; \\
	    cd \$\$DIR ;\\
	    \$(MAKE) ; status=\$\$? ; \\
	    if [ \$\$status != 0 ] ; then \\
	      echo "Exit status from make was \$\$status" ; exit \$\$status ; \\
	    fi ; \\
	    cd \$\$back ; \\
	  done
control:
	@for DIR in \$(OBJDIRS) ;\\
	  do LASTDIR=\$\$DIR ;\\
	done ;\\
	back=`pwd` ;\\
	cd \$\$LASTDIR ;\\
	\$(MAKE) control_model  ;\\
	cd \$\$back

one:
	@for DIR in \$(OBJDIRS) ;\\
	  do LASTDIR=\$\$DIR ;\\
	done ;\\
	back=`pwd` ;\\
	cd \$\$LASTDIR ;\\
	\$(MAKE) \$(name)  ;\\
	cd \$\$back


install:
	@for DIR in \$(OBJDIRS) ;\\
	  do \\
	  (cd \$\$DIR ;\\
	  \$(MAKE) install ; if [ \$\$? != 0 ] ; then \\
	        echo "Exit status from make was \$\$?" ; exit 1 ; fi ;) ;\\
	  done

clean:
	@for DIR in \$(OBJDIRS) ;\\
	  do \\
	  (cd \$\$DIR ;\\
	  \$(MAKE) clean ; if [ \$\$? != 0 ] ; then \\
	        echo "Exit status from make was \$\$?" ; exit 1 ; fi ;) ;\\
	  done
	-rm -f ${use_builddir}/bin/*
	-rm -f ${use_builddir}/lib/*.a
	-rm -f ${use_builddir}/module/*.mod
	-rm -f ${use_builddir}/src/*.o
	-rm -rf html/[a-z]*

distclean:
	-rm -rf build
	-rm Makefile
	-rm build_command
	-rm run/set-up.info
	-rm -rf doc/html
	-rm -rf doc/latex
	-rm -rf html/[a-z]*

EOF
}

#-------------------------------------------------------------------------------------
create_std_modules_script()
{
  modules_list=$use_load_modules
  if [[ "$use_mpi" == "yes" ]]; then
    modules_list="$modules_list $use_mpi_modules"
  fi

  if [ "x$modules_list" == "x" ] ; then
    use_load_modules_script=""
  else
    use_load_modules_script="$base_folder/config/load_modules_script"
    echo "#-----------------#"  > $use_load_modules_script
    for profile_filename in $use_load_profiles
    do
      if [ -a  $profile_filename ] ; then
        echo ". $profile_filename" >> $use_load_modules_script
      fi
    done

    cat >> $use_load_modules_script << EOF
module purge
module load $modules_list
module list
EOF
#  chmod +x $use_load_modules_script
  fi
}

#-------------------------------------------------------------------------------------
load_modules()
{
  if [ x$use_load_modules_script == x ] ; then
    create_std_modules_script
  fi

  if [ x$use_load_modules_script != x ] ; then
    if [ -r $use_load_modules_script ] ; then
      . $use_load_modules_script
    else
        finish -1 "load_modules_script: $use_load_modules_script does not exist"
    fi
  fi
}

#-------------------------------------------------------------------------------------
create_enivoriment()
{

  #---------------
  # create the make_flags
  F77FLAGS=$F77_FLAGS
  CFLAGS="$C_FLAGS ${DEF_COPT}__ICON__"
  LDFLAGS="$LD_FLAGS"

  # create FFLAGS, CFLAGS
  FFLAGS="$BASIC_FLAGS $INFO_FLAGS ${DEF_FOPT}__ICON__"

  #---------------
  # add debug flags
  if [[ $debug_mode == "yes" ]]; then
    FFLAGS="$FFLAGS $TRACE_FLAGS $DEBUG_FLAGS"
  elif [[ $trace_mode == "yes" ]]; then
    FFLAGS="$FFLAGS $TRACE_FLAGS"
  fi

  #---------------
  # add opt flags
  # echo "optimize_level = $optimize_level"
  case $optimize_level in
    std)
        FFLAGS="$FFLAGS $STD_OPT_FLAGS"
        LDFLAGS="$LDFLAGS $STD_OPT_FLAGS"
        ;;
    low)
        FFLAGS="$FFLAGS $LOW_OPT_FLAGS"
        LDFLAGS="$LDFLAGS $LOW_OPT_FLAGS"
        ;;
    high)
        FFLAGS="$FFLAGS $HI_OPT_FLAGS"
        LDFLAGS="$LDFLAGS $HI_OPT_FLAGS"
        ;;
  esac

  #---------------
  # add openmp flags
  if [[ $use_openmp == "yes" ]]; then
    FFLAGS="$FFLAGS $OMP_FLAGS"
    LDFLAGS="$LDFLAGS $OMP_FLAGS"
  fi

  #---------------
  # add mpi flags
  if [[ $use_mpi == "yes" ]]; then
    use_load_modules="$use_mpi_modules $use_load_modules"
  else
    FFLAGS="$FFLAGS ${DEF_FOPT}NOMPI"
    CFLAGS="$CFLAGS ${DEF_COPT}NOMPI"
    F77LAGS="$F77LAGS ${DEF_FOPT}NOMPI"
    MPI_LIB=""
    MPI_INC=""
  fi
}


#-------------------------------------------------------------------------------------
find_target()
{
  name=`hostname`
  use_host=$name

  case "$name" in
  mpipc*)
    use_target="mpipc"
    ;;
  tornado*)
    use_target="tornado"
    ;;
  squall*)
    use_target="squall"
    ;;
  blizzard*|plogintest*)
    use_target="blizzard"
    ;;
  passat*)
    use_target="passat"
    ;;
  login0*)
    use_target="supermuc"
    ;;
  mick*|maik*)
    use_target="MIC"
    ;;
  *)
    check_target $name
    if [[ $check_target != "OK" ]] ; then
      finish -1 "$name unkown host"
    fi
    use_target="$name"
    ;;
  esac
}


#-------------------------------------------------------------------------------------
create_target_setup_machine_compiler()
{

  if [[ x$use_target = x ]]; then
    find_target
  fi

  include_targets "$use_target compiler"

  #call the target machine
  if [[ $include_targets != "OK" ]]; then
    finish -1 "no such file set_target_${use_target} can be used"
  else
    set_target_machine_${use_target}
  fi

  under_buildfolder="$use_target"_"$use_fortran"_"$use_mpi"_mpi_"$use_openmp"_openmp
  use_builddir="build/$under_buildfolder"

  #call the setup routines for the machine_compiler
  case "$use_target" in
  "squall" ) # the same as mpipc
    create_target_setup_mpipc_${use_fortran}
    ;;
  *) # default
    create_target_setup_${use_target}_${use_fortran}
    ;;
  esac

}

#-------------------------------------------------------------------------------------
create_target_model_icon_testbed()
{
  source_folders="blas lapack support src"
}

#-------------------------------------------------------------------------------------
create_target_setup()
{
  # get the model parameters
  create_target_model_icon_testbed
echo "  create_target_model_icon_testbed ... finished"
  #call the setup routines for the machine_compiler
  create_target_setup_machine_compiler
echo "  create_target_setup_machine_compiler ... finished"
  # create the enviroment
  create_enivoriment
echo "  create_enivoriment ... finished"
  #write the run/set-up.info
  create_setup_info
echo "  create_setup_info ... finished"
  #create the config.h
  create_config_h
echo "  create_config_h ... finished"
  #create the Makefile
  create_make
echo "  create_make ... finished"
  #create the build calling the createMakefiles.pl
  config/createMakefiles.pl --target=$under_buildfolder --srcdirs="${source_folders}"
echo "  config/createMakefiles.pl --target=$under_buildfolder --srcdirs=\"${source_folders}\" ... finished"
  #create the build_command
  create_build_command
echo "  create_build_command ... finished"
}
#-------------------------------------------------------------------------------------
