find_package(Qt6 6.4.2 COMPONENTS Concurrent Svg WebEngineWidgets Widgets REQUIRED)

# Define output binary name.
if(APPLE)
    set(_project_output_name ${CMAKE_PROJECT_NAME})
else()
    string(TOLOWER ${CMAKE_PROJECT_NAME} _project_output_name)
endif()

set(PROJECT_EXECUTABLE_NAME "${_project_output_name}${CMAKE_EXECUTABLE_SUFFIX}")
message(STATUS "Project executable name: ${PROJECT_EXECUTABLE_NAME}")

# Only support installing runtime dependencies with Qt >=6.5.1 (see QTBUG-111741).
if(Qt6Widgets_VERSION VERSION_GREATER_EQUAL "6.5.1")
    set(_use_qt_cmake_commands TRUE)

    qt_standard_project_setup()
endif()

if(APPLE)
    list(APPEND App_RESOURCES resources/zeal.icns)
elseif(WIN32)
    configure_file(versioninfo.rc.in ${CMAKE_CURRENT_BINARY_DIR}/versioninfo.rc)
    list(APPEND App_RESOURCES ${CMAKE_CURRENT_BINARY_DIR}/versioninfo.rc)
    list(APPEND App_RESOURCES zeal.manifest)
else()
    set(App_RESOURCES) # Silence CMake warning.
endif()

qt_add_executable(App WIN32
    main.cpp
    zeal.qrc
    ${App_RESOURCES}
)

target_link_libraries(App PRIVATE Core Ui Util Widgets Qt6::Svg Qt6::Widgets)

zeal_attach_qt_pch(App <QWidget>)

# Scoped here (not project-wide) so changes to the version string don't
# invalidate compiler caches for every TU on every commit.
target_compile_definitions(App PRIVATE ZEAL_VERSION="${ZEAL_VERSION_FULL}")

set_target_properties(App PROPERTIES
    OUTPUT_NAME ${_project_output_name}
    RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}
)

# Optionally deploy to the build directory after each build.
# Useful for local development on Windows when Qt is not in PATH.
option(ZEAL_DEPLOY_QT_ON_BUILD "Copy Qt runtime dependencies to build directory (Windows only)" OFF)

