# Автотесты BiLauncher. Включаются опцией BILAUNCHER_BUILD_TESTS (корневой CMakeLists.txt).
#
# Код лаунчера не меняется ради тестов. Те же исходники собираются ещё раз в
# статическую библиотеку-QML-модуль bilauncher_testlib (URI BiLauncher): её
# линкуют все тесты — и C++-тесты сервисов, и Qt Quick Test для QML.
# Подробности — doc/testing.md.

find_package(Qt6 REQUIRED COMPONENTS Test QuickTest Network Qml Quick QuickControls2)

set(CMAKE_AUTOMOC ON)

# --- Исходники лаунчера -----------------------------------------------------------
# Все .cpp/.h из корня, кроме main.cpp: новый файл попадёт в тесты сам.
file(GLOB LAUNCHER_TEST_CPP CONFIGURE_DEPENDS "${PROJECT_SOURCE_DIR}/*.cpp" "${PROJECT_SOURCE_DIR}/*.h")
list(FILTER LAUNCHER_TEST_CPP EXCLUDE REGEX "/main\\.cpp$")

# QML-файлы модуля. MicrosoftLoginDialog.qml нужен только со сборкой WebEngine;
# тестовая библиотека собирается без него (как сборка без Qt WebEngine), так что
# backend.microsoftAvailable в тестах всегда false.
file(GLOB LAUNCHER_TEST_QML RELATIVE "${PROJECT_SOURCE_DIR}" CONFIGURE_DEPENDS "${PROJECT_SOURCE_DIR}/*.qml")
list(REMOVE_ITEM LAUNCHER_TEST_QML MicrosoftLoginDialog.qml)

# Ресурсы модуля берём прямо из корневого CMakeLists.txt (строки «RESOURCES …»),
# чтобы список не пришлось вести в двух местах.
file(READ "${PROJECT_SOURCE_DIR}/CMakeLists.txt" _root_cmake)
string(REGEX MATCHALL "\n[ \t]*RESOURCES[^\n]*" _resource_lines "${_root_cmake}")
set(LAUNCHER_TEST_RESOURCES "")
foreach(_line IN LISTS _resource_lines)
    string(REGEX REPLACE "^[ \t\n]*RESOURCES[ \t]+" "" _line "${_line}")
    string(REGEX REPLACE "[ \t]+" ";" _files "${_line}")
    list(APPEND LAUNCHER_TEST_RESOURCES ${_files})
endforeach()
list(REMOVE_ITEM LAUNCHER_TEST_RESOURCES "")

# Файлы QML-модуля лежат в корне проекта, а не в tests/: для qt_add_qml_module
# им нужны пути относительно текущего каталога, поэтому копируем их в дерево сборки.
set(_module_dir "${CMAKE_CURRENT_BINARY_DIR}/module_src")
set(_module_qml "")
foreach(_file IN LISTS LAUNCHER_TEST_QML LAUNCHER_TEST_RESOURCES)
    configure_file("${PROJECT_SOURCE_DIR}/${_file}" "${_module_dir}/${_file}" COPYONLY)
endforeach()
foreach(_file IN LISTS LAUNCHER_TEST_QML)
    list(APPEND _module_qml "${_module_dir}/${_file}")
    set_source_files_properties("${_module_dir}/${_file}" PROPERTIES QT_RESOURCE_ALIAS "${_file}")
endforeach()
set(_module_res "")
foreach(_file IN LISTS LAUNCHER_TEST_RESOURCES)
    list(APPEND _module_res "${_module_dir}/${_file}")
    set_source_files_properties("${_module_dir}/${_file}" PROPERTIES QT_RESOURCE_ALIAS "${_file}")
endforeach()

