cmake_minimum_required(VERSION 3.24)

include(CheckLanguage)
check_language(CUDA)
if(CMAKE_CUDA_COMPILER)
  set(_cugrid_cuda_default ON)
else()
  set(_cugrid_cuda_default OFF)
endif()

# Auto-detected: ON if a CUDA compiler is on PATH, OFF otherwise (e.g. CPU-only dev
# machines, cloud CI). Override explicitly with -DCUGRID_ENABLE_CUDA=ON/OFF.
option(CUGRID_ENABLE_CUDA "Build CUDA kernels" ${_cugrid_cuda_default})
option(CUGRID_BUILD_TESTS "Build C++ unit tests (GoogleTest, fetched)" ON)
option(CUGRID_BUILD_PYTHON "Build the pybind11 extension module" ON)

if(CUGRID_ENABLE_CUDA AND NOT CMAKE_CUDA_COMPILER)
  message(WARNING "CUGRID_ENABLE_CUDA=ON but no CUDA compiler was found on PATH; building CPU-only.")
  set(CUGRID_ENABLE_CUDA OFF)
endif()

if(CUGRID_ENABLE_CUDA)
  project(cugrid LANGUAGES CXX CUDA)
else()
  project(cugrid LANGUAGES CXX)
endif()

set(CMAKE_CXX_STANDARD 20)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_CXX_EXTENSIONS OFF)
set(CMAKE_POSITION_INDEPENDENT_CODE ON)

if(NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES)
  set(CMAKE_BUILD_TYPE RelWithDebInfo CACHE STRING "Build type" FORCE)
endif()

# Header-only interface target: include path + language standard + optional
# CUDA/NVTX defines. Every cugrid target (CPU or GPU) links against this.
add_library(cugrid_common INTERFACE)
target_include_directories(cugrid_common INTERFACE
  $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>
  $<INSTALL_INTERFACE:include>)
target_compile_features(cugrid_common INTERFACE cxx_std_20)

if(CUGRID_ENABLE_CUDA)
  set(CMAKE_CUDA_STANDARD 20)
  set(CMAKE_CUDA_STANDARD_REQUIRED ON)
  find_package(CUDAToolkit REQUIRED)

  target_compile_definitions(cugrid_common INTERFACE CUGRID_HAVE_CUDA)
  target_link_libraries(cugrid_common INTERFACE CUDA::cudart)

  if(TARGET CUDA::nvtx3)
    target_compile_definitions(cugrid_common INTERFACE CUGRID_HAVE_NVTX)
    target_link_libraries(cugrid_common INTERFACE CUDA::nvtx3)
  endif()
endif()

if(CUGRID_BUILD_PYTHON)
  find_package(Python 3.12 COMPONENTS Interpreter Development.Module REQUIRED)
  find_package(pybind11 CONFIG REQUIRED)

  pybind11_add_module(_core python/cugrid/_bindings.cpp)
  target_link_libraries(_core PRIVATE cugrid_common)

  install(TARGETS _core DESTINATION cugrid)
endif()

if(CUGRID_BUILD_TESTS)
  enable_testing()
  add_subdirectory(tests/unit)
endif()
