cmake_minimum_required(VERSION 3.12)
project(spark)
include(GNUInstallDirs)
include(${CMAKE_SOURCE_DIR}/cmake/GitVersion.cmake)
set(CMAKE_CXX_STANDARD 20)

get_version_from_git()
if(WIN32)
  set(platform "windows")
else()
  set(platform "linux")
endif()

set(
  EXTERNALS_ROOT
  "${CMAKE_SOURCE_DIR}/externals/${platform}"
  CACHE
  STRING
  "External dependencies root folder (should contain folders: lib, bin, include")

# SHARED_MEMORY_PREFIX serves as a kind of namespace so multiple applications
# can run simultaneously without fighting over the same shm files (e.g., sparkd,
# api server, etc.).
set(SHARED_MEMORY_PREFIX "\${BTS_SHARED_MEMORY_PREFIX}" CACHE STRING "Prefix to use when creating shared memory files")
set(EXTERNALS_BIN "${EXTERNALS_ROOT}/bin")
set(EXTERNALS_INCLUDE "${EXTERNALS_ROOT}/include")
set(EXTERNALS_LIB "${EXTERNALS_ROOT}/lib/$<CONFIG>")
set(BUILD_DOCS OFF CACHE BOOL "Build documentation")
set(BUILD_SDK OFF CACHE BOOL "Build the sdk")
set(EXPORT_MD_CONSUMER OFF CACHE BOOL "Export (extern) C functions for MD consumer interop")
if (WIN32)
  set(BUILD_SPARKD OFF CACHE BOOL "Build sparkd")
  set(BUILD_ADMIN_WEB_APP OFF CACHE BOOL "Build the Admin WebApp")
else()
  set(BUILD_SPARKD ON CACHE BOOL "Build sparkd")
  set(BUILD_ADMIN_WEB_APP ON CACHE BOOL "Build the Admin WebApp")
endif()

include_directories(BEFORE SYSTEM ${EXTERNALS_INCLUDE} ${EXTERNALS_ROOT}/include/zlib)
link_directories(${EXTERNALS_LIB})

add_compile_definitions(SHARED_MEMORY_PREFIX="${SHARED_MEMORY_PREFIX}")
if(DEFINED APP_DATA_DIR)
  add_compile_definitions(APP_DATA_DIR="${APP_DATA_DIR}")
endif()
add_compile_definitions(EXPORT_MD_CONSUMER="${EXPORT_MD_CONSUMER}")
if(WIN32)
  # subdirs
  add_subdirectory(src/lib_spark)
