cmake_minimum_required(VERSION 3.16)
project(smsd VERSION 5.2.1 LANGUAGES CXX)

set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)

# ---- Options ----
option(SMSD_BUILD_TESTS "Build unit tests" ON)
option(SMSD_BUILD_PYTHON "Build Python bindings via pybind11" OFF)
option(SMSD_BUILD_CUDA "Build CUDA batch screening" OFF)
option(SMSD_BUILD_OPENMP "Enable OpenMP for batch processing" ON)
option(SMSD_WITH_RDKIT "Build RDKit adapter for SMILES/MOL parsing" OFF)

# ---- Header-only library (no RDKit dependency) ----
add_library(smsd INTERFACE)
target_include_directories(smsd INTERFACE
    $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>
    $<INSTALL_INTERFACE:include>)

# ---- Optional: OpenMP for batch processing ----
if(SMSD_BUILD_OPENMP)
    find_package(OpenMP)
    if(OpenMP_CXX_FOUND)
        message(STATUS "SMSD: OpenMP found (version ${OpenMP_CXX_VERSION})")
        # Propagate OpenMP flags via the INTERFACE library so that any target
        # linking smsd automatically picks up OpenMP support for batch.hpp.
        target_link_libraries(smsd INTERFACE OpenMP::OpenMP_CXX)
    else()
        message(STATUS "SMSD: OpenMP not found -- batch.hpp will use sequential fallback")
    endif()
endif()

# ---- Optional: RDKit adapter ----
if(SMSD_WITH_RDKIT)
    find_package(RDKit REQUIRED)
    add_library(smsd_rdkit STATIC src/rdkit_adapter.cpp)
    target_link_libraries(smsd_rdkit PUBLIC smsd RDKit::SmilesParse RDKit::GraphMol
        RDKit::RingDecomposerLib RDKit::Depictor)
    target_include_directories(smsd_rdkit PUBLIC ${RDKit_INCLUDE_DIRS})
endif()

# ---- Optional: CUDA batch screening ----
if(SMSD_BUILD_CUDA)
    enable_language(CUDA)
    add_library(smsd_cuda STATIC cuda/batch_screen.cu)
    target_link_libraries(smsd_cuda PUBLIC smsd)
    set_target_properties(smsd_cuda PROPERTIES
        CUDA_ARCHITECTURES "70;80;90"
        CUDA_SEPARABLE_COMPILATION ON)
    # Enable CUDA C++17
    target_compile_features(smsd_cuda PUBLIC cxx_std_17)
endif()

# ---- Optional: Python bindings ----
if(SMSD_BUILD_PYTHON)
    find_package(pybind11 REQUIRED)
    pybind11_add_module(_smsd bindings/pybind11/smsd_bindings.cpp)
    target_link_libraries(_smsd PRIVATE smsd)
    if(SMSD_WITH_RDKIT)
        target_link_libraries(_smsd PRIVATE smsd_rdkit)
    endif()
    # Install the Python extension module (required by scikit-build-core)
    install(TARGETS _smsd LIBRARY DESTINATION smsd RUNTIME DESTINATION smsd)
endif()

# ---- Tests ----
if(SMSD_BUILD_TESTS)
    enable_testing()

    # Main test suite
    add_executable(smsd_tests tests/test_main.cpp)
    target_link_libraries(smsd_tests PRIVATE smsd)
    if(SMSD_WITH_RDKIT)
        target_link_libraries(smsd_tests PRIVATE smsd_rdkit)
    endif()
    add_test(NAME smsd_tests COMMAND smsd_tests)

    # Batch processing test suite (OpenMP + fingerprint)
    add_executable(smsd_batch_tests tests/test_batch.cpp)
    target_link_libraries(smsd_batch_tests PRIVATE smsd)
    if(SMSD_WITH_RDKIT)
        target_link_libraries(smsd_batch_tests PRIVATE smsd_rdkit)
    endif()
    add_test(NAME smsd_batch_tests COMMAND smsd_batch_tests)

    # Comprehensive SMILES parser test suite (200+ tests)
    add_executable(smsd_smiles_comprehensive_tests tests/test_smiles_comprehensive.cpp)
    target_compile_definitions(smsd_smiles_comprehensive_tests PRIVATE SMSD_TEST_SMILES_COMPREHENSIVE)
    target_link_libraries(smsd_smiles_comprehensive_tests PRIVATE smsd)
    add_test(NAME smsd_smiles_comprehensive_tests COMMAND smsd_smiles_comprehensive_tests)
endif()

# ---- Install ----
install(DIRECTORY include/smsd DESTINATION include)
install(TARGETS smsd EXPORT smsdTargets)
install(EXPORT smsdTargets NAMESPACE smsd:: DESTINATION lib/cmake/smsd)
