cmake_minimum_required(VERSION 3.22.0)
project(NVBenchTestExport CUDA CXX)

message(STATUS "NVBench_DIR=${NVBench_DIR}")
find_package(NVBench REQUIRED)

add_executable(test_bench test_bench.cu)
target_link_libraries(test_bench PRIVATE nvbench::main)
enable_testing()
add_test(NAME test_bench COMMAND "$<TARGET_FILE:test_bench>" --timeout 1)
add_test(NAME nvbench_ctl COMMAND "$<TARGET_FILE:nvbench::ctl>")

# Setup runtime library paths for testing.
# Unix uses LD_LIBRARY_PATH; Windows uses PATH for DLL lookup.
function(get_imported_location out_var target_name)
  get_property(imported_configs TARGET ${target_name}
    PROPERTY IMPORTED_CONFIGURATIONS
  )
  list(LENGTH imported_configs num_configs)
  if (num_configs GREATER 1)
    message(WARNING
      "Multiple IMPORTED_CONFIGURATIONS for ${target_name}. "
      "Picking CMAKE_BUILD_TYPE if present, otherwise the first one."
    )
  endif()

  if (num_configs GREATER 0)
    if (CMAKE_BUILD_TYPE)
      string(TOUPPER "${CMAKE_BUILD_TYPE}" build_type)
      list(FIND imported_configs "${build_type}" imported_config_index)
    else()
      set(imported_config_index -1)
    endif()
    if (imported_config_index GREATER_EQUAL 0)
      list(GET imported_configs ${imported_config_index} imported_config)
    else()
      list(GET imported_configs 0 imported_config)
    endif()
    get_property(imported_location TARGET ${target_name}
      PROPERTY IMPORTED_LOCATION_${imported_config}
    )
  endif()

  if (NOT imported_location)
    get_property(imported_location TARGET ${target_name}
      PROPERTY IMPORTED_LOCATION
    )
  endif()

  set(${out_var} "${imported_location}" PARENT_SCOPE)
endfunction()

set(nvbench_lib_dir "")
# On Unix the build tree uses RUNPATH so only the install tree needs the path.
# On Windows there is no RUNPATH so we always need the DLL directory.
if (WIN32 OR TEST_TYPE STREQUAL "INSTALL_TREE")
  get_imported_location(nvbench_lib nvbench::nvbench)
  if (nvbench_lib)
    cmake_path(GET nvbench_lib PARENT_PATH nvbench_lib_dir)
  endif()
endif()

set(cupti_lib_dir "")
if (TARGET nvbench::cupti)
  get_imported_location(cupti_lib nvbench::cupti)
  if (cupti_lib)
    cmake_path(GET cupti_lib PARENT_PATH cupti_lib_dir)
  endif()
endif()

if (WIN32)
  set(path_modifications "")
  if (cupti_lib_dir)
    list(APPEND path_modifications "PATH=path_list_prepend:$<SHELL_PATH:${cupti_lib_dir}>")
  endif()
  if (nvbench_lib_dir)
    list(APPEND path_modifications "PATH=path_list_prepend:$<SHELL_PATH:${nvbench_lib_dir}>")
  endif()
  if (path_modifications)
    set_property(TEST test_bench PROPERTY
      ENVIRONMENT_MODIFICATION ${path_modifications}
    )
    set_property(TEST nvbench_ctl PROPERTY
      ENVIRONMENT_MODIFICATION ${path_modifications}
    )
  endif()
else()
  set(test_bench_ld_modifications "")
  if (cupti_lib_dir)
    list(APPEND test_bench_ld_modifications
      "LD_LIBRARY_PATH=path_list_prepend:$<SHELL_PATH:${cupti_lib_dir}>"
    )
  endif()
  if (test_bench_ld_modifications)
    set_property(TEST test_bench PROPERTY
      ENVIRONMENT_MODIFICATION ${test_bench_ld_modifications}
    )
  endif()

  set(nvbench_ctl_ld_modifications "")
  if (cupti_lib_dir)
    list(APPEND nvbench_ctl_ld_modifications
      "LD_LIBRARY_PATH=path_list_prepend:$<SHELL_PATH:${cupti_lib_dir}>"
    )
  endif()
  if (nvbench_lib_dir)
    list(APPEND nvbench_ctl_ld_modifications
      "LD_LIBRARY_PATH=path_list_prepend:$<SHELL_PATH:${nvbench_lib_dir}>"
    )
  endif()
  if (nvbench_ctl_ld_modifications)
    set_property(TEST nvbench_ctl PROPERTY
      ENVIRONMENT_MODIFICATION ${nvbench_ctl_ld_modifications}
    )
  endif()
endif()
