cmake_minimum_required(VERSION 3.20)
project(RageTextureContract LANGUAGES C)
enable_testing()
set(CMAKE_C_STANDARD 17)
set(CMAKE_C_STANDARD_REQUIRED ON)
set(CMAKE_C_EXTENSIONS OFF)
option(RAGE_ASSET_SANITIZERS "Instrument standalone asset contracts with ASan and UBSan" OFF)
if(RAGE_ASSET_SANITIZERS)
    if(MSVC OR NOT CMAKE_C_COMPILER_ID MATCHES "GNU|Clang")
        message(FATAL_ERROR "This sanitizer gate requires Unix GCC or Clang")
    endif()
    add_compile_options(-fsanitize=address,undefined -fno-omit-frame-pointer)
    add_link_options(-fsanitize=address,undefined)
endif()
get_filename_component(RAGE_SOURCE "${CMAKE_CURRENT_LIST_DIR}/../.." ABSOLUTE)
add_executable(texture_span_tests "${RAGE_SOURCE}/tests/render/texture_span_tests.c")
target_include_directories(texture_span_tests PRIVATE
    "${RAGE_SOURCE}/external/psyz/psyz/src/platform")
if(MSVC)
    target_compile_options(texture_span_tests PRIVATE /W4 /WX)
else()
    target_compile_options(texture_span_tests PRIVATE -Wall -Wextra -Werror)
    target_link_libraries(texture_span_tests PRIVATE m)
endif()
add_test(NAME texture_span COMMAND texture_span_tests)
set(MINIZ_SOURCE "${RAGE_SOURCE}/external/libchdr/deps/miniz-3.1.2")
add_library(miniz STATIC "${MINIZ_SOURCE}/miniz.c")
add_library(json STATIC "${RAGE_SOURCE}/external/yyjson/yyjson.c")
target_include_directories(json PUBLIC "${RAGE_SOURCE}/external/yyjson")
target_include_directories(miniz PUBLIC "${MINIZ_SOURCE}")
target_compile_definitions(miniz PUBLIC MINIZ_NO_ARCHIVE_APIS MINIZ_NO_DEFLATE_APIS MINIZ_NO_STDIO MINIZ_NO_TIME)
add_executable(texture_patch_tests
    "${RAGE_SOURCE}/tests/disc/texture_patch_tests.c"
    "${RAGE_SOURCE}/src/port/texture_patch.c")
target_include_directories(texture_patch_tests PRIVATE "${RAGE_SOURCE}/src/port")
target_link_libraries(texture_patch_tests PRIVATE miniz json)
if(MSVC)
    target_compile_options(texture_patch_tests PRIVATE /W4 /WX /UNDEBUG)
    target_compile_definitions(texture_patch_tests PRIVATE _CRT_SECURE_NO_WARNINGS)
else()
    target_compile_options(texture_patch_tests PRIVATE -Wall -Wextra -Werror -UNDEBUG)
endif()
add_test(NAME texture_patch COMMAND texture_patch_tests)
add_library(material_contract STATIC
    "${RAGE_SOURCE}/src/render/render_material.c"
    "${RAGE_SOURCE}/src/render/asset_path.c"
    "${RAGE_SOURCE}/src/render/authored_car_surface.c")
target_include_directories(material_contract PUBLIC "${RAGE_SOURCE}/src")
add_executable(render_material_tests "${RAGE_SOURCE}/tests/render/render_material_tests.c")
add_executable(material_transaction_tests "${RAGE_SOURCE}/tests/disc/material_transaction_tests.c")
add_executable(modern_upload_queue_tests "${RAGE_SOURCE}/tests/disc/modern_upload_queue_tests.c")
foreach(target render_material_tests material_transaction_tests modern_upload_queue_tests)
    target_link_libraries(${target} PRIVATE material_contract)
    if(MSVC)
        target_compile_definitions(${target} PRIVATE _CRT_SECURE_NO_WARNINGS)
        target_compile_options(${target} PRIVATE /W4 /WX /UNDEBUG)
    else()
        target_compile_options(${target} PRIVATE -Wall -Wextra -Werror -UNDEBUG)
    endif()
    add_test(NAME ${target} COMMAND ${target})
endforeach()
option(RAGE_TEXTURE_ARCHIVE_TESTS "Also exercise extract/pack processes (requires SDL3)" OFF)
if(RAGE_TEXTURE_ARCHIVE_TESTS)
    find_package(SDL3 CONFIG REQUIRED)
    add_executable(mod_inventory_tests "${RAGE_SOURCE}/tests/disc/mod_inventory_tests.c"
        "${RAGE_SOURCE}/src/render/mod_file_policy.c" "${RAGE_SOURCE}/src/render/asset_path.c")
    target_include_directories(mod_inventory_tests PRIVATE "${RAGE_SOURCE}" "${RAGE_SOURCE}/src")
    target_link_libraries(mod_inventory_tests PRIVATE SDL3::SDL3)
    if(MSVC)
        target_compile_definitions(mod_inventory_tests PRIVATE _CRT_SECURE_NO_WARNINGS)
        target_compile_options(mod_inventory_tests PRIVATE /W4 /WX /UNDEBUG)
    else()
        target_compile_options(mod_inventory_tests PRIVATE -Wall -Wextra -Werror -UNDEBUG)
    endif()
    add_test(NAME mod_inventory COMMAND mod_inventory_tests)
    add_executable(rage-extract "${RAGE_SOURCE}/tools/rage_extract.c")
    add_executable(rage-pack "${RAGE_SOURCE}/tools/rage_pack.c" "${RAGE_SOURCE}/src/port/texture_patch.c")
    target_include_directories(rage-pack PRIVATE "${RAGE_SOURCE}/src/port")
    target_link_libraries(rage-pack PRIVATE miniz json)
    add_executable(mod_archive_tests "${RAGE_SOURCE}/tests/disc/mod_archive_tests.c")
    target_link_libraries(mod_archive_tests PRIVATE SDL3::SDL3)
    add_dependencies(mod_archive_tests rage-extract rage-pack)
    if(MSVC)
        foreach(target rage-extract rage-pack mod_archive_tests)
            target_compile_definitions(${target} PRIVATE _CRT_SECURE_NO_WARNINGS)
        endforeach()
        target_compile_options(mod_archive_tests PRIVATE /W4 /WX /UNDEBUG)
    else()
        target_compile_options(mod_archive_tests PRIVATE -Wall -Wextra -Werror -UNDEBUG)
    endif()
    add_test(NAME mod_archive COMMAND mod_archive_tests $<TARGET_FILE:rage-extract> $<TARGET_FILE:rage-pack>)
    set_tests_properties(mod_archive PROPERTIES TIMEOUT 180)
endif()
