cmake_minimum_required(VERSION 3.26)

project(
  Rubikoslav
  VERSION 1.1.0
  LANGUAGES CXX)

include(CTest)
include(GNUInstallDirs)
include(CMakePackageConfigHelpers)

set(CMAKE_CXX_EXTENSIONS OFF)

option(RUBIKOSLAV_BUILD_PYTHON "Build the optional pybind11 cube module" ON)
option(RUBIKOSLAV_BUILD_EXAMPLES "Build the supported command-line example" ON)
option(RUBIKOSLAV_BUILD_WEB "Build the web visualizer data generator" ON)
option(RUBIKOSLAV_WARNINGS_AS_ERRORS "Treat compiler warnings as errors" OFF)

set(RUBIKOSLAV_CUDA
    "AUTO"
    CACHE STRING "CUDA backend: AUTO, ON, or OFF")
set_property(CACHE RUBIKOSLAV_CUDA PROPERTY STRINGS AUTO ON OFF)
string(TOUPPER "${RUBIKOSLAV_CUDA}" RUBIKOSLAV_CUDA)
if(NOT RUBIKOSLAV_CUDA MATCHES "^(AUTO|ON|OFF)$")
  message(FATAL_ERROR "RUBIKOSLAV_CUDA must be AUTO, ON, or OFF")
endif()

set(RUBIKOSLAV_HAS_CUDA OFF)
if(NOT RUBIKOSLAV_CUDA STREQUAL "OFF")
  include(CheckLanguage)
  check_language(CUDA)
  if(CMAKE_CUDA_COMPILER)
    enable_language(CUDA)
    set(RUBIKOSLAV_HAS_CUDA ON)
  elseif(RUBIKOSLAV_CUDA STREQUAL "ON")
    message(
      FATAL_ERROR "RUBIKOSLAV_CUDA=ON requires an NVIDIA CUDA compiler (nvcc).")
  endif()
endif()

add_subdirectory(cpp)
add_subdirectory(cuda)

if(BUILD_TESTING)
  add_subdirectory(cpp/tests)
endif()

if(RUBIKOSLAV_BUILD_EXAMPLES)
  add_subdirectory(cpp/examples)
endif()

if(RUBIKOSLAV_BUILD_WEB)
  add_subdirectory(web)
endif()

if(SKBUILD)
  install(
    FILES "${CMAKE_SOURCE_DIR}/web/index.html"
          "${CMAKE_SOURCE_DIR}/web/styles.css"
          "${CMAKE_SOURCE_DIR}/web/asset-manifest.json"
    DESTINATION rubikoslav/web)
  install(
    DIRECTORY "${CMAKE_SOURCE_DIR}/web/styles/"
    DESTINATION rubikoslav/web/styles
    FILES_MATCHING
    PATTERN "*.css")
  install(
    DIRECTORY "${CMAKE_SOURCE_DIR}/web/dist/"
    DESTINATION rubikoslav/web/dist
    FILES_MATCHING
    PATTERN "*.js")
else()
  install(DIRECTORY cpp/include/Rubikoslav
          DESTINATION ${CMAKE_INSTALL_INCLUDEDIR})

  install(
    EXPORT RubikoslavTargets
    FILE RubikoslavTargets.cmake
    NAMESPACE Rubikoslav::
    DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/Rubikoslav)

  configure_package_config_file(
    cpp/cmake/RubikoslavConfig.cmake.in
    "${CMAKE_CURRENT_BINARY_DIR}/RubikoslavConfig.cmake"
    INSTALL_DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/Rubikoslav)
  write_basic_package_version_file(
    "${CMAKE_CURRENT_BINARY_DIR}/RubikoslavConfigVersion.cmake"
    VERSION ${PROJECT_VERSION}
    COMPATIBILITY SameMajorVersion)
  install(FILES "${CMAKE_CURRENT_BINARY_DIR}/RubikoslavConfig.cmake"
                "${CMAKE_CURRENT_BINARY_DIR}/RubikoslavConfigVersion.cmake"
          DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/Rubikoslav)
endif()
