# ── Unit tests ────────────────────────────────────────────────────────────────
# Pure, GPU-free, model-free tests. The similarity tests compile the GEMM backend
# directly with SAE_GEMM_CPU so the suite builds and runs on a machine without a
# GPU regardless of the main build's SAE_GEMM_BACKEND selection.

find_package(Catch2 3 QUIET)
if(NOT Catch2_FOUND)
    include(FetchContent)
    FetchContent_Declare(
        Catch2
        GIT_REPOSITORY https://github.com/catchorg/Catch2.git
        GIT_TAG        v3.5.3
    )
    FetchContent_MakeAvailable(Catch2)
endif()

add_executable(sae_tests
    test_similarity.cpp
    test_calibration.cpp
    test_gallery_store.cpp
    test_face_utils.cpp
    test_track_gallery.cpp
    test_face_tracker.cpp
    test_track_registry.cpp
    test_face_detector_node.cpp
    test_scene_detector_node.cpp
    test_replay_fixtures.cpp
    test_embedding_dump.cpp
    test_audio_signature.cpp
    test_benchmark.cpp
    test_channel_bytes.cpp
    ${CMAKE_SOURCE_DIR}/src/backends/gemm_backend.cpp
    ${CMAKE_SOURCE_DIR}/src/gallery/gallery_store.cpp
    ${CMAKE_SOURCE_DIR}/src/audio_signature.cpp
    ${CMAKE_SOURCE_DIR}/src/gallery/embedder_stamp.cpp
)
target_include_directories(sae_tests PRIVATE ${CMAKE_SOURCE_DIR}/src)
# SAE_GEMM_CPU: build the CPU reference GEMM regardless of the main backend.
# SAE_MODELS_DIR: config.hpp (pulled in by track_gallery.hpp) bakes model paths.
# SAE_TEST_FIXTURES_DIR: the audio golden vector is read from the source tree,
# not copied, so the file the plugin repo shares is the file under test.
# AR-026/AR-027: exercise the same kernel CI actually runs. Without this the
# suite compiles the scalar fallback while the CPU builder image links OpenBLAS,
# so the tested path and the shipped path would differ.
find_package(PkgConfig QUIET)
if(PkgConfig_FOUND)
    pkg_check_modules(OPENBLAS_T QUIET openblas)
endif()
if(OPENBLAS_T_FOUND)
    target_include_directories(sae_tests PRIVATE ${OPENBLAS_T_INCLUDE_DIRS})
    target_link_libraries(sae_tests PRIVATE ${OPENBLAS_T_LINK_LIBRARIES})
elseif(NOT SAE_ALLOW_SCALAR_GEMM)
    # Same rule as the CPU backend itself: testing the scalar loop while the
    # shipped CPU path is OpenBLAS means the suite is not evidence about the
    # kernel that runs.
    message(FATAL_ERROR
        "OpenBLAS not found, and the unit tests compile the CPU GEMM kernel "
        "(AR-026). Install openblas-devel, or pass -DSAE_ALLOW_SCALAR_GEMM=ON "
        "to test the scalar fallback deliberately.")
endif()

target_compile_definitions(sae_tests PRIVATE
    $<$<BOOL:${OPENBLAS_T_FOUND}>:SAE_GEMM_CBLAS>
    SAE_GEMM_CPU
    SAE_MODELS_DIR="${SAE_MODELS_DIR}"
    SAE_TEST_FIXTURES_DIR="${CMAKE_CURRENT_SOURCE_DIR}/fixtures")
# gallery_store.cpp + gallery_calibration.hpp use nlohmann/json and HDF5
# (galleries are HDF5-native, see src/gallery/gallery_store.cpp); face_utils.hpp
# and the calibration GEMM pull in OpenCV (calib3d/imgproc/core) via types.hpp.
# ffmpeg_libs: audio_signature.cpp decodes the golden fixture (avformat/avcodec/
# avutil/swresample). Still GPU-free — the audio path is pure CPU.
target_link_libraries(sae_tests PRIVATE
    Catch2::Catch2WithMain
    nlohmann_json::nlohmann_json
    # VR-015: test_benchmark.cpp includes src/benchmark.hpp, which reads KPN's
    # diagnostics structs. Header-only — no KPN network is constructed here, so
    # the cost attribution stays testable on CI's GPU-free N100.
    kpn
    ffmpeg_libs
    ${OpenCV_LIBS}
    ${HDF5_CXX_LIBRARIES})
target_include_directories(sae_tests PRIVATE ${HDF5_INCLUDE_DIRS})

include(CTest)
include(Catch)
catch_discover_tests(sae_tests)
