# scavenger_core: the native C++ data plane library.
#
# Backend-agnostic pieces (task queue, hardware poller, scoring, memory
# manager, scheduler) stay free of OpenVINO/llama.cpp/Vulkan dependencies so
# this library builds and its full test suite runs in CI (no Intel SDKs on
# hosted runners) - see PHASE_PLAN.md Phase 2. Only the concrete backend
# implementations (core/src/backends/) need those SDKs, gated behind
# SCAVENGER_BUILD_BACKENDS below.

# moodycamel::ConcurrentQueue: header-only lock-free MPMC queue backing
# TaskQueue<T> (core/include/scavenger/task_queue.hpp). Fetched rather than
# vendored as a submodule since it's a single header with no build step of
# its own - see PHASE_PLAN.md Phase 2 commit 1.
include(FetchContent)
FetchContent_Declare(
    concurrentqueue
    GIT_REPOSITORY https://github.com/cameron314/concurrentqueue.git
    GIT_TAG v1.0.5
)
FetchContent_MakeAvailable(concurrentqueue)

add_library(scavenger_core STATIC
    src/version.cpp
    src/hw_poller.cpp
    src/scoring.cpp
    src/memory_manager.cpp
    src/scheduler.cpp
    # Phase M1: NVML-based dGPU utilization source. Always compiled
    # (unconditionally, unlike the CUDA *inference* backend below) since it
    # has no CUDA-toolkit/link-time dependency at all - NVML is loaded at
    # runtime via LoadLibrary/dlopen (see the header's design-goals comment)
    # so this is safe to include in every build; IsAvailable() is simply
    # false on a machine with no NVIDIA driver.
    src/nvml_utilization_source.cpp
    # Phase M1: merges a primary (PDH) source with the optional NVML source
    # above into the single UtilizationSnapshot HwPoller polls - see its
    # header for why this exists as a shared class rather than duplicated
    # inline in bindings/pybind_module.cpp and core/tools/scheduler_demo.cpp.
    src/combined_utilization_source.cpp
)

# pdh_utilization_source.cpp is guarded end-to-end with #ifdef _WIN32 (see
# core/include/scavenger/pdh_utilization_source.hpp) so it's harmless to
# always list it, but it's only added on Windows to avoid compiling an
# empty translation unit elsewhere and to keep the Pdh.lib link requirement
# scoped to where it's actually needed.
if(WIN32)
    target_sources(scavenger_core PRIVATE src/pdh_utilization_source.cpp)
    target_link_libraries(scavenger_core PRIVATE Pdh)
endif()

target_include_directories(scavenger_core
    PUBLIC
        $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>
)

target_link_libraries(scavenger_core PUBLIC concurrentqueue)

target_compile_features(scavenger_core PUBLIC cxx_std_17)

if(MSVC)
    target_compile_options(scavenger_core PRIVATE /W4)
else()
    target_compile_options(scavenger_core PRIVATE -Wall -Wextra -Wpedantic)
endif()

# SCAVENGER_BUILD_BACKENDS/SCAVENGER_BUILD_IMAGE_GEN are declared in the
# root CMakeLists.txt (SCAVENGER_BUILD_BACKENDS also gates the
# third_party/llama.cpp add_subdirectory(), which must happen before this
# file is processed). core/src/backends/CMakeLists.txt itself further
# gates openvino_image_backend.cpp behind SCAVENGER_BUILD_IMAGE_GEN
# specifically, so either flag alone is enough to reach this directory.
if(SCAVENGER_BUILD_BACKENDS OR SCAVENGER_BUILD_IMAGE_GEN)
    add_subdirectory(src/backends)
endif()

if(SCAVENGER_BUILD_TESTS)
    add_subdirectory(tests)
endif()

if(SCAVENGER_BUILD_HARDWARE_TOOLS)
    add_subdirectory(tools)
endif()
