macro(add_test_with_mode exe mode device)
  add_test(NAME ${exe}-${mode} COMMAND ./${exe} --verbose --device "${device}")
  set_property(TEST ${exe}-${mode} APPEND PROPERTY ENVIRONMENT OCCA_CACHE_DIR=${OCCA_BUILD_DIR}/occa)
endmacro()

macro(add_test_with_modes exe)
  add_test_with_mode(${exe} serial "{\"mode\": \"Serial\"}")
  if (OCCA_CUDA_ENABLED)
    add_test_with_mode(${exe} cuda "{\"mode\": \"CUDA\", \"device_id\": 0}")
  endif()
  if (OCCA_HIP_ENABLED)
    add_test_with_mode(${exe} hip "{\"mode\": \"HIP\", \"device_id\": 0}")
  endif()
  if (OCCA_METAL_ENABLED)
    add_test_with_mode(${exe} metal "{\"mode\": \"Metal\", \"device_id\": 0}")
  endif()
  if (OCCA_OPENCL_ENABLED)
    add_test_with_mode(${exe} opencl "{\"mode\": \"OpenCL\", \"platform_id\": 0, \"device_id\": 0}")
  endif()
  if (OCCA_DPCPP_ENABLED)
    add_test_with_mode(${exe} dpcpp "{\"mode\": \"dpcpp\", \"platform_id\": 0, \"device_id\": 0}")
  endif()
  if (OCCA_OPENMP_ENABLED)
    add_test_with_mode(${exe} openmp "{\"mode\": \"OpenMP\"}")
  endif()
endmacro()

macro(add_test_without_mode exe)
  add_test(NAME ${exe} COMMAND ${exe} --verbose)
  set_property(TEST ${exe} APPEND PROPERTY ENVIRONMENT OCCA_CACHE_DIR=${OCCA_BUILD_DIR}/occa)
endmacro()

macro(compile_c_example target file)
  add_executable(examples_c_${target} ${file})
  target_link_libraries(examples_c_${target} libocca)
  target_include_directories(examples_c_${target} PRIVATE
    $<BUILD_INTERFACE:${OCCA_SOURCE_DIR}/src>)
  if (OCCA_ENABLE_TESTS)
    add_test_with_modes(examples_c_${target})
  endif()
endmacro()

macro(compile_cpp_example target file)
  add_executable(examples_cpp_${target} ${file})
  target_link_libraries(examples_cpp_${target} libocca)
  target_include_directories(examples_cpp_${target} PRIVATE
    $<BUILD_INTERFACE:${OCCA_SOURCE_DIR}/src>)
  if (OCCA_ENABLE_TESTS)
    add_test_without_mode(examples_cpp_${target})
  endif()
endmacro()

macro(compile_cpp_example_with_modes target file)
  add_executable(examples_cpp_${target} ${file})
  target_link_libraries(examples_cpp_${target} libocca)
  target_include_directories(examples_cpp_${target} PRIVATE
    $<BUILD_INTERFACE:${OCCA_SOURCE_DIR}/src>)
  if (OCCA_ENABLE_TESTS)
    add_test_with_modes(examples_cpp_${target})
  endif()
endmacro()

add_subdirectory(c)
add_subdirectory(cpp)

if (OCCA_ENABLE_FORTRAN)
  macro(compile_fortran_example_with_modes target file)
    add_executable(examples_fortran_${target} ${file})
    target_link_libraries(examples_fortran_${target} libocca)
    if (OCCA_ENABLE_TESTS)
      add_test_with_modes(examples_fortran_${target})
    endif()
  endmacro()

  add_subdirectory(fortran)
endif()
