cmake_minimum_required(VERSION 3.14)
project(sparkd)

include(FetchContent)
include(${CMAKE_SOURCE_DIR}/cmake/safe_dep_glob.cmake)
include(${CMAKE_SOURCE_DIR}/cmake/ProtobufGenerateCpp.cmake)
include(${CMAKE_SOURCE_DIR}/cmake/InstallBasic.cmake)
include(GNUInstallDirs)

if (NOT DEFINED PROJECT_VERSION)
  set(PROJECT_VERSION 1.0.0)
endif()

# dependencies
file(
  GLOB_RECURSE ${PROJECT_NAME}_PROTO_SOURCES
  RELATIVE ${CMAKE_CURRENT_SOURCE_DIR}
  *.proto
)
file(
  GLOB_RECURSE ${PROJECT_NAME}_SOURCES
  RELATIVE ${CMAKE_CURRENT_SOURCE_DIR}
  *.cpp
)
update_deps_file("${${PROJECT_NAME}_PROTO_SOURCES};${${PROJECT_NAME}_SOURCES}")

protobuf_generate_cpp(
  CXX_SOURCES ${PROJECT_NAME}_PROTO_CXX_SOURCES
  CXX_HEADERS ${PROJECT_NAME}_PROTO_CXX_HEADERS
  CXX_OUT_DIR ${CMAKE_CURRENT_BINARY_DIR}/include
  PROTO_INCLUDE_DIRS
    ${EXTERNALS_INCLUDE}
    ${CMAKE_SOURCE_DIR}/src/lib_spark
    ${CMAKE_CURRENT_SOURCE_DIR}
  PROTO_SOURCES
    ${${PROJECT_NAME}_PROTO_SOURCES}
)
add_executable(sparkd ${${PROJECT_NAME}_SOURCES} ${${PROJECT_NAME}_PROTO_CXX_SOURCES})

# include paths
target_include_directories(
  sparkd
  PUBLIC
    $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}>
    $<BUILD_INTERFACE:${CMAKE_CURRENT_BINARY_DIR}>/include
    $<BUILD_INTERFACE:${emumba-deribit-connector-library_INCLUDE_DIRS}>
)

find_package(PkgConfig REQUIRED)
pkg_check_modules(emumba-deribit-connector-library REQUIRED emumba-deribit-connector)

# This dir contains rapidjsonConfig.cmake
list(APPEND CMAKE_PREFIX_PATH ${CMAKE_CURRENT_SOURCE_DIR}/cmake_modules)
find_package(rapidjson REQUIRED)
target_include_directories(
  ${PROJECT_NAME} SYSTEM
  PUBLIC
    $<BUILD_INTERFACE:${rapidjson_INCLUDE_DIR}> 
)
add_dependencies(${PROJECT_NAME} rapidjson_project)

# databento
FetchContent_Declare(
  databento
  GIT_REPOSITORY https://github.com/databento/databento-cpp
  GIT_TAG v0.31.0
)
FetchContent_MakeAvailable(databento)

# deribit-demo log level
if(NOT DEFINED DERIBIT_DEMO_LOG_LEVEL)
  add_definitions(-DSPDLOG_ACTIVE_LEVEL=0)
  message("-- Building of DERIBIT_DEMO_LOG_LEVEL=TRACE")
elseif(DERIBIT_DEMO_LOG_LEVEL STREQUAL "TRACE")
  add_definitions(-DSPDLOG_ACTIVE_LEVEL=0)
  message("-- Building of DERIBIT_DEMO_LOG_LEVEL=TRACE")
elseif(DERIBIT_DEMO_LOG_LEVEL STREQUAL "DEBUG")
  add_definitions(-DSPDLOG_ACTIVE_LEVEL=1)
  message("-- Building of DERIBIT_DEMO_LOG_LEVEL=DEBUG")
elseif(DERIBIT_DEMO_LOG_LEVEL STREQUAL "INFO")
  add_definitions(-DSPDLOG_ACTIVE_LEVEL=2)
  message("-- Building of DERIBIT_DEMO_LOG_LEVEL=INFO")
