# Copyright (c) 2025 The YAC Authors
#
# SPDX-License-Identifier: BSD-3-Clause

function(yac_add_test)
  set(options)
  set(oneValueArgs NAME MPI_PROCS)
  set(multiValueArgs LABELS LINK)
  cmake_parse_arguments(
    PARSE_ARGV 0 arg "${options}" "${oneValueArgs}" "${multiValueArgs}"
  )

  set(test_command)

  # Merge default labels and links with provided ones
  if(DEFINED YAC_TEST_DEFAULT_LABELS)
    list(APPEND arg_LABELS ${YAC_TEST_DEFAULT_LABELS})
  endif()
  if(DEFINED YAC_TEST_DEFAULT_LINK)
    list(APPEND arg_LINK ${YAC_TEST_DEFAULT_LINK})
  endif()

  # Check if all link targets exists
  set(all_targets_exists TRUE)
  foreach(tgt IN LISTS arg_LINK)
    if(NOT TARGET ${tgt})
      set(all_targets_exists FALSE)
      break()
    endif()
  endforeach()

  # Compile if there is a c file
  if(EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/${arg_NAME}.c" AND all_targets_exists)
    add_executable("${arg_NAME}.x" "${arg_NAME}.c")
    target_link_libraries("${arg_NAME}.x" tests_common)
    if(arg_LINK)
      target_link_libraries("${arg_NAME}.x" ${arg_LINK})
    endif()
    set(test_command "${arg_NAME}.x")
  endif()

  # Compile if there is a c file
  if(EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/${arg_NAME}.F90"
     AND YAC_ENABLE_FORTRAN
     AND all_targets_exists
  )
    add_executable("${arg_NAME}.x" "${arg_NAME}.F90")
    target_link_libraries("${arg_NAME}.x" tests_common)
    if(arg_LINK)
      target_link_libraries("${arg_NAME}.x" ${arg_LINK})
    endif()
    set(test_command "${arg_NAME}.x")
  endif()

  # configure_file if there is a .sh.in file
  if(EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/${arg_NAME}.sh.in")
    configure_file(
      "${arg_NAME}.sh.in"
      "${arg_NAME}.sh"
      @ONLY
      FILE_PERMISSIONS
      OWNER_READ
      OWNER_WRITE
      OWNER_EXECUTE
      GROUP_READ
      GROUP_EXECUTE
      WORLD_READ
      WORLD_EXECUTE
    )
    set(test_command "${arg_NAME}.sh") # may override executable
  endif()

  # add_test
  if(NOT test_command)
    message(FATAL_ERROR "No test_command can be detected for test ${arg_NAME}.")
  endif()
  add_test(NAME "${arg_NAME}" COMMAND "${test_command}")
  set_tests_properties(
    "${arg_NAME}"
    PROPERTIES SKIP_RETURN_CODE 77 TIMEOUT 1200 ENVIRONMENT "OMP_NUM_THREADS=2"
  )
  if(arg_LABELS)
    set_tests_properties("${arg_NAME}" PROPERTIES LABELS "${arg_LABELS}")
  endif()

  if(DEFINED arg_MPI_PROCS)
    if(YAC_ENABLE_OPENMP)
      math(EXPR arg_MPI_PROCS "${arg_MPI_PROCS} * 2")
    endif()
    set_tests_properties("${arg_NAME}" PROPERTIES PROCESSORS "${arg_MPI_PROCS}")
  endif()
endfunction()

add_subdirectory(common)
add_subdirectory(core)
add_subdirectory(utils)
add_subdirectory(pak)
if(YAC_ENABLE_TOOLS)
  add_subdirectory(tools)
endif()
if(YAC_ENABLE_MCI)
  add_subdirectory(mci)
endif()
if(YAC_ENABLE_PYTHON)
  add_subdirectory(python)
endif()
