# Add individual tests as executables in separate directories at the bottom of this file

add_subdirectory(catch2)

# The top-level project defines _UNICODE globally, which makes Catch2's bundled
# main emit wmain instead of main. Test executables link with the default
# /SUBSYSTEM:CONSOLE entry point (mainCRTStartup, which calls main), so force
# Catch2 to emit main to keep the CRT entry point happy.
if(MSVC)
    target_compile_definitions(Catch2WithMain PRIVATE DO_NOT_USE_WMAIN)
endif()

set(TEST_DATA_DIR ${CMAKE_CURRENT_SOURCE_DIR}/data)
file(TO_NATIVE_PATH "${TEST_DATA_DIR}" TEST_DATA_DIR)

# Shipped vendor profiles, so tests can exercise the real machine/filament gcode.
set(PROFILES_DIR ${CMAKE_SOURCE_DIR}/resources/profiles)
file(TO_NATIVE_PATH "${PROFILES_DIR}" PROFILES_DIR)

include(CTest)
include(Catch)

set(CATCH_EXTRA_ARGS "" CACHE STRING "Extra arguments for catch2 test suites.") # Unknown if this still works and/or should be replaced with something else.

add_library(test_common INTERFACE)
target_compile_definitions(test_common INTERFACE TEST_DATA_DIR=R"\(${TEST_DATA_DIR}\)" PROFILES_DIR=R"\(${PROFILES_DIR}\)" CATCH_CONFIG_FAST_COMPILE)
target_include_directories(test_common INTERFACE ${CMAKE_CURRENT_SOURCE_DIR})

if (APPLE)
    target_link_libraries(test_common INTERFACE "-liconv -framework IOKit" "-framework CoreFoundation" -lc++)
endif()

# Copies runtime shared libraries next to each test executable. Handles both
# single-config generators (CMAKE_BUILD_TYPE set) and multi-config generators
# (Ninja Multi-Config, Visual Studio) where CMAKE_BUILD_TYPE is empty and DLLs
# must land in every per-config output directory. On Windows the loader finds
# DLLs in the executable's directory; the Linux branch below does the same for
# the deps-built FFmpeg libraries and adds an $ORIGIN rpath, since the ELF
# loader does not search the executable's directory and the CI unit-test runner
# only receives the tests artifact (no deps install).
function(orcaslicer_copy_test_dlls)
    if (WIN32)
        set(_configs ${CMAKE_CONFIGURATION_TYPES})
        if (NOT _configs)
            set(_configs "${CMAKE_BUILD_TYPE}")
        endif()
        foreach(_cfg IN LISTS _configs)
            if (_cfg STREQUAL "Debug")
                orcaslicer_copy_dlls(COPY_DLLS "Debug" "d" _unused_dlls)
            else()
                orcaslicer_copy_dlls(COPY_DLLS "${_cfg}" "" _unused_dlls)
            endif()
        endforeach()
    elseif (UNIX AND NOT APPLE)
        # Only test executables that link libslic3r_gui pull in the FFmpeg
        # shared libraries (src/slic3r/CMakeLists.txt links PkgConfig::LIBAV
        # into it). Copy them next to the executable and give it an $ORIGIN
        # rpath so the loader finds them when the tests run on the CI unit-test
        # runner, which only receives this build/tests tree.
        #
        # Optional first arg: the target to patch, for directories that define
        # more than one test executable. Defaults to ${_TEST_NAME}_tests so
        # existing single-executable callers don't need to pass it.
        if (ARGC GREATER 0)
            set(_target ${ARGV0})
        else()
            set(_target ${_TEST_NAME}_tests)
        endif()

        get_target_property(_linked_libs ${_target} LINK_LIBRARIES)
        if (NOT "libslic3r_gui" IN_LIST _linked_libs)
            return()
        endif()

        set_property(TARGET ${_target} PROPERTY BUILD_RPATH "$ORIGIN")
        set(_configs ${CMAKE_CONFIGURATION_TYPES})
        if (NOT _configs)
            set(_configs "${CMAKE_BUILD_TYPE}")
        endif()
        foreach(_cfg IN LISTS _configs)
            orcaslicer_copy_sos(${_target} "${_cfg}" "" _unused_sos)
        endforeach()
    endif()
endfunction()

# Register Catch2 tags as CTest labels so `ctest -L`/`-LE` can filter by tag.
function(orcaslicer_discover_tests TARGET)
    catch_discover_tests(${TARGET} ADD_TAGS_AS_LABELS)
endfunction()

add_subdirectory(libnest2d)
add_subdirectory(libslic3r)
add_subdirectory(slic3rutils)
add_subdirectory(fff_print)
add_subdirectory(sla_print)
add_subdirectory(filament_group)

# End-to-end checks of the orca-slicer binary. Linux only: they read result.json, which the CLI
# writes on Linux only. src/ is added before tests/, so the target is known here.
if (UNIX AND NOT APPLE AND TARGET OrcaSlicer)
    add_subdirectory(cli)
endif ()

