include (ScreamUtils)

# This test requires CPRNC
include (BuildCprnc)
BuildCprnc()

# Needed for RRTMGP
find_library(NETCDF_C netcdf HINTS ${NetCDF_C_PATH}/lib)
# Get or create the dynamics lib
#                 HOMME_TARGET   NP PLEV QSIZE_D
CreateDynamicsLib("theta-l_kokkos"  4   72   10)

set (NEED_LIBS cld_fraction shoc p3 scream_rrtmgp rrtmgp ${NETCDF_C} ${dynLibName} scream_control scream_share physics_share yakl diagnostics)

# We have 3 runs:
#  1) run for 2*N time steps starting from t=0 (baseline run)
#  2) run for N time steps starting from t=0 (init run)
#  3) run for N time steps re-starting from t=N*dt (restarted run)
# We can use the same namelist for all tests, using 3 different input yaml files

# Add _np1 only if we're running also with more than one rank. Otherwise, add nothing
set (TEST_NRANKS ${TEST_RANK_START})
if (TEST_RANK_END GREATER TEST_RANK_START)
  list (APPEND TEST_NRANKS ${TEST_RANK_END})
endif()

# Create a single executable for all the 3 runs
CreateUnitTestExec(model_restart model_restart.cpp "${NEED_LIBS}")

# Set time integration options
set (ATM_TIME_STEP 300)
set (CASE_T0 2021-10-12-43200)
set (CASE_TN 2021-10-12-43800)

foreach (NRANKS IN ITEMS ${TEST_NRANKS})

  # Create the baseline (run all 6 timsteps in a single run)
  CreateUnitTestFromExec(model_baseline model_restart
                         EXE_ARGS "--use-colour no --ekat-test-params ifile=input_baseline.yaml"
                         MPI_RANKS ${NRANKS}
                         PROPERTIES FIXTURES_SETUP baseline_run_np${NRANKS})

  # Start a simulation, but only run half of the time steps
  CreateUnitTestFromExec(model_initial model_restart
                         EXE_ARGS "--use-colour no --ekat-test-params ifile=input_initial.yaml"
                         MPI_RANKS ${NRANKS}
                         PROPERTIES FIXTURES_SETUP initial_run_np${NRANKS}
                                    RESOURCE_LOCK rpointer_file)

  # Restart the simulation, and run the second half of the time steps
  CreateUnitTestFromExec(model_restart model_restart
                         EXE_ARGS "--use-colour no --ekat-test-params ifile=input_restarted.yaml"
                         MPI_RANKS ${NRANKS}
                         PROPERTIES FIXTURES_REQUIRED initial_run_np${NRANKS}
                                    FIXTURES_SETUP restarted_run_np${NRANKS}
                                    RESOURCE_LOCK rpointer_file)

  # Finally, compare the nc outputs generated by the basline and restarted runs
  # IMPORTANT: make sure these file names match what baseline/restarted runs produce
  set (SRC_FILE model_output_baseline.INSTANT.nsteps_x2.np${NRANKS}.${CASE_TN}.nc)
  set (TGT_FILE model_output.INSTANT.nsteps_x2.np${NRANKS}.${CASE_TN}.nc)

  add_test (NAME restarted_vs_monolithic_check_np${NRANKS}
            COMMAND cmake -P ${CMAKE_BINARY_DIR}/bin/CprncTest.cmake ${SRC_FILE} ${TGT_FILE}
            WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR})
  set_tests_properties (restarted_vs_monolithic_check_np${NRANKS} PROPERTIES
                        RESOURCE_GROUPS "devices:1"
                        FIXTURES_REQUIRED "baseline_run_np${NRANKS};restarted_run_np${NRANKS}")
endforeach()

# Determine num subcycles needed to keep shoc dt<=300s
set (SHOC_MAX_DT 300)
math (EXPR MAC_MIC_SUBCYCLES "(${ATM_TIME_STEP} + ${SHOC_MAX_DT} - 1) / ${SHOC_MAX_DT}")

# Configure yaml input file to run directory
set (RUN_T0 2021-10-12-43200)
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/input_baseline.yaml
               ${CMAKE_CURRENT_BINARY_DIR}/input_baseline.yaml)
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/input_initial.yaml
               ${CMAKE_CURRENT_BINARY_DIR}/input_initial.yaml)
set (RUN_T0 2021-10-12-43500)
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/input_restarted.yaml
               ${CMAKE_CURRENT_BINARY_DIR}/input_restarted.yaml)

# The two yaml files that control the output streams (for the baseline and restart runs)
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/model_output.yaml
               ${CMAKE_CURRENT_BINARY_DIR}/model_output.yaml COPYONLY)
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/model_restart_output.yaml
               ${CMAKE_CURRENT_BINARY_DIR}/model_restart_output.yaml COPYONLY)

# Set homme's test options, so that we can configure the namelist correctly
# Discretization/algorithm settings
set (HOMME_TEST_NE 2)
set (HOMME_TEST_LIM 9)
set (HOMME_TEST_REMAP_FACTOR 1)
set (HOMME_TEST_TRACERS_FACTOR 1)
set (HOMME_TEST_TIME_STEP 300)
set (HOMME_THETA_FORM 1)
set (HOMME_TTYPE 10)
set (HOMME_SE_FTYPE 0)

# Hyperviscosity settings
set (HOMME_TEST_HVSCALING 0)
set (HOMME_TEST_HVS 1)
set (HOMME_TEST_HVS_TOM 0)

set (HOMME_TEST_NU 7e15)
set (HOMME_TEST_NUDIV 1e15)
set (HOMME_TEST_NUTOP 2.5e5)

# Testcase settings
set (HOMME_TEST_MOISTURE notdry)
set (HOMME_THETA_HY_MODE .false.)

# Vert coord settings
set (HOMME_TEST_VCOORD_INT_FILE acme-72i.ascii)
set (HOMME_TEST_VCOORD_MID_FILE acme-72m.ascii)

# Configure the namelist into the test directory
configure_file(${SCREAM_SRC_DIR}/dynamics/homme/tests/theta.nl
               ${CMAKE_CURRENT_BINARY_DIR}/namelist.nl)

# Ensure test input files are present in the data dir
GetInputFile(scream/init/${EAMxx_tests_IC_FILE_72lev})
GetInputFile(cam/topo/USGS-gtopo30_ne4np4pg2_16x_converted.c20200527.nc)
