cmake_minimum_required(VERSION 3.16)
project(_p2pstream_core CXX)

set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_POSITION_INDEPENDENT_CODE ON)

if(NOT CMAKE_BUILD_TYPE)
  set(CMAKE_BUILD_TYPE Release)
endif()

add_compile_options(
  $<$<CONFIG:Release>:-O3>
  $<$<CONFIG:Release>:-march=native>
  $<$<CONFIG:Release>:-ffast-math>
  $<$<CONFIG:Release>:-funroll-loops>
)

find_package(Python3 REQUIRED COMPONENTS Interpreter Development)

execute_process(
  COMMAND "${Python3_EXECUTABLE}" -c "import pybind11; print(pybind11.get_cmake_dir())"
  OUTPUT_VARIABLE PYBIND11_CMAKE_DIR
  OUTPUT_STRIP_TRAILING_WHITESPACE
  RESULT_VARIABLE _pb11_rc
)
if(NOT _pb11_rc EQUAL 0)
  message(FATAL_ERROR "pybind11 not found. Run: pip install pybind11")
endif()
list(APPEND CMAKE_PREFIX_PATH "${PYBIND11_CMAKE_DIR}")
find_package(pybind11 REQUIRED CONFIG)

find_package(OpenSSL REQUIRED)

find_package(PkgConfig QUIET)
if(PKG_CONFIG_FOUND)
  pkg_check_modules(LZ4 QUIET liblz4)
endif()
if(NOT LZ4_FOUND)
  find_library(LZ4_LIB lz4)
  find_path(LZ4_INC lz4.h)
  if(LZ4_LIB AND LZ4_INC)
    set(LZ4_LIBRARIES   ${LZ4_LIB})
    set(LZ4_INCLUDE_DIRS ${LZ4_INC})
    set(LZ4_FOUND TRUE)
  endif()
endif()

find_library(MINIUPNPC_LIB miniupnpc)
find_path(MINIUPNPC_INC miniupnpc/miniupnpc.h)

pybind11_add_module(_p2pstream_core MODULE
  codec.cpp
  nat_traversal.cpp
  bindings.cpp
)

target_include_directories(_p2pstream_core PRIVATE
  ${CMAKE_CURRENT_SOURCE_DIR}
  ${OPENSSL_INCLUDE_DIR}
)

target_link_libraries(_p2pstream_core PRIVATE OpenSSL::Crypto)

if(LZ4_FOUND)
  message(STATUS "LZ4 found — enabling frame compression")
  target_include_directories(_p2pstream_core PRIVATE ${LZ4_INCLUDE_DIRS})
  target_link_libraries(_p2pstream_core PRIVATE ${LZ4_LIBRARIES})
  target_compile_definitions(_p2pstream_core PRIVATE HAS_LZ4)
else()
  message(STATUS "LZ4 not found — compression disabled (pass-through mode)")
endif()

if(MINIUPNPC_LIB AND MINIUPNPC_INC)
  message(STATUS "miniupnpc found — enabling UPnP IGD")
  target_include_directories(_p2pstream_core PRIVATE ${MINIUPNPC_INC})
  target_link_libraries(_p2pstream_core PRIVATE ${MINIUPNPC_LIB})
  target_compile_definitions(_p2pstream_core PRIVATE HAS_MINIUPNPC)
else()
  message(STATUS "miniupnpc not found — UPnP disabled")
endif()

if(UNIX)
  target_link_libraries(_p2pstream_core PRIVATE pthread)
endif()
