cmake_minimum_required(VERSION 3.20)

project(SimCAEUpdateClient LANGUAGES C CXX)

set(UPDATE_CLIENT_SOURCE_DIR "${CMAKE_CURRENT_SOURCE_DIR}")
set(UPDATE_CLIENT_IS_STANDALONE OFF)
if(CMAKE_SOURCE_DIR STREQUAL CMAKE_CURRENT_SOURCE_DIR)
    set(UPDATE_CLIENT_IS_STANDALONE ON)
endif()

set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_CXX_EXTENSIONS OFF)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(CMAKE_AUTOMOC ON)
set(CMAKE_AUTOUIC ON)
set(CMAKE_AUTORCC ON)

if(MSVC)
    add_compile_options(/utf-8)
endif()

cmake_path(
    ABSOLUTE_PATH UPDATE_CLIENT_SOURCE_DIR
    BASE_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/.."
    NORMALIZE
    OUTPUT_VARIABLE _update_client_source_root
)
cmake_path(GET _update_client_source_root PARENT_PATH _update_client_parent_root)
set(
    UPDATE_CLIENT_THIRDPARTY_ROOT
    "${_update_client_parent_root}/3rdparty"
    CACHE PATH
    "Root directory for update-client third-party packages"
)
option(
    UPDATE_CLIENT_STRICT_THIRDPARTY
    "Require OpenSSL imported library and include paths to stay under the third-party root"
    ON
)
set(
    UPDATE_CLIENT_PRODUCT_CONFIG_FILE
    ""
    CACHE FILEPATH
    "Exact product config to embed; empty selects config/config.json then the example"
)
set(
    UPDATE_CLIENT_LAUNCH_TOKEN
    ""
    CACHE STRING
    "Optional build-provided launch ticket token override"
)
mark_as_advanced(UPDATE_CLIENT_LAUNCH_TOKEN)
set(UPDATE_CLIENT_MAIN_EXECUTABLE "" CACHE STRING "Override main_executable in embedded config")
set(UPDATE_CLIENT_LAUNCHER_EXECUTABLE "" CACHE STRING "Override launcher_executable in embedded config")
set(UPDATE_CLIENT_UPDATER_EXECUTABLE "" CACHE STRING "Override updater_executable in embedded config")
set(UPDATE_CLIENT_BOOTSTRAP_EXECUTABLE "" CACHE STRING "Override bootstrap_executable in embedded config")
set(UPDATE_CLIENT_PLATFORM "" CACHE STRING "Override platform in embedded config")
set(UPDATE_CLIENT_ARCH "" CACHE STRING "Override arch in embedded config")

if(WIN32)
    set(_update_client_deploy_qt_default ON)
else()
    set(_update_client_deploy_qt_default OFF)
endif()
option(
    UPDATE_CLIENT_DEPLOY_QT_RUNTIME
    "Run the Qt deployment tool after building each Qt executable"
    ${_update_client_deploy_qt_default}
)
option(
    UPDATE_CLIENT_REQUIRE_TRANSLATIONS
    "Fail configuration when translations/update-client_zh_CN.ts is absent"
    OFF
)
option(
    UPDATE_CLIENT_INSTALL_RUNTIME_ASSETS
    "Install update-client runtime assets from this project"
    ${UPDATE_CLIENT_IS_STANDALONE}
)
option(
    UPDATE_CLIENT_BUILD_DEMO_APP
    "Build the standalone MainApp integration demo"
    ${UPDATE_CLIENT_IS_STANDALONE}
)

list(PREPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake")
include(UpdateClientDependencies)
include(UpdateClientResources)

update_client_find_dependencies()
update_client_select_product_config(_update_client_product_config_source)
update_client_generate_normalized_product_config(
    _update_client_product_config
    "${_update_client_product_config_source}"
)
update_client_create_embedded_resources(
    UpdateClientEmbeddedResources
    "${_update_client_product_config}"
)

add_custom_target(UpdateClientNoHanCheck ALL
    COMMAND "${CMAKE_COMMAND}"
        "-DUPDATE_CLIENT_SCAN_ROOT=${CMAKE_CURRENT_SOURCE_DIR}"
        -P "${CMAKE_CURRENT_SOURCE_DIR}/cmake/CheckNoHan.cmake"
    COMMENT "Checking update-client production sources for Han characters"
    VERBATIM
)
add_dependencies(UpdateClientEmbeddedResources UpdateClientNoHanCheck)

if(UPDATE_CLIENT_IS_STANDALONE)
    if(NOT CMAKE_ARCHIVE_OUTPUT_DIRECTORY)
        set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/out/lib")
    endif()
    if(NOT CMAKE_LIBRARY_OUTPUT_DIRECTORY)
        set(CMAKE_LIBRARY_OUTPUT_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/out/bin")
    endif()
    if(NOT CMAKE_RUNTIME_OUTPUT_DIRECTORY)
        set(CMAKE_RUNTIME_OUTPUT_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/out/bin")
    endif()
endif()

add_subdirectory(Bootstrap)
add_subdirectory(Common)

add_library(UpdateClientUpdaterLogic STATIC
    Updater/UpdaterLogic.h
    Updater/UpdaterLogic.cpp
)
target_compile_features(UpdateClientUpdaterLogic PUBLIC cxx_std_17)
target_include_directories(UpdateClientUpdaterLogic PUBLIC
    "${CMAKE_CURRENT_SOURCE_DIR}/Updater"
)
target_link_libraries(UpdateClientUpdaterLogic
    PUBLIC
        Common
        Qt5::Core
        Qt5::Network
        Qt5::Gui
        Qt5::Widgets
)

add_subdirectory(Launcher)
add_subdirectory(Updater)

set(_update_client_primary_targets
    Bootstrap
    Common
    UpdateClientUpdaterLogic
    Launcher
    Updater
)
if(UPDATE_CLIENT_BUILD_DEMO_APP)
    add_subdirectory(MainApp)
    list(APPEND _update_client_primary_targets MainApp)
endif()

foreach(_update_client_primary_target IN LISTS _update_client_primary_targets)
    add_dependencies("${_update_client_primary_target}" UpdateClientNoHanCheck)
endforeach()

set_property(DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}" PROPERTY VS_STARTUP_PROJECT Launcher)

if(UPDATE_CLIENT_INSTALL_RUNTIME_ASSETS)
    update_client_install_openssl_runtime(bin)
endif()
