cmake_minimum_required(VERSION 3.19)

file(READ "${CMAKE_SOURCE_DIR}/VERSION" VER_RAW)
string(STRIP ${VER_RAW} ABYSSUTILS_VERSION)
add_compile_definitions(ABYSSUTILS_VERSION="${ABYSSUTILS_VERSION}")

project(
  abyssutils
  VERSION ${ABYSSUTILS_VERSION}
  DESCRIPTION "Small C++ library for utilities used across the Abyss* ecosystem")

# Keep the historical defaults while honoring an explicit cache/parent choice.
if(CMAKE_BUILD_TYPE MATCHES Debug OR CMAKE_BUILD_TYPE MATCHES DEBUG)
  option(BUILD_TESTING "Build tests" ON)
else()
  option(BUILD_TESTING "Build tests" OFF)
endif()
include(CTest)
include(GNUInstallDirs)

set(PREFIX ${CMAKE_INSTALL_PREFIX})
set(INCLUDE ${CMAKE_INSTALL_FULL_INCLUDEDIR})
set(LIBDIR ${CMAKE_INSTALL_FULL_LIBDIR})

configure_file(abyssutils.pc.in abyssutils.pc @ONLY)

set(CMAKE_CXX_STANDARD 26)
add_compile_options(
  -Wall
  -Wextra
  -Wpedantic
  -Wno-unused-parameter
  -Wno-unused-value
  -Wno-missing-field-initializers
  -Wno-narrowing
  -Wno-pointer-arith)
set(CMAKE_EXPORT_COMPILE_COMMANDS TRUE)

if(CMAKE_BUILD_TYPE MATCHES Debug OR CMAKE_BUILD_TYPE MATCHES DEBUG)
  message(STATUS "Configuring abyssutils in Debug")
  add_compile_definitions(ABYSSLAND_DEBUG)
else()
  add_compile_options(-O3)
  message(STATUS "Configuring abyssutils in Release")
endif()

file(GLOB_RECURSE SRCFILES CONFIGURE_DEPENDS "src/*.cpp" "include/*.hpp")
file(GLOB_RECURSE PUBLIC_HEADERS CONFIGURE_DEPENDS "include/*.hpp")
list(FILTER SRCFILES EXCLUDE REGEX "eventLoop/backend/(Epoll|Kqueue)\\.cpp$")

if(CMAKE_SYSTEM_NAME STREQUAL "Linux")
  list(APPEND SRCFILES "${CMAKE_CURRENT_SOURCE_DIR}/src/eventLoop/backend/Epoll.cpp")
elseif(CMAKE_SYSTEM_NAME MATCHES "FreeBSD|OpenBSD|NetBSD|DragonFly")
  find_package(Threads REQUIRED)
  set(EVENT_LOOP_LIBRARIES Threads::Threads)
  list(APPEND SRCFILES "${CMAKE_CURRENT_SOURCE_DIR}/src/eventLoop/backend/Kqueue.cpp")
else()
  message(FATAL_ERROR "Unsupported event-loop platform: ${CMAKE_SYSTEM_NAME}")
endif()

find_package(PkgConfig REQUIRED)
pkg_check_modules(deps REQUIRED IMPORTED_TARGET pixman-1)

add_library(abyssutils SHARED ${SRCFILES})
target_include_directories(
  abyssutils
  PUBLIC "./include"
  PRIVATE "./src")
set_target_properties(abyssutils PROPERTIES VERSION ${abyssutils_VERSION}
                                           SOVERSION 13)
target_link_libraries(abyssutils PkgConfig::deps ${EVENT_LOOP_LIBRARIES})

if(BUILD_TESTING)
  # GTest
  find_package(GTest CONFIG REQUIRED)
  include(GoogleTest)
  file(GLOB_RECURSE TESTFILES CONFIGURE_DEPENDS "tests/*.cpp")
  add_executable(abyssutils_tests ${TESTFILES})

  target_compile_options(abyssutils_tests PRIVATE --coverage -fsanitize=address)
  target_link_options(abyssutils_tests PRIVATE --coverage)
  
  target_include_directories(
    abyssutils_tests
    PUBLIC "./include"
    PRIVATE "./src" "./src/include" "./protocols" "${CMAKE_BINARY_DIR}")
  target_link_libraries(abyssutils_tests PRIVATE asan abyssutils GTest::gtest_main
                                                       PkgConfig::deps)
  gtest_discover_tests(abyssutils_tests
    PROPERTIES ENVIRONMENT "ASAN_OPTIONS=detect_leaks=0"
  )

  # Add coverage to abyssutils for test builds
  target_compile_options(abyssutils PRIVATE --coverage)
  target_link_options(abyssutils PRIVATE --coverage)
endif()

# Installation
install(TARGETS abyssutils)
install(DIRECTORY "include/abyssutils" DESTINATION ${CMAKE_INSTALL_INCLUDEDIR})
install(FILES ${CMAKE_BINARY_DIR}/abyssutils.pc
        DESTINATION ${CMAKE_INSTALL_LIBDIR}/pkgconfig)
