cmake_minimum_required(VERSION 3.24)
project(mag_render_sdk_compute LANGUAGES C CXX)
set(MAG_RENDER_NATIVE_BACKEND "metal" CACHE STRING "Explicit synthetic hardware backend: metal or vulkan")
set_property(CACHE MAG_RENDER_NATIVE_BACKEND PROPERTY STRINGS metal vulkan)
set(MAG_RENDER_SDK_SOURCE "" CACHE PATH "Explicit source-bound SDK override; no default discovery")
set(MAG_RENDER_SHADER_FIXTURE "" CACHE FILEPATH "Generated source-bound SPIR-V fixture header for Vulkan")
if(NOT EXISTS "${MAG_RENDER_SDK_SOURCE}/libs/video/rsx_frontend.h")
    message(FATAL_ERROR "Provide an explicit MAG_RENDER_SDK_SOURCE with the reviewed frontend API")
endif()
get_filename_component(PUBLIC_ROOT "${CMAKE_CURRENT_SOURCE_DIR}/../.." ABSOLUTE)
find_program(CARGO cargo REQUIRED)
set(CRATE "${PUBLIC_ROOT}/crates/mag-render")
set(RUST_ARCHIVE "${CMAKE_CURRENT_BINARY_DIR}/cargo/release/libmag_render.a")
file(GLOB_RECURSE RUST_SOURCES CONFIGURE_DEPENDS "${CRATE}/src/*.rs")
add_custom_command(OUTPUT "${RUST_ARCHIVE}"
    COMMAND "${CMAKE_COMMAND}" -E env --unset=MAKEFLAGS --unset=MFLAGS --unset=CARGO_MAKEFLAGS RUSTUP_TOOLCHAIN=1.99.0 "CARGO_TARGET_DIR=${CMAKE_CURRENT_BINARY_DIR}/cargo"
        "${CARGO}" build --manifest-path "${CRATE}/Cargo.toml" --lib --release --locked --offline --features sdk-compute
    WORKING_DIRECTORY "${PUBLIC_ROOT}" DEPENDS ${RUST_SOURCES} "${CRATE}/Cargo.toml" "${CRATE}/Cargo.lock" VERBATIM)
add_custom_target(rust_sdk_compute DEPENDS "${RUST_ARCHIVE}")
set(SDK "${MAG_RENDER_SDK_SOURCE}")
if(MAG_RENDER_NATIVE_BACKEND STREQUAL "metal")
    if(NOT APPLE)
        message(FATAL_ERROR "The Metal fixture requires macOS")
    endif()
    enable_language(OBJC)
    enable_language(OBJCXX)
    add_executable(sdk_compute_fixture sdk_compute_main.mm sdk_compute_owner.m "${PUBLIC_ROOT}/src/mag_render_backend_bridge.cpp"
        "${SDK}/libs/video/rsx_frontend.c" "${SDK}/libs/video/rsx_frontend_metal.m"
        "${SDK}/libs/video/rsx_texture_layout.c" "${SDK}/runtime/diagnostics/critical_trace.c"
        "${SDK}/runtime/diagnostics/render_ablation.c" "${SDK}/libs/input/pad_macos.m")
    target_compile_options(sdk_compute_fixture PRIVATE "$<$<COMPILE_LANGUAGE:OBJC,OBJCXX>:-fobjc-arc>")
    target_compile_definitions(sdk_compute_fixture PRIVATE PS3RECOMP_DISABLE_NATIVE_OSK)
    target_link_options(sdk_compute_fixture PRIVATE -Wl,-dead_strip)
    target_link_libraries(sdk_compute_fixture PRIVATE "-framework Metal" "-framework Cocoa" "-framework QuartzCore" "-framework Security" "-framework SystemConfiguration" iconv resolv)
elseif(MAG_RENDER_NATIVE_BACKEND STREQUAL "vulkan")
    if(NOT CMAKE_SYSTEM_NAME STREQUAL "Linux")
        message(FATAL_ERROR "The headless Vulkan fixture currently requires Linux")
    endif()
    if(NOT EXISTS "${MAG_RENDER_SHADER_FIXTURE}")
        message(FATAL_ERROR "Provide a freshly generated MAG_RENDER_SHADER_FIXTURE header")
    endif()
    find_package(PkgConfig REQUIRED)
    pkg_check_modules(SDL2 REQUIRED IMPORTED_TARGET sdl2)
    pkg_check_modules(VULKAN_HEADERS REQUIRED vulkan)
    find_package(Threads REQUIRED)
    get_filename_component(SHADER_INCLUDE "${MAG_RENDER_SHADER_FIXTURE}" DIRECTORY)
    add_executable(sdk_compute_fixture sdk_compute_main_vulkan.cpp sdk_compute_owner_vulkan.c
        "${PUBLIC_ROOT}/src/mag_render_backend_bridge.cpp" "${MAG_RENDER_SHADER_FIXTURE}"
        "${SDK}/libs/video/rsx_frontend.c" "${SDK}/libs/video/rsx_frontend_vulkan.c")
    target_include_directories(sdk_compute_fixture PRIVATE "${SHADER_INCLUDE}" ${VULKAN_HEADERS_INCLUDE_DIRS})
    target_compile_options(sdk_compute_fixture PRIVATE -ffunction-sections -fdata-sections ${VULKAN_HEADERS_CFLAGS_OTHER})
    target_link_options(sdk_compute_fixture PRIVATE -Wl,--gc-sections)
    # The existing SDK dynamically loads Vulkan; link headers/SDL only.
    target_link_libraries(sdk_compute_fixture PRIVATE PkgConfig::SDL2 Threads::Threads ${CMAKE_DL_LIBS} m rt util)
else()
    message(FATAL_ERROR "Unknown explicit hardware backend")
endif()
add_dependencies(sdk_compute_fixture rust_sdk_compute)
target_compile_features(sdk_compute_fixture PRIVATE c_std_17 cxx_std_17)
target_compile_options(sdk_compute_fixture PRIVATE -O1 -g -UNDEBUG)
target_include_directories(sdk_compute_fixture PRIVATE "${SDK}/include" "${SDK}/libs/video" "${PUBLIC_ROOT}/src")
target_link_libraries(sdk_compute_fixture PRIVATE "${RUST_ARCHIVE}")