else()
  if(BUILD_SPARKD)
    # Note: All macros that begin w/ 'CCAPI' are ccapi's macros (defined and/or
    # read by their code). We override some below.
    add_compile_definitions(SPARK_ENABLE_CCAPI)

    # This allows us to override hardcoded exchange-urls with ones read from
    # config (i.e., resolved at runtime rather than compile-time)
    add_compile_definitions(CCAPI_EXPOSE_INTERNAL)

    # Enable ccapi services
    add_compile_definitions(CCAPI_ENABLE_SERVICE_MARKET_DATA)
    add_compile_definitions(CCAPI_ENABLE_SERVICE_EXECUTION_MANAGEMENT)
    # Enable ccapi exchanges
    add_compile_definitions(CCAPI_ENABLE_EXCHANGE_BINANCE)
    add_compile_definitions(CCAPI_ENABLE_EXCHANGE_BINANCE_COIN_FUTURES)
    add_compile_definitions(CCAPI_ENABLE_EXCHANGE_BINANCE_US)
    add_compile_definitions(CCAPI_ENABLE_EXCHANGE_BINANCE_USDS_FUTURES)
    add_compile_definitions(CCAPI_ENABLE_EXCHANGE_COINBASE)
    add_compile_definitions(CCAPI_ENABLE_EXCHANGE_DERIBIT)
    add_compile_definitions(CCAPI_ENABLE_EXCHANGE_OKX)

    set(CCAPI_LOG_LEVEL
      "Warn"
      CACHE STRING "<Fatal|Error|Warn|Info|Debug|Trace> Log level for ccapi")
    string(TOUPPER "${CCAPI_LOG_LEVEL}" _ccapi_log_level_upper)
    add_compile_definitions("CCAPI_ENABLE_LOG_${_ccapi_log_level_upper}")

    # ** Binance **
    add_compile_definitions(CCAPI_BINANCE_URL_REST_BASE="https://api.binance.com")
    add_compile_definitions(BINANCE_INSTRUMENTS_PATH="/api/v3/exchangeInfo")
    add_compile_definitions(BINANCE_PRICE_STATS_PATH="/api/v3/ticker/24hr")

    # ** Binance US **
    add_compile_definitions(BINANCE_US_INSTRUMENTS_PATH="/api/v3/exchangeInfo")
    add_compile_definitions(BINANCE_US_PRICE_STATS_PATH="/api/v3/ticker/24hr")

    # ** Binance USDS Futures **
    add_compile_definitions(CCAPI_BINANCE_USDS_FUTURES_URL_REST_BASE="https://fapi.binance.com")
    add_compile_definitions(BINANCE_USDS_FUTURES_INSTRUMENTS_PATH="/fapi/v1/exchangeInfo")
    add_compile_definitions(BINANCE_USDS_FUTURES_PRICE_STATS_PATH="/fapi/v1/ticker/24hr")
    add_compile_definitions(BINANCE_USDS_FUTURES_USER_DATA_PATH="/api/v3/userDataStream")

    # ** Binance Coin Futures **
    add_compile_definitions(CCAPI_BINANCE_COIN_FUTURES_URL_REST_BASE="https://dapi.binance.com")
    add_compile_definitions(BINANCE_COIN_FUTURES_INSTRUMENTS_PATH="/dapi/v1/exchangeInfo")
    add_compile_definitions(BINANCE_COIN_FUTURES_PRICE_STATS_PATH="/dapi/v1/ticker/24hr")

    # ** Deribit **
    add_compile_definitions(DERIBIT_INSTRUMENT_PATH="/api/v2/public/get_instrument")
    add_compile_definitions(DERIBIT_INSTRUMENTS_PATH="/api/v2/public/get_instruments")
    add_compile_definitions(DERIBIT_COMBOS_PATH="/api/v2/public/get_combos")
    add_compile_definitions(DERIBIT_TICKER_PATH="/api/v2/public/ticker")
    add_compile_definitions(DERIBIT_CURRENCIES_METHOD="public/get_currencies")
    add_compile_definitions(DERIBIT_INSTRUMENT_METHOD="public/get_instrument")
    add_compile_definitions(DERIBIT_INSTRUMENTS_METHOD="public/get_instruments")
    add_compile_definitions(DERIBIT_COMBO_DETAILS_METHOD="public/get_combo_details")
    add_compile_definitions(DERIBIT_COMBOS_METHOD="public/get_combos")

    # ** Okx **
    add_compile_definitions(OKX_INSTRUMENTS_PATH="/api/v5/public/instruments")
    add_compile_definitions(OKX_UNDERLYING_PATH="/api/v5/public/underlying")
  endif()

  # subdirs
  add_subdirectory(src/lib_spark)
  if (BUILD_SPARKD)
    add_subdirectory(src/lib_python_interop)
    add_subdirectory(src/lib_onixs_fix)
    add_subdirectory(src/lib_binance)
    add_subdirectory(src/lib_okx_execution)
    add_subdirectory(src/app_sparkd)
    add_subdirectory(src/data_files)
  endif()
  if (BUILD_ADMIN_WEB_APP)
    add_subdirectory(src/Spark.Admin.WebApp)
  endif()
  if(BUILD_DOCS)
    add_subdirectory(doc/user)
  endif()
  if(BUILD_SDK)
    add_subdirectory(src/sdk)
  endif()
endif()
