cmake_minimum_required(VERSION 3.20)
if(CMAKE_SOURCE_DIR STREQUAL CMAKE_CURRENT_SOURCE_DIR)
    project(HazeLauncher LANGUAGES CXX RC)
endif()
if(NOT WIN32)
    message(FATAL_ERROR "HazeLauncher currently supports Windows only")
endif()
enable_language(RC)
add_library(HazeLaunch STATIC launch_config.cpp launch_win32.cpp diagnostics.cpp)
target_compile_features(HazeLaunch PUBLIC cxx_std_20)
target_include_directories(HazeLaunch PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}")
target_link_libraries(HazeLaunch PUBLIC advapi32 bcrypt dxgi)
if(MSVC)
    target_compile_options(HazeLaunch PRIVATE /EHsc /W4)
endif()
add_executable(HazeLauncher WIN32 main.cpp launcher.rc)
target_link_libraries(HazeLauncher PRIVATE HazeLaunch comctl32 shell32 ole32)
target_include_directories(HazeLauncher PRIVATE "${CMAKE_CURRENT_SOURCE_DIR}")
if(MSVC)
    target_compile_options(HazeLauncher PRIVATE /EHsc /W4)
    target_link_options(HazeLauncher PRIVATE /MANIFEST:NO)
endif()
# Build defaults are deliberately not installed into packages. Their relative
# paths preserve the development tree's existing saves/settings/cache.
get_filename_component(HAZE_LAUNCH_ROOT "${CMAKE_CURRENT_SOURCE_DIR}/../.." ABSOLUTE)
# Diagnostics identify the source and SDK gitlink this launcher was configured from.
file(STRINGS "${HAZE_LAUNCH_ROOT}/VERSION" HAZE_LAUNCH_VERSION LIMIT_COUNT 1)
set(HAZE_LAUNCH_COMMIT unknown)
set(HAZE_LAUNCH_SDK unknown)
find_package(Git QUIET)
if(GIT_FOUND)
    execute_process(COMMAND "${GIT_EXECUTABLE}" rev-parse HEAD WORKING_DIRECTORY "${HAZE_LAUNCH_ROOT}"
        OUTPUT_VARIABLE commit OUTPUT_STRIP_TRAILING_WHITESPACE ERROR_QUIET RESULT_VARIABLE commit_result)
    execute_process(COMMAND "${GIT_EXECUTABLE}" rev-parse HEAD:external/ps3recomp WORKING_DIRECTORY "${HAZE_LAUNCH_ROOT}"
        OUTPUT_VARIABLE sdk OUTPUT_STRIP_TRAILING_WHITESPACE ERROR_QUIET RESULT_VARIABLE sdk_result)
    execute_process(COMMAND "${GIT_EXECUTABLE}" status --porcelain --untracked-files=no WORKING_DIRECTORY "${HAZE_LAUNCH_ROOT}"
        OUTPUT_VARIABLE dirty OUTPUT_STRIP_TRAILING_WHITESPACE ERROR_QUIET RESULT_VARIABLE dirty_result)
    if(commit_result EQUAL 0 AND commit MATCHES "^[0-9a-f]+$")
        set(HAZE_LAUNCH_COMMIT "${commit}")
        if(dirty_result EQUAL 0 AND NOT dirty STREQUAL "")
            string(APPEND HAZE_LAUNCH_COMMIT "-modified")
        endif()
    endif()
    if(sdk_result EQUAL 0 AND sdk MATCHES "^[0-9a-f]+$")
        set(HAZE_LAUNCH_SDK "${sdk}")
    endif()
endif()
set_property(SOURCE diagnostics.cpp APPEND PROPERTY COMPILE_DEFINITIONS
    "HAZE_LAUNCH_VERSION=\"${HAZE_LAUNCH_VERSION}\"" "HAZE_LAUNCH_COMMIT=\"${HAZE_LAUNCH_COMMIT}\"" "HAZE_LAUNCH_SDK=\"${HAZE_LAUNCH_SDK}\"")
if(NOT DEFINED HAZE_SHARED_ROOT)
    set(HAZE_SHARED_ROOT "${HAZE_LAUNCH_ROOT}")
endif()
include(../windows-icon.cmake)
haze_local_icon(HazeLauncher)
if(CMAKE_RUNTIME_OUTPUT_DIRECTORY)
    set(HAZE_LAUNCH_OUTPUT "${CMAKE_RUNTIME_OUTPUT_DIRECTORY}")
else()
    set(HAZE_LAUNCH_OUTPUT "${CMAKE_CURRENT_BINARY_DIR}")
endif()
file(RELATIVE_PATH HAZE_LAUNCH_ROOT_REL "${HAZE_LAUNCH_OUTPUT}" "${HAZE_LAUNCH_ROOT}")
file(RELATIVE_PATH HAZE_SHARED_ROOT_REL "${HAZE_LAUNCH_ROOT}" "${HAZE_SHARED_ROOT}")
file(GENERATE OUTPUT "$<TARGET_FILE_DIR:HazeLauncher>/launcher-defaults.ini" CONTENT
    "; Generated development defaults; launcher.ini overrides these.\n[Launcher]\nInstallRoot=${HAZE_LAUNCH_ROOT_REL}\nSharedRoot=${HAZE_SHARED_ROOT_REL}\n")
install(TARGETS HazeLauncher RUNTIME DESTINATION bin)
install(FILES ../../config/launcher.example.ini DESTINATION bin)

option(HAZE_LAUNCHER_TESTS "Build launcher model and process tests" OFF)
if(HAZE_LAUNCHER_TESTS)
    enable_testing()
    add_library(HazeLaunchFixtureRuntime SHARED ../../tests/launcher_runtime.cpp)
    add_executable(HazeLaunchFixture ../../tests/launcher_child.cpp)
    target_link_libraries(HazeLaunchFixture PRIVATE HazeLaunchFixtureRuntime)
    target_compile_features(HazeLaunchFixture PRIVATE cxx_std_20)
    add_executable(HazeLaunchTests ../../tests/test_launcher.cpp)
    target_link_libraries(HazeLaunchTests PRIVATE HazeLaunch shell32)
    if(MSVC)
        target_compile_options(HazeLaunchTests PRIVATE /UNDEBUG /EHsc)
    endif()
    add_test(NAME launcher COMMAND HazeLaunchTests "$<TARGET_FILE:HazeLaunchFixture>" "$<TARGET_FILE:HazeLauncher>" "${CMAKE_CURRENT_BINARY_DIR}/test-data")
    set_tests_properties(launcher PROPERTIES TIMEOUT 60)
    add_executable(HazeLaunchDiagnosticsTests ../../tests/test_launcher_diagnostics.cpp)
    target_link_libraries(HazeLaunchDiagnosticsTests PRIVATE HazeLaunch)
    if(MSVC)
        target_compile_options(HazeLaunchDiagnosticsTests PRIVATE /UNDEBUG /EHsc)
    endif()
    add_test(NAME launcher-diagnostics COMMAND HazeLaunchDiagnosticsTests "${CMAKE_CURRENT_BINARY_DIR}/test-data")
    set_tests_properties(launcher-diagnostics PROPERTIES TIMEOUT 120)
endif()
