add_library(libSceJobManager SHARED EXCLUDE_FROM_ALL Export.cpp)
target_include_directories(libSceJobManager PRIVATE ${LIBS_INCLUDE_DIR})
target_link_libraries(libSceJobManager PRIVATE libSceAgc libSceAgcDriver libSceRazorCpu ulobjmgr)
configure_windows_unwind(libSceJobManager)

if(BUILD_TESTING)
    add_test_executable(guest_job_manager_profiler_tests ${LIBS_INCLUDE_DIR}/tests/JobManagerProfiler.cpp Export.cpp)
    target_include_directories(guest_job_manager_profiler_tests PRIVATE ${LIBS_INCLUDE_DIR}
        ${ANYPS5_VULKAN_HEADERS_INCLUDE_DIR} ${ANYPS5_SPIRV_HEADERS_INCLUDE_DIR}
        $<TARGET_PROPERTY:shader_recompiler_agc_driver,INTERFACE_INCLUDE_DIRECTORIES>)
    target_compile_options(guest_job_manager_profiler_tests PRIVATE -msse4.2)
    target_link_libraries(guest_job_manager_profiler_tests PRIVATE libSceAgc libSceAgcDriver libkernel libc ulobjmgr)
    configure_windows_unwind(guest_job_manager_profiler_tests)
    add_test(NAME guest_job_manager_profiler COMMAND guest_job_manager_profiler_tests)
    add_test(NAME guest_job_manager_profiler_gpu COMMAND guest_job_manager_profiler_tests gpu)
    set_tests_properties(guest_job_manager_profiler guest_job_manager_profiler_gpu PROPERTIES TIMEOUT 20)
    set_tests_properties(guest_job_manager_profiler_gpu PROPERTIES SKIP_RETURN_CODE 77 ENVIRONMENT "ANYPS5_NO_SHADER_CACHE=1")
    if(WIN32)
        set_tests_properties(guest_job_manager_profiler guest_job_manager_profiler_gpu PROPERTIES ENVIRONMENT_MODIFICATION
            "PATH=path_list_prepend:$<TARGET_FILE_DIR:libSceAgc>")
    endif()
    add_test_executable(job_manager_compute_progress_tests ${LIBS_INCLUDE_DIR}/tests/JobManagerComputeProgress.cpp)
    target_include_directories(job_manager_compute_progress_tests PRIVATE ${LIBS_INCLUDE_DIR})
    target_link_libraries(job_manager_compute_progress_tests PRIVATE libc)
    configure_windows_unwind(job_manager_compute_progress_tests)
    add_test(NAME guest_job_manager_compute_progress COMMAND job_manager_compute_progress_tests)
    set_tests_properties(guest_job_manager_compute_progress PROPERTIES TIMEOUT 20)
    if(WIN32)
        set_tests_properties(guest_job_manager_compute_progress PROPERTIES ENVIRONMENT_MODIFICATION
            "PATH=path_list_prepend:$<TARGET_FILE_DIR:libc>")
    endif()
    add_test_executable(guest_job_manager_failure_tests ${LIBS_INCLUDE_DIR}/tests/JobManagerFailures.cpp Export.cpp)
    target_include_directories(guest_job_manager_failure_tests PRIVATE ${LIBS_INCLUDE_DIR})
    target_link_libraries(guest_job_manager_failure_tests PRIVATE libSceAgc libSceAgcDriver libSceRazorCpu libkernel libc ulobjmgr)
    configure_windows_unwind(guest_job_manager_failure_tests)
    add_test(NAME guest_job_manager_failures COMMAND guest_job_manager_failure_tests)
    set_tests_properties(guest_job_manager_failures PROPERTIES TIMEOUT 20)
    if(WIN32)
        set_tests_properties(guest_job_manager_failures PROPERTIES ENVIRONMENT_MODIFICATION
            "PATH=path_list_prepend:$<TARGET_FILE_DIR:libSceAgc>")
    endif()
    add_test_executable(guest_job_manager_registration_tests ${LIBS_INCLUDE_DIR}/tests/JobManagerRegistration.cpp Export.cpp)
    target_include_directories(guest_job_manager_registration_tests PRIVATE ${LIBS_INCLUDE_DIR})
    target_link_libraries(guest_job_manager_registration_tests PRIVATE libSceAgc libSceAgcDriver libSceRazorCpu libkernel libc)
    configure_windows_unwind(guest_job_manager_registration_tests)
    add_test(NAME guest_job_manager_registration COMMAND guest_job_manager_registration_tests)
    set_tests_properties(guest_job_manager_registration PROPERTIES TIMEOUT 20)
    if(WIN32)
        set_tests_properties(guest_job_manager_registration PROPERTIES ENVIRONMENT_MODIFICATION
            "PATH=path_list_prepend:$<TARGET_FILE_DIR:libSceAgc>")
    endif()
    add_test_executable(guest_job_manager_tests ${LIBS_INCLUDE_DIR}/tests/GuestJobManager.cpp)
    target_include_directories(guest_job_manager_tests PRIVATE ${LIBS_INCLUDE_DIR})
    target_link_libraries(guest_job_manager_tests PRIVATE libSceJobManager libSceAgc libSceAgcDriver libkernel libc)
    configure_windows_unwind(guest_job_manager_tests)
    if(WIN32 OR CMAKE_SYSTEM_NAME STREQUAL "Linux")
        add_library(job_manager_reference SHARED EXCLUDE_FROM_ALL
            ${LIBS_INCLUDE_DIR}/tests/GuestJobManager.cpp
            ${LIBS_INCLUDE_DIR}/tests/JobManagerReference.cpp)
        target_include_directories(job_manager_reference PRIVATE ${LIBS_INCLUDE_DIR})
        target_compile_definitions(job_manager_reference PRIVATE ANYPS5_JOB_MANAGER_REFERENCE)
        target_link_libraries(job_manager_reference PRIVATE libkernel libc ${CMAKE_DL_LIBS})
        set_target_properties(job_manager_reference PROPERTIES PREFIX "" SUFFIX .prx
            RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/tests
            LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/tests)
        configure_windows_unwind(job_manager_reference)
    endif()
    foreach(testCase IN ITEMS memory owned_state validation dispatch ordering nested limits node_pool priority shutdown worker_policy worker_wake worker_wait worker_count worker_spin shutdown_running shutdown_waiter shutdown_queued shutdown_destroy shutdown_partial shutdown_cross_wait concurrent_wait)
        add_test(NAME guest_job_manager_${testCase} COMMAND guest_job_manager_tests ${testCase})
        set_tests_properties(guest_job_manager_${testCase} PROPERTIES TIMEOUT 20)
        if(WIN32)
            set_tests_properties(guest_job_manager_${testCase} PROPERTIES ENVIRONMENT_MODIFICATION
                "PATH=path_list_prepend:$<TARGET_FILE_DIR:libSceJobManager>")
        endif()
    endforeach()
    set_tests_properties(guest_job_manager_worker_spin PROPERTIES ENVIRONMENT "APS5_TIME_SCALE=1")
    foreach(scale IN ITEMS 0.1 10)
        add_test(NAME guest_job_manager_worker_spin_scale_${scale} COMMAND guest_job_manager_tests worker_spin)
        set_tests_properties(guest_job_manager_worker_spin_scale_${scale} PROPERTIES TIMEOUT 20 ENVIRONMENT "APS5_TIME_SCALE=${scale}")
        if(WIN32)
            set_tests_properties(guest_job_manager_worker_spin_scale_${scale} PROPERTIES ENVIRONMENT_MODIFICATION
                "PATH=path_list_prepend:$<TARGET_FILE_DIR:libSceJobManager>")
        endif()
    endforeach()
endif()