# Deploy Qt runtime dependencies on Windows.
if(WIN32 AND _use_qt_cmake_commands)
    qt_generate_deploy_script(
        TARGET App
        OUTPUT_SCRIPT _qt_deploy_script
        CONTENT "
qt_deploy_runtime_dependencies(
    EXECUTABLE \"$<TARGET_FILE:App>\"
    BIN_DIR .
    NO_TRANSLATIONS
    NO_COMPILER_RUNTIME
    DEPLOY_TOOL_OPTIONS --skip-plugin-types qmltooling,position,generic --no-quick-import
)")

    if(ZEAL_DEPLOY_QT_ON_BUILD)
        add_custom_command(TARGET App POST_BUILD
            COMMAND ${CMAKE_COMMAND} -P ${_qt_deploy_script}
            WORKING_DIRECTORY $<TARGET_FILE_DIR:App>
            COMMENT "Deploying Qt runtime dependencies..."
        )
    endif()
endif()

if(APPLE)
    set_target_properties(App PROPERTIES
        MACOSX_BUNDLE TRUE
        MACOSX_BUNDLE_BUNDLE_NAME ${CMAKE_PROJECT_NAME}
        MACOSX_BUNDLE_GUI_IDENTIFIER "org.zealdocs.zeal"
        MACOSX_BUNDLE_BUNDLE_VERSION ${PROJECT_VERSION}
        MACOSX_BUNDLE_LONG_VERSION_STRING ${PROJECT_VERSION}
        MACOSX_BUNDLE_SHORT_VERSION_STRING "${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR}"
        MACOSX_BUNDLE_ICON_FILE "zeal.icns"
        MACOSX_BUNDLE_COPYRIGHT ${PROJECT_COPYRIGHT}
        RESOURCE "resources/zeal.icns"
    )
elseif(WIN32)
    install(TARGETS App RUNTIME DESTINATION .)

    # Install the license alongside the binary.
    install(FILES "${CMAKE_SOURCE_DIR}/COPYING" DESTINATION .)

    # Many machines carry no system-wide MSVC runtime, or one older than the toolset. These
    # are not KnownDLLs, so app-local copies take precedence over System32 (issue #1658).
    set(CMAKE_INSTALL_SYSTEM_RUNTIME_DESTINATION .)
    include(InstallRequiredSystemLibraries)

    # File names vary by toolset, so let the packaging check assert on what was resolved.
    foreach(_lib ${CMAKE_INSTALL_SYSTEM_RUNTIME_LIBS})
        get_filename_component(_lib_name "${_lib}" NAME)
        list(APPEND CPACK_ZEAL_RUNTIME_LIBS "${_lib_name}")
    endforeach()

    if(_use_qt_cmake_commands)
        # Install Qt runtime dependencies.
        install(SCRIPT ${_qt_deploy_script})

        unset(_qt_deploy_script)
        unset(_use_qt_cmake_commands)
    endif()
elseif(UNIX)
    include(GNUInstallDirs)
    install(TARGETS App DESTINATION ${CMAKE_INSTALL_BINDIR})
endif()

#
# CPack configuration.
#
set(CPACK_GENERATOR "7Z;ZIP")

set(CPACK_VERBATIM_VARIABLES YES)

# Usage: cmake --build --preset <preset-name> --target package
# E.g. cmake --build --preset release --target package
set(CPACK_PACKAGE_NAME ${CMAKE_PROJECT_NAME})
set(CPACK_PACKAGE_DESCRIPTION ${CMAKE_PROJECT_DESCRIPTION})
set(CPACK_PACKAGE_HOMEPAGE_URL ${CMAKE_PROJECT_HOMEPAGE_URL})
set(CPACK_PACKAGE_VENDOR ${PROJECT_COMPANY_NAME})
set(CPACK_PACKAGE_VERSION ${PROJECT_VERSION})
set(CPACK_PACKAGE_ICON "${CMAKE_SOURCE_DIR}/src/app/resources/zeal.ico")

# Set binary package file name.
if(WIN32)
    if(CMAKE_SYSTEM_PROCESSOR STREQUAL "AMD64")
        set(_package_file_name_suffix "-windows-x64")
    elseif(CMAKE_SYSTEM_PROCESSOR STREQUAL "X86")
        set(_package_file_name_suffix "-windows-x86")
    elseif(CMAKE_SYSTEM_PROCESSOR STREQUAL "ARM64")
        set(_package_file_name_suffix "-windows-arm64")
    else()
        set(_package_file_name_suffix "-windows-unknown")
    endif()
else()
    set(_package_file_name_suffix "")
endif()

if(ZEAL_PORTABLE_BUILD)
    string(PREPEND _package_file_name_suffix "-portable")
endif()

set(CPACK_PACKAGE_FILE_NAME "${_project_output_name}-${ZEAL_VERSION_FULL}${_package_file_name_suffix}")

set(CPACK_PACKAGE_INSTALL_DIRECTORY ${CPACK_PACKAGE_NAME})
set(CPACK_PACKAGE_EXECUTABLES ${_project_output_name} ${CPACK_PACKAGE_NAME})
set(CPACK_CREATE_DESKTOP_LINKS ${_project_output_name} ${CPACK_PACKAGE_NAME})

set(CPACK_RESOURCE_FILE_README "${CMAKE_SOURCE_DIR}/README.md")

if(WIN32)
    # CPack WiX configuration.
    # Requires WiX 4 or 5; avoid WiX 6+ (Open Source Maintenance Fee terms).
    # Install WiX toolset:
    #   dotnet tool install --global wix --version 5.0.2
    # Install required extensions (pin to match WiX version):
    #   wix extension add --global WixToolset.UI.wixext/5.0.2
    #   wix extension add --global WixToolset.Util.wixext/5.0.2
    set(CPACK_WIX_VERSION "4")
    if(CMAKE_SYSTEM_PROCESSOR STREQUAL "AMD64")
        set(CPACK_WIX_ARCHITECTURE "x64")
    else()
        string(TOLOWER "${CMAKE_SYSTEM_PROCESSOR}" CPACK_WIX_ARCHITECTURE)
    endif()
    set(CPACK_WIX_UPGRADE_GUID "5C4B6030-A1B4-4EFE-A5AF-28F6FA2E7978")
    set(CPACK_WIX_PROPERTY_ARPURLINFOABOUT ${CMAKE_PROJECT_HOMEPAGE_URL})
    set(CPACK_WIX_PRODUCT_ICON "${CMAKE_SOURCE_DIR}/src/app/resources/zeal.ico")
    #set(CPACK_WIX_UI_BANNER "${CMAKE_SOURCE_DIR}/pkg/wix/banner.png")
    #set(CPACK_WIX_UI_DIALOG "${CMAKE_SOURCE_DIR}/pkg/wix/dialog.png")
    set(CPACK_WIX_EXTENSIONS "WixToolset.Util.wixext")
    set(CPACK_WIX_UI_REF "Zeal_InstallDir")
    set(CPACK_WIX_TEMPLATE "${CMAKE_SOURCE_DIR}/pkg/wix/template.xml")
    set(CPACK_WIX_PATCH_FILE "${CMAKE_SOURCE_DIR}/pkg/wix/patch.xml")
    set(CPACK_WIX_EXTRA_SOURCES
        "${CMAKE_SOURCE_DIR}/pkg/wix/ui.wxs"
        "${CMAKE_SOURCE_DIR}/pkg/wix/exitdialog.wxs"
    )

    set(CPACK_PRE_BUILD_SCRIPTS "${CMAKE_SOURCE_DIR}/pkg/wix/cpack_pre_build.cmake")

    if(NOT ZEAL_PORTABLE_BUILD)
        list(APPEND CPACK_GENERATOR "WIX")
        set(CPACK_POST_BUILD_SCRIPTS "${CMAKE_SOURCE_DIR}/pkg/wix/cpack_post_build.cmake")
    endif()
endif()

# Set options for the source package.
# Usage: cmake --build --target package_source
set(CPACK_SOURCE_GENERATOR "TGZ;TXZ;ZIP")
set(CPACK_SOURCE_PACKAGE_FILE_NAME "${_project_output_name}-${ZEAL_VERSION_FULL}")
set(CPACK_SOURCE_IGNORE_FILES
    # Directories.
    ".git/"
    ".github/"
    ".vscode/"
    "build/"
    # Files.
    ".editorconfig"
    ".gitattributes"
    ".gitignore"
)

include(CPack)
