set(CMAKE_INSTALL_RPATH_USE_LINK_PATH TRUE)

add_library(tent_interface INTERFACE)
target_include_directories(
  tent_interface
  INTERFACE $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/../include>
            $<INSTALL_INTERFACE:include>)
target_compile_features(tent_interface INTERFACE cxx_std_20)

if(TARGET asio_shared)
  target_link_libraries(tent_interface INTERFACE asio_shared)
endif()

# CUDA
if(USE_CUDA)
  find_package(CUDAToolkit REQUIRED)
  message(STATUS "CUDA: Enabled")
  target_compile_definitions(tent_interface INTERFACE USE_CUDA)
  target_include_directories(tent_interface
                             INTERFACE ${CUDAToolkit_INCLUDE_DIRS})
  target_link_libraries(tent_interface INTERFACE CUDA::cudart)
else()
  message(STATUS "CUDA: Disabled")
endif()

# ROCm / HIP
if(USE_HIP)
  list(APPEND CMAKE_PREFIX_PATH "/opt/rocm/lib/cmake")
  find_package(HIP REQUIRED)
  message(STATUS "ROCm/HIP: Enabled")
  target_compile_definitions(tent_interface INTERFACE USE_HIP
                                                      __HIP_PLATFORM_AMD__)
  target_include_directories(tent_interface INTERFACE ${HIP_INCLUDE_DIRS})
  target_link_libraries(tent_interface INTERFACE hip::host)
else()
  message(STATUS "ROCm/HIP: Disabled")
endif()

# GDS
find_library(CUFILE_LIB cufile HINTS ${CUDAToolkit_LIBRARY_DIR})
find_path(CUFILE_INCLUDE cufile.h HINTS ${CUDAToolkit_INCLUDE_DIRS})
if(USE_CUDA
   AND CUDAToolkit_FOUND
   AND CUFILE_LIB
   AND CUFILE_INCLUDE)
  message(STATUS "GDS: Enabled")
  target_compile_definitions(tent_interface INTERFACE USE_GDS)
  target_include_directories(tent_interface INTERFACE ${CUFILE_INCLUDE})
  target_link_libraries(tent_interface INTERFACE ${CUFILE_LIB})
else()
  message(STATUS "GDS: Disabled")
endif()

# RDMA (ibverbs)
find_library(IBVERBS_LIB ibverbs PATHS /usr/lib /usr/lib64 /usr/local/lib
                                       /usr/local/lib64)
find_path(IBVERBS_INCLUDE infiniband/verbs.h PATHS /usr/include
                                                   /usr/local/include)
if(IBVERBS_LIB AND IBVERBS_INCLUDE)
  message(STATUS "RDMA: Enabled")
  target_compile_definitions(tent_interface INTERFACE USE_RDMA)
  target_include_directories(tent_interface INTERFACE ${IBVERBS_INCLUDE})
  target_link_libraries(tent_interface INTERFACE ${IBVERBS_LIB})
else()
  message(STATUS "RDMA: Disabled")
endif()

# io_uring
if(TARGET Mooncake::liburing)
  message(STATUS "Uring: Enabled")
  target_compile_definitions(tent_interface INTERFACE USE_URING)
  target_link_libraries(tent_interface INTERFACE Mooncake::liburing)
else()
  message(STATUS "Uring: Disabled")
endif()

if(USE_SUNRISE)
  target_compile_definitions(tent_interface INTERFACE USE_SUNRISE)
  target_include_directories(tent_interface INTERFACE ${MC_TANGRT_ROOT}/include)
  target_link_directories(
    tent_interface INTERFACE ${MC_TANGRT_ROOT}/lib/linux-x86_64
    ${MC_TANGRT_ROOT}/lib)
  target_link_libraries(tent_interface INTERFACE tangrt_shared ptml_shared dl)
endif()

add_subdirectory(common)
add_subdirectory(rpc)
add_subdirectory(metastore)
add_subdirectory(runtime)
add_subdirectory(platform)
add_subdirectory(transport)
add_subdirectory(metrics)
if(NOT TARGET pybind11::module)
  find_package(pybind11 QUIET)
endif()
if(TARGET pybind11::module)
  add_subdirectory(python)
else()
  message(STATUS "pybind11 not found, skipping Tent Python bindings")
endif()

file(GLOB TENT_ENGINE_SOURCES "${CMAKE_CURRENT_SOURCE_DIR}/*.cpp")

add_library(tent STATIC ${TENT_ENGINE_SOURCES})
target_link_libraries(tent PUBLIC tent_runtime tent_interface)

add_library(tent_shared SHARED ${TENT_ENGINE_SOURCES})
target_link_libraries(tent_shared PUBLIC tent_runtime tent_interface)

add_library(tent_link_group INTERFACE)
target_link_libraries(tent_link_group INTERFACE "-Wl,--start-group" tent)
foreach(
  tgt
  metastore_redis
  metastore_http
  metastore_etcd
  tent_platform_all
  platform_cuda
  platform_rocm
  platform_ascend
  platform_sunrise
  platform_tpu
  tent_xport_gds
  tent_xport_uring
  tent_xport_bufio
  tent_xport_mnnvl
  tent_xport_nvlink
  tent_xport_rdma
  tent_xport_shm
  tent_xport_tcp
  tent_xport_ub
  tent_xport_ascend_direct
  tent_xport_sunrise_link
  tent_xport_tpu
  tent_xport_mpcomm
  tent_metrics)
  if(TARGET ${tgt})
    target_link_libraries(tent_link_group INTERFACE ${tgt})
  endif()
endforeach()
if(TARGET mooncake_common)
  # Use the archive path so CMake does not de-duplicate mooncake_common against
  # an earlier transitive occurrence. TENT RPC objects reference the Transfer
  # Engine client I/O pool accessor and need the archive inside this rescan
  # group when all components are linked statically.
  target_link_libraries(tent_link_group
                        INTERFACE "$<TARGET_FILE:mooncake_common>")
endif()
target_link_libraries(tent_link_group INTERFACE "-Wl,--end-group")
install(
  TARGETS tent_shared
  ARCHIVE DESTINATION lib
  LIBRARY DESTINATION lib
  RUNTIME DESTINATION bin)