qt_add_library(bilauncher_testlib STATIC)
qt_add_qml_module(bilauncher_testlib
    URI BiLauncher
    OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/qml/BiLauncher"
    SOURCES ${LAUNCHER_TEST_CPP}
    QML_FILES ${_module_qml}
    RESOURCES ${_module_res}
    NO_LINT
)
target_include_directories(bilauncher_testlib PUBLIC "${PROJECT_SOURCE_DIR}" "${LAUNCHER_GENERATED_DIR}")
add_dependencies(bilauncher_testlib launcher_version)
target_link_libraries(bilauncher_testlib PUBLIC
    Qt6::Quick Qt6::QuickControls2 Qt6::Qml Qt6::Svg Qt6::Core Qt6::CorePrivate Qt6::Gui Qt6::Network
)

# --- Подставная java --------------------------------------------------------------
add_executable(fake_java fake_java/main.cpp)
set_target_properties(fake_java PROPERTIES CXX_STANDARD 17 CXX_STANDARD_REQUIRED ON
    AUTOMOC OFF MACOSX_BUNDLE FALSE WIN32_EXECUTABLE FALSE)

# --- Общая обвязка тестов --------------------------------------------------------
add_library(bilauncher_testsupport STATIC
    common/testenv.h common/testenv.cpp
    common/fixtures.h common/fixtures.cpp
    common/fakeinternet.h common/fakeinternet.cpp
    common/fakemojang.h common/fakemojang.cpp
    common/nettest.h
)
# Designated initializers (VersionSpec{.id = ...}) — C++20.
target_compile_features(bilauncher_testsupport PUBLIC cxx_std_20)
target_include_directories(bilauncher_testsupport PUBLIC common)
target_compile_definitions(bilauncher_testsupport PUBLIC
    BILAUNCHER_FIXTURES_DIR="${CMAKE_CURRENT_SOURCE_DIR}/fixtures"
    BILAUNCHER_SOURCE_DIR="${PROJECT_SOURCE_DIR}"
    BILAUNCHER_FAKE_JAVA="$<TARGET_FILE:fake_java>"
)
target_link_libraries(bilauncher_testsupport PUBLIC bilauncher_testlib Qt6::Test Qt6::Network Qt6::CorePrivate)
add_dependencies(bilauncher_testsupport fake_java)

# Окружение всех тестов: без окон, без GPU, без кеша QML на диске.
set(BILAUNCHER_TEST_ENV
    "QT_QPA_PLATFORM=offscreen"
    "QT_QUICK_BACKEND=software"
    "QML_DISABLE_DISK_CACHE=1"
    "QT_LOGGING_RULES=qt.network.ssl.warning=false"
)

# bilauncher_add_test(<имя> LABEL <метка> SOURCES ... [TIMEOUT сек] [GUI])
function(bilauncher_add_test name)
    cmake_parse_arguments(ARG "GUI" "LABEL;TIMEOUT" "SOURCES" ${ARGN})
    add_executable(${name} ${ARG_SOURCES})
    set_target_properties(${name} PROPERTIES MACOSX_BUNDLE FALSE WIN32_EXECUTABLE FALSE)
    target_link_libraries(${name} PRIVATE bilauncher_testsupport)
    if(ARG_GUI)
        target_link_libraries(${name} PRIVATE bilauncher_testlibplugin Qt6::QuickTest)
    endif()
    add_test(NAME ${name} COMMAND ${name})
    if(NOT ARG_TIMEOUT)
        set(ARG_TIMEOUT 120)
    endif()
    set_tests_properties(${name} PROPERTIES
        LABELS "${ARG_LABEL}"
        TIMEOUT ${ARG_TIMEOUT}
        ENVIRONMENT "${BILAUNCHER_TEST_ENV}")
    if(WIN32)
        # DLL Qt — из установки Qt, без windeployqt для каждого теста.
        set_property(TEST ${name} APPEND PROPERTY ENVIRONMENT_MODIFICATION
            "PATH=path_list_prepend:$<TARGET_FILE_DIR:Qt6::Core>")
    endif()
endfunction()

add_subdirectory(unit)
add_subdirectory(net)
add_subdirectory(backend)
add_subdirectory(qml)
