# SPDX-License-Identifier: Apache-2.0
cmake_minimum_required(VERSION 3.20)
project(trellis VERSION 0.1.0 LANGUAGES C CXX)

set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_POSITION_INDEPENDENT_CODE ON)
include(GNUInstallDirs)
include(CMakePackageConfigHelpers)

option(TRELLIS_BUILD_EXAMPLES "Build C/C++ embed examples" ON)
# Legacy: CUDA door is always compiled into trellis_c via dynamic load (no toolkit at build).
option(TRELLIS_BUILD_CUDA "Build optional CUDA language stub target" OFF)

add_library(trellis_c SHARED
  c_abi/trellis_abi.cpp
  c_abi/trellis_cuda_api.cpp
  doors/cuda/cuda_door.cpp
)
add_library(Trellis::trellis_c ALIAS trellis_c)

target_include_directories(trellis_c
  PUBLIC
    $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/c_abi>
    $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/core/include>
    $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/cpp>
    $<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>
  PRIVATE
    $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/doors/cuda>
    $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}>
)
target_compile_definitions(trellis_c PRIVATE TRELLIS_BUILD)
if(WIN32)
  set_target_properties(trellis_c PROPERTIES WINDOWS_EXPORT_ALL_SYMBOLS ON)
endif()
set_target_properties(trellis_c PROPERTIES
  OUTPUT_NAME trellis_c
  VERSION ${PROJECT_VERSION}
  SOVERSION 0
  EXPORT_NAME trellis_c
)

add_library(trellis_door_cpu doors/cpu/door_cpu.cpp)
target_include_directories(trellis_door_cpu PUBLIC
  $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/core/include>
  $<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>
)

if(TRELLIS_BUILD_CUDA)
  enable_language(CUDA)
  add_library(trellis_door_cuda doors/cuda/door_stub.cpp)
  target_include_directories(trellis_door_cuda PUBLIC
    $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/core/include>
    $<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>
  )
endif()

# Smoke + examples
add_executable(c_abi_smoke ci/c_abi_smoke.c)
target_link_libraries(c_abi_smoke PRIVATE trellis_c)

add_executable(cuda_door_arch_test ci/cuda_door_arch_test.cpp)
target_link_libraries(cuda_door_arch_test PRIVATE trellis_c)
target_include_directories(cuda_door_arch_test PRIVATE
  ${CMAKE_CURRENT_SOURCE_DIR}/doors/cuda
)

if(TRELLIS_BUILD_EXAMPLES)
  add_executable(trellis_c_hello examples/c/hello_trellis.c)
  target_link_libraries(trellis_c_hello PRIVATE trellis_c)
  add_executable(trellis_cpp_hello examples/cpp/hello_trellis.cpp)
  target_link_libraries(trellis_cpp_hello PRIVATE trellis_c)
endif()

# --- Install / find_package(Trellis) ---
install(TARGETS trellis_c
  EXPORT TrellisTargets
  ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
  LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
  RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
  INCLUDES DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}
)
install(FILES c_abi/trellis.h DESTINATION ${CMAKE_INSTALL_INCLUDEDIR})
install(DIRECTORY core/include/trellis DESTINATION ${CMAKE_INSTALL_INCLUDEDIR})
install(FILES cpp/trellis.hpp DESTINATION ${CMAKE_INSTALL_INCLUDEDIR})

install(EXPORT TrellisTargets
  FILE TrellisTargets.cmake
  NAMESPACE Trellis::
  DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/Trellis
)

configure_package_config_file(
  cmake/TrellisConfig.cmake.in
  ${CMAKE_CURRENT_BINARY_DIR}/TrellisConfig.cmake
  INSTALL_DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/Trellis
)
write_basic_package_version_file(
  ${CMAKE_CURRENT_BINARY_DIR}/TrellisConfigVersion.cmake
  VERSION ${PROJECT_VERSION}
  COMPATIBILITY SameMajorVersion
)
install(FILES
  ${CMAKE_CURRENT_BINARY_DIR}/TrellisConfig.cmake
  ${CMAKE_CURRENT_BINARY_DIR}/TrellisConfigVersion.cmake
  DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/Trellis
)