elseif(DERIBIT_DEMO_LOG_LEVEL STREQUAL "WARN")
  add_definitions(-DSPDLOG_ACTIVE_LEVEL=3)
  message("-- Building of DERIBIT_DEMO_LOG_LEVEL=WARN")
elseif(DERIBIT_DEMO_LOG_LEVEL STREQUAL "ERROR")
  add_definitions(-DSPDLOG_ACTIVE_LEVEL=4)
  message("-- Building of DERIBIT_DEMO_LOG_LEVEL=ERROR")
elseif(DERIBIT_DEMO_LOG_LEVEL STREQUAL "CRITICAL")
  add_definitions(-DSPDLOG_ACTIVE_LEVEL=5)
  message("-- Building of DERIBIT_DEMO_LOG_LEVEL=CRITICAL")
elseif(DERIBIT_DEMO_LOG_LEVEL STREQUAL "OFF")
  add_definitions(-DSPDLOG_ACTIVE_LEVEL=6)
  message("-- Building of DERIBIT_DEMO_LOG_LEVEL=OFF")
else()
  add_definitions(-DSPDLOG_ACTIVE_LEVEL=0)
  message("-- Building of DERIBIT_DEMO_LOG_LEVEL=TRACE")
endif()

target_link_directories(
  ${PROJECT_NAME} PUBLIC
  $<BUILD_INTERFACE:${CMAKE_CURRENT_BINARY_DIR}>
  $<INSTALL_INTERFACE:${CMAKE_INSTALL_LIBDIR}>
)

# Set RPATH so sparkd knows where to find our shared libs (e.g., libspark).
# The dirs are relative to sparkd's path, represented by "$ORIGIN".
set_target_properties(
  ${PROJECT_NAME} PROPERTIES
  BUILD_RPATH "$ORIGIN/../lib_spark;$ORIGIN/../lib_python_interop"
  INSTALL_RPATH "$ORIGIN/../${CMAKE_INSTALL_LIBDIR}"
)

include(${CMAKE_SOURCE_DIR}/cmake/SymLink.cmake)
include(${CMAKE_SOURCE_DIR}/cmake/SymLinkPythonModule.cmake)
# Py interop
sym_link_python_module(
  LIB_NAME python_interop
  MODULE_NAME python_interop_module
  PLUGIN_NAME python_interop_plugins
)
target_link_libraries(
  sparkd
  spark
  binance
  okx_execution
  python_interop
  python_interop_module
  databento::databento
  ${emumba-deribit-connector-library_LIBRARIES}
  tbb
  quickfix
  benchmark
  Common++
  Packet++
  Pcap++
  lttng-ust
  -lpcap
  -static-libgcc
  -static-libstdc++
  -pthread)

# Onixs
target_link_libraries(
  ${PROJECT_NAME}
  onixs-cmemdh
  OnixS.IceImpactMulticastPriceFeedHandlerCpp
  # gcc doesn't resolve onixs-fix-engine and ACE in runtime path unless we specify
  # --no-as-needed. These are onixs deps that aren't called directly by our code.
  # Note: this isn't an issue for clang
  -Wl,--no-as-needed
  onixs-fix-engine
  ACE
)

# Catch2
find_package(Catch2 CONFIG REQUIRED)
target_link_libraries(${PROJECT_NAME} Catch2::Catch2)

install_basic()
install(
  FILES
    "${EXTERNALS_LIB}/libonixs-cmemdh.so"
    "${EXTERNALS_LIB}/libonixs-cmemdh.so.4"
    "${EXTERNALS_LIB}/libonixs-cmemdh.so.4.8.0"
    "${EXTERNALS_LIB}/libOnixS.IceImpactMulticastPriceFeedHandlerCpp.so.3.16.0.0"
    "${EXTERNALS_LIB}/libonixs-fix-engine.so"
    "${EXTERNALS_LIB}/libonixs-fix-engine.so.4"
    "${EXTERNALS_LIB}/libonixs-fix-engine.so.4.10.1"
    "${EXTERNALS_LIB}/libACE-5.7.5.so"
  DESTINATION ${CMAKE_INSTALL_LIBDIR}
)
