# SPDX-License-Identifier: GPL-3.0-or-later
# SPDX-FileCopyrightText: 2025 ai-ad4 and the FreePDFEditor contributors
#
# Spike F — ADR-0005 Rust-vs-C++ build-friction probe (§15 decision data).
# Builds a tiny Rust leaf decoder (staticlib) behind a C ABI and links it into
# a C++ driver, to measure the actual integration cost of adding Rust to the
# tree. This is the empirical input to the Rust-vs-C++ decision; it is not a
# product spike.

# Find cargo. The probe only builds if Rust is available; the ADR records the
# decision either way, so a missing Rust toolchain doesn't block the decision.
find_program(CARGO_EXECUTABLE NAMES cargo)

if(CARGO_EXECUTABLE)
    set(_rust_dir ${CMAKE_CURRENT_SOURCE_DIR}/F_rust_ffi_probe/rust)
    set(_rust_lib ${_rust_dir}/target/release/libfpe_rust_leaf.a)

    # Build the Rust staticlib with cargo. The staticlib is the link shape that
    # avoids a runtime .so dependency — the standard Rust-into-C++ integration.
    add_custom_command(
        OUTPUT ${_rust_lib}
        COMMAND ${CARGO_EXECUTABLE} build --release --manifest-path ${_rust_dir}/Cargo.toml
        DEPENDS ${_rust_dir}/Cargo.toml ${_rust_dir}/src/lib.rs
        COMMENT "Building Rust leaf decoder (staticlib) for FFI probe"
        VERBATIM)

    add_executable(spike_f_rust_ffi
        common/SpikeRunner.cpp
        common/SpikeRunner.h
        F_rust_ffi_probe/cpp_driver.cpp
    )
    target_include_directories(spike_f_rust_ffi PRIVATE ${CMAKE_CURRENT_SOURCE_DIR})
    target_compile_features(spike_f_rust_ffi PRIVATE cxx_std_20)
    freepdfeditor_apply_warnings(spike_f_rust_ffi)
    freepdfeditor_apply_hardening(spike_f_rust_ffi)

    # Link the Rust staticlib by absolute path (a .a is an archive, not a
    # -l flag). Mark it as a dependency of the custom command output so the
    # Rust build runs before the link.
    add_dependencies(spike_f_rust_ffi fpe_rust_leaf_staticlib)
    target_link_libraries(spike_f_rust_ffi PRIVATE
        ${_rust_lib} pthread dl)
    target_link_options(spike_f_rust_ffi PRIVATE -static-libgcc)

    # Make the staticlib a real CMake target with a custom command so the
    # build graph knows it is produced, not pre-existing.
    add_custom_target(fpe_rust_leaf_staticlib DEPENDS ${_rust_lib})

    # Skip the rust spike from the default 'all' target if Rust isn't wanted in
    # a given build (e.g. a CI image without cargo) — it's gated on CARGO_EXECUTABLE.
else()
    message(STATUS "cargo not found — Spike F (Rust FFI probe) skipped; "
        "ADR-0005 will record the decision without the empirical build data.")
endif()