cmake_minimum_required(VERSION 3.16)

project(GGTPassword VERSION 0.1 LANGUAGES CXX)

set(CMAKE_AUTOUIC ON)
set(CMAKE_AUTOMOC ON)
set(CMAKE_AUTORCC ON)

set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)

# 调试模式选项
option(DEBUG_MODE "Enable debug mode with Safari developer tools integration" ON)

# 检测平台
if(APPLE)
    if(CMAKE_SYSTEM_NAME STREQUAL "iOS")
        set(IOS TRUE)
        set(PLATFORM_NAME "iOS")
        # iOS特定设置：根据SDK类型设置不同的部署目标
        if(CMAKE_OSX_SYSROOT MATCHES "simulator")
            set(CMAKE_OSX_DEPLOYMENT_TARGET "13.0")
            # iOS 模拟器：Qt 6.10.0 的 arm64 切片只支持设备平台，必须使用 x86_64
            set(CMAKE_XCODE_ATTRIBUTE_ARCHS[sdk=iphonesimulator*] "x86_64")
            set(CMAKE_XCODE_ATTRIBUTE_VALID_ARCHS[sdk=iphonesimulator*] "x86_64")
            set(CMAKE_XCODE_ATTRIBUTE_ONLY_ACTIVE_ARCH "NO")
            # 强制使用 Release 版本的 Qt 库，避免 QtCore_debug 的链接问题
            # set(CMAKE_MAP_IMPORTED_CONFIG_DEBUG "Release")
            # message(STATUS "iOS Simulator build - using x86_64 architecture with Release Qt libraries")
        else()
            set(CMAKE_OSX_DEPLOYMENT_TARGET "17.0")
            message(STATUS "iOS Device build - using deployment target 17.0")
        endif()
        set(CMAKE_XCODE_ATTRIBUTE_DEVELOPMENT_TEAM "" CACHE STRING "Development Team ID")
        set(CMAKE_XCODE_ATTRIBUTE_CODE_SIGN_IDENTITY "iPhone Developer" CACHE STRING "Code Sign Identity")
        # 设置iOS SDK版本以匹配Qt插件
        set(CMAKE_XCODE_ATTRIBUTE_IPHONEOS_DEPLOYMENT_TARGET "${CMAKE_OSX_DEPLOYMENT_TARGET}")
        # 定义Q_OS_IOS宏，用于条件编译
        add_compile_definitions(Q_OS_IOS)
    else()
        set(PLATFORM_NAME "macOS")
    endif()
elseif(ANDROID)
    set(PLATFORM_NAME "Android")
elseif(WIN32)
    set(PLATFORM_NAME "Windows")
else()
    set(PLATFORM_NAME "Linux")
endif()

message(STATUS "Building for platform: ${PLATFORM_NAME}")
message(STATUS "Debug mode: ${DEBUG_MODE}")

# Qt组件
if(IOS)
    # iOS 构建只用 QtCore，移除 QtQuick 以保证纯原生 UI
    find_package(Qt6 REQUIRED COMPONENTS Core)
    set(QT_VERSION_MAJOR 6)
    # 完全禁用Qt的主函数和应用程序管理
    set(QT_NO_LINK_QTMAIN ON)
    set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DQT_NO_LINK_QTMAIN")
    add_compile_definitions(QT_NO_LINK_QTMAIN)
    # 阻止 Qt 为 Apple 平台设置入口包装 (qt_main_wrapper)
    set(QT_NO_SET_XCODE_LD_ENTRY_POINT ON)
    set(CMAKE_XCODE_ATTRIBUTE_QT_IMAGEFORMATS_PLUGIN_PATH "")
    set(CMAKE_XCODE_ATTRIBUTE_QT_DISABLE_IMAGEFORMATS_PLUGINS "YES")
    # iOS部署目标已在上面根据SDK类型设置，此处不再重复
elseif(ANDROID)
    # Android平台需要Core和Widgets模块，但不需要WebView（使用原生WebView）
    find_package(Qt6 REQUIRED COMPONENTS Core Widgets)
    set(QT_VERSION_MAJOR 6)
else()
    # 其他平台只支持Qt6
    find_package(Qt6 REQUIRED COMPONENTS Widgets)
    set(QT_VERSION_MAJOR 6)
endif()

# 基础源文件
# 基础源文件
set(PROJECT_SOURCES
        main.cpp
        
        # Qt资源文件
        resources.qrc
        
        # 通信桥接层
        bridge/WebViewBridge.h
        bridge/WebViewBridge.cpp
        
        # MVC架构
        mvc/BaseModel.h
        mvc/BaseModel.cpp
        mvc/BaseController.h
        mvc/BaseController.cpp
        mvc/BaseView.h
        mvc/BaseView.cpp
        
        # Demo模块
        demo/DemoModel.cpp
        demo/DemoController.cpp
)

# 平台特定源文件
if(APPLE)
    if(IOS)
        # 允许通过 -DBUNDLE_IDENTIFIER 覆盖 Bundle ID；未指定则使用默认值
        set(BUNDLE_IDENTIFIER_DEFAULT "com.ggt.GGTPassword")
        if(DEFINED BUNDLE_IDENTIFIER AND NOT "${BUNDLE_IDENTIFIER}" STREQUAL "")
            set(EFFECTIVE_BUNDLE_IDENTIFIER "${BUNDLE_IDENTIFIER}")
        else()
            set(EFFECTIVE_BUNDLE_IDENTIFIER "${BUNDLE_IDENTIFIER_DEFAULT}")
        endif()
        # iOS平台 - 使用原生WKWebView和AppDelegate
        list(APPEND PROJECT_SOURCES
            platform/ios/AppDelegate.h
            platform/ios/AppDelegate.mm
            platform/ios/IOSWebViewBridge.h
            platform/ios/IOSWebViewBridge.mm
            platform/ios/IOSView.h
            platform/ios/IOSView.cpp
            platform/ios/IOSViewController.h
            platform/ios/IOSViewController.mm
        )
        # iOS框架
        find_library(WEBKIT_FRAMEWORK WebKit)
        find_library(UIKIT_FRAMEWORK UIKit)
        set(PLATFORM_FRAMEWORKS ${WEBKIT_FRAMEWORK} ${UIKIT_FRAMEWORK})
    else()
        # macOS平台 - 包含mainwindow文件
        list(APPEND PROJECT_SOURCES
            mainwindow.cpp
            mainwindow.h
            debug/DebugManager.h
            debug/DebugManager.cpp
            platform/macos/MacOSWebViewBridge.h
            platform/macos/MacOSWebViewBridge.mm
            platform/macos/MacOSView.h
            platform/macos/MacOSView.cpp
            platform/macos/MacOSMenu.h
            platform/macos/MacOSMenu.mm
        )
        # macOS框架
        find_library(WEBKIT_FRAMEWORK WebKit)
        find_library(COCOA_FRAMEWORK Cocoa)
        set(PLATFORM_FRAMEWORKS ${WEBKIT_FRAMEWORK} ${COCOA_FRAMEWORK})
    endif()
elseif(ANDROID)
    # Android平台 - 使用原生WebView
    list(APPEND PROJECT_SOURCES
        platform/android/AndroidWebViewBridge.h
        platform/android/AndroidWebViewBridge.cpp
        platform/android/AndroidView.h
        platform/android/AndroidView.cpp
        debug/DebugManager.h
        debug/DebugManager.cpp
    )
    # Android特定设置
    set(PLATFORM_NAME "Android")
    add_compile_definitions(Q_OS_ANDROID)
elseif(WIN32)
    # Windows平台 - 使用WebView2
    list(APPEND PROJECT_SOURCES
        mainwindow.cpp
        mainwindow.h
        debug/DebugManager.h
        debug/DebugManager.cpp
        platform/windows/WindowsWebViewBridge.h
        platform/windows/WindowsWebViewBridge.cpp
        platform/windows/WindowsView.h
        platform/windows/WindowsView.cpp
    )
    # Windows WebView2依赖配置（稍后在目标创建后设置）
    find_package(PkgConfig QUIET)
    # 添加WebView2 NuGet包路径（如果使用NuGet安装）
    set(WEBVIEW2_INCLUDE_DIR "" CACHE PATH "WebView2 include directory")
    set(WEBVIEW2_LIB_DIR "" CACHE PATH "WebView2 library directory")
    
    # 如果没有指定路径，尝试查找常见位置
    if(NOT WEBVIEW2_INCLUDE_DIR)
        find_path(WEBVIEW2_INCLUDE_DIR 
            NAMES WebView2.h
            PATHS
                "C:/Program Files (x86)/Microsoft/Web/WebView2/*/include"
                "${CMAKE_CURRENT_SOURCE_DIR}/packages/Microsoft.Web.WebView2.*/build/native/include"
            NO_DEFAULT_PATH
        )
    endif()
    
    if(WEBVIEW2_INCLUDE_DIR)
        message(STATUS "Found WebView2 headers at: ${WEBVIEW2_INCLUDE_DIR}")
    else()
        message(WARNING "WebView2 headers not found. Please install WebView2 SDK or set WEBVIEW2_INCLUDE_DIR")
    endif()
else()
    # 其他平台包含mainwindow文件
    list(APPEND PROJECT_SOURCES
        mainwindow.cpp
        mainwindow.h
    )
endif()

# Web资源文件
set(WEB_RESOURCES
    web/index.html
    web/bridge.js
)

# macOS 特定配置 - 排除已弃用的 AGL 框架
if(APPLE AND NOT IOS)
    set_target_properties(Qt6::Gui PROPERTIES
        INTERFACE_LINK_LIBRARIES ""
    )
endif()

# 创建资源文件 - 只支持Qt6
qt_add_executable(GGTPassword
    MANUAL_FINALIZATION
    ${PROJECT_SOURCES}
)

# 非 iOS 平台使用 Qt 资源（qrc）；iOS 改为放入 Bundle 文件
if(NOT IOS)
    qt_add_resources(GGTPassword "web_resources"
        PREFIX "/web"
        FILES ${WEB_RESOURCES}
    )
endif()

# Qt6 Android配置
if(ANDROID)
    # 默认使用源码目录的 platform/android 作为打包源目录
    set(DEFAULT_ANDROID_PACKAGE_SOURCE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/platform/android")
    set(ANDROID_PACKAGE_DIR "${DEFAULT_ANDROID_PACKAGE_SOURCE_DIR}")

    # 允许通过 -DGGT_ANDROID_PACKAGE_SOURCE_DIR=... 覆盖到构建目录下的中间产物
    if(DEFINED GGT_ANDROID_PACKAGE_SOURCE_DIR AND NOT GGT_ANDROID_PACKAGE_SOURCE_DIR STREQUAL "")
        set(ANDROID_PACKAGE_DIR "${GGT_ANDROID_PACKAGE_SOURCE_DIR}")
    endif()

    # 仅使用单一打包源目录，避免 androiddeployqt 解析失败
    set_property(TARGET GGTPassword PROPERTY QT_ANDROID_PACKAGE_SOURCE_DIR "${ANDROID_PACKAGE_DIR}")
endif()

# 链接库
if(IOS)
    target_link_libraries(GGTPassword PRIVATE Qt${QT_VERSION_MAJOR}::Core)
    # 设置iOS特定的链接器标志，避免链接不兼容的Qt插件
    if(CMAKE_OSX_SYSROOT MATCHES "simulator")
        # 模拟器：强制使用 x86_64 架构（Qt 6.10.0 限制）
        set_target_properties(GGTPassword PROPERTIES
            XCODE_ATTRIBUTE_OTHER_LDFLAGS "-Wl,-dead_strip"
            XCODE_ATTRIBUTE_STRIP_STYLE "non-global"
            XCODE_ATTRIBUTE_LD_ENTRY_POINT "_main"
            XCODE_ATTRIBUTE_ARCHS[sdk=iphonesimulator*] "x86_64"
            XCODE_ATTRIBUTE_VALID_ARCHS[sdk=iphonesimulator*] "x86_64 arm64"
            XCODE_ATTRIBUTE_EXCLUDED_ARCHS[sdk=iphonesimulator*] "arm64"
            XCODE_ATTRIBUTE_ONLY_ACTIVE_ARCH "NO"
        )
    else()
        # 真机：使用默认 arm64
        set_target_properties(GGTPassword PROPERTIES
            XCODE_ATTRIBUTE_OTHER_LDFLAGS "-Wl,-dead_strip"
            XCODE_ATTRIBUTE_STRIP_STYLE "non-global"
            XCODE_ATTRIBUTE_LD_ENTRY_POINT "_main"
        )
    endif()
elseif(ANDROID)
    # Android平台链接库（不需要WebView，使用原生WebView）
    target_link_libraries(GGTPassword PRIVATE 
        Qt${QT_VERSION_MAJOR}::Core
        Qt${QT_VERSION_MAJOR}::Widgets
    )
else()
    target_link_libraries(GGTPassword PRIVATE Qt${QT_VERSION_MAJOR}::Widgets)
endif()

# 链接平台特定框架
if(APPLE AND PLATFORM_FRAMEWORKS)
    target_link_libraries(GGTPassword PRIVATE ${PLATFORM_FRAMEWORKS})
endif()

# Windows平台特定配置
if(WIN32)
    # 设置WebView2 SDK路径
    set(WEBVIEW2_SDK_PATH "${CMAKE_CURRENT_SOURCE_DIR}/third_party/webview2")
    set(WEBVIEW2_INCLUDE_DIR "${WEBVIEW2_SDK_PATH}/build/native/include")
    
    # 检查WebView2头文件是否存在
    if(EXISTS "${WEBVIEW2_INCLUDE_DIR}/WebView2.h")
        message(STATUS "Found WebView2 SDK at: ${WEBVIEW2_INCLUDE_DIR}")
    else()
        message(FATAL_ERROR "WebView2.h not found at: ${WEBVIEW2_INCLUDE_DIR}")
    endif()
    
    # 确定平台架构
    if(CMAKE_SIZEOF_VOID_P EQUAL 8)
        set(WEBVIEW2_ARCH "x64")
    else()
        set(WEBVIEW2_ARCH "x86")
    endif()
    
    # 设置WebView2库路径
    set(WEBVIEW2_LIB_DIR "${WEBVIEW2_SDK_PATH}/build/native/${WEBVIEW2_ARCH}")
    
    # 链接WebView2相关库
    target_link_libraries(GGTPassword PRIVATE 
        ole32 
        oleaut32 
        user32 
        gdi32
        "${WEBVIEW2_LIB_DIR}/WebView2Loader.dll.lib"
    )
    
    # 添加WebView2头文件路径
    target_include_directories(GGTPassword PRIVATE ${WEBVIEW2_INCLUDE_DIR})
endif()

# 设置编译器特定选项
if(APPLE)
    # 启用Objective-C++支持
    if(IOS)
        set_source_files_properties(
            main.cpp
            platform/ios/AppDelegate.mm
            platform/ios/IOSWebViewBridge.mm
            platform/ios/IOSViewController.mm
            PROPERTIES COMPILE_FLAGS "-x objective-c++"
        )
    else()
        set_source_files_properties(
            platform/macos/MacOSWebViewBridge.mm
            platform/macos/MacOSMenu.mm
            PROPERTIES COMPILE_FLAGS "-x objective-c++"
        )
    endif()
    
    # 设置最低系统版本
    if(IOS)
        set_target_properties(GGTPassword PROPERTIES
            XCODE_ATTRIBUTE_IPHONEOS_DEPLOYMENT_TARGET "13.0"
            XCODE_ATTRIBUTE_TARGETED_DEVICE_FAMILY "1,2"  # iPhone和iPad
            XCODE_ATTRIBUTE_ONLY_ACTIVE_ARCH "NO"
            XCODE_ATTRIBUTE_VALID_ARCHS "arm64"
            XCODE_ATTRIBUTE_ARCHS "arm64"
            # 启用自动代码签名（参考temp项目但使用自动签名）
            XCODE_ATTRIBUTE_CODE_SIGN_STYLE "Automatic"
            XCODE_ATTRIBUTE_CODE_SIGN_IDENTITY "iPhone Developer"
            XCODE_ATTRIBUTE_DEVELOPMENT_TEAM ""
            # Bundle配置
            MACOSX_BUNDLE_GUI_IDENTIFIER ${EFFECTIVE_BUNDLE_IDENTIFIER}
            XCODE_ATTRIBUTE_PRODUCT_BUNDLE_IDENTIFIER "${EFFECTIVE_BUNDLE_IDENTIFIER}"
            XCODE_ATTRIBUTE_REQUIRES_FULL_SCREEN "YES"
            # 禁用 Bitcode（iOS 14+ 不再需要）
            XCODE_ATTRIBUTE_ENABLE_BITCODE "NO"
            # 明确设置入口点为 _main，避免使用 Qt 的 _qt_main_wrapper
            XCODE_ATTRIBUTE_LD_ENTRY_POINT "_main"
        )
        
        # iOS特定的Bundle设置
        set_target_properties(GGTPassword PROPERTIES
            MACOSX_BUNDLE TRUE
            MACOSX_BUNDLE_INFO_PLIST ${CMAKE_CURRENT_SOURCE_DIR}/Info.plist.in
            XCODE_ATTRIBUTE_PRODUCT_BUNDLE_IDENTIFIER "${EFFECTIVE_BUNDLE_IDENTIFIER}"
            XCODE_ATTRIBUTE_MARKETING_VERSION "1.0"
            XCODE_ATTRIBUTE_CURRENT_PROJECT_VERSION "1"
        )
    else()
        set_target_properties(GGTPassword PROPERTIES
            XCODE_ATTRIBUTE_MACOSX_DEPLOYMENT_TARGET "10.15"
        )
    endif()
endif()

# 包含目录
target_include_directories(GGTPassword PRIVATE
    ${CMAKE_CURRENT_SOURCE_DIR}
    ${CMAKE_CURRENT_SOURCE_DIR}/bridge
    ${CMAKE_CURRENT_SOURCE_DIR}/mvc
    ${CMAKE_CURRENT_SOURCE_DIR}/platform
)

# 编译定义
target_compile_definitions(GGTPassword PRIVATE
    QT_DEPRECATED_WARNINGS
)

# 根据DEBUG_MODE选项添加编译定义
if(DEBUG_MODE)
    target_compile_definitions(GGTPassword PRIVATE
        WEBVIEW_DEBUG_MODE=1
        QT_MESSAGELOGCONTEXT
    )
    message(STATUS "Debug mode enabled - Safari developer tools will be available")
else()
    target_compile_definitions(GGTPassword PRIVATE
        WEBVIEW_DEBUG_MODE=0
    )
    message(STATUS "Debug mode disabled - No debug features will be loaded")
endif()

# Qt for iOS sets MACOSX_BUNDLE_GUI_IDENTIFIER automatically since Qt 6.1.
# If you are developing for iOS or macOS you should consider setting an
# explicit, fixed bundle identifier manually though.
if(DEFINED QT_VERSION)
    if(${QT_VERSION} VERSION_LESS 6.1.0)
        # Qt < 6.1 无法自动设置 GUI Identifier，使用有效的 Bundle ID
        if(NOT DEFINED EFFECTIVE_BUNDLE_IDENTIFIER)
            set(EFFECTIVE_BUNDLE_IDENTIFIER "com.ggt.GGTPassword")
        endif()
        set(BUNDLE_ID_OPTION MACOSX_BUNDLE_GUI_IDENTIFIER ${EFFECTIVE_BUNDLE_IDENTIFIER})
    endif()
endif()

# 配置Info.plist
if(APPLE)
    set_target_properties(GGTPassword PROPERTIES
        MACOSX_BUNDLE_INFO_PLIST ${CMAKE_CURRENT_SOURCE_DIR}/Info.plist.in
    )
endif()

set_target_properties(GGTPassword PROPERTIES
    ${BUNDLE_ID_OPTION}
    MACOSX_BUNDLE_BUNDLE_VERSION ${PROJECT_VERSION}
    MACOSX_BUNDLE_SHORT_VERSION_STRING ${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR}
    MACOSX_BUNDLE TRUE
)

# Windows 控制台/GUI 子系统切换：调试模式下启用控制台输出
if(WIN32)
    if(DEBUG_MODE)
        # Debug 模式：使用控制台子系统，便于在终端查看输出
        set_target_properties(GGTPassword PROPERTIES WIN32_EXECUTABLE FALSE)
        message(STATUS "Windows: Console subsystem enabled for debug mode (stdout/stderr visible)")
    else()
        # Release 模式：使用 GUI 子系统，不弹出控制台窗口
        set_target_properties(GGTPassword PROPERTIES WIN32_EXECUTABLE TRUE)
        message(STATUS "Windows: GUI subsystem enabled for release mode")
    endif()
endif()

include(GNUInstallDirs)
install(TARGETS GGTPassword
    BUNDLE DESTINATION .
    LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
    RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
)

# 完成Qt6可执行文件配置
qt_finalize_executable(GGTPassword)

# 添加测试程序选项
option(BUILD_TEST_ONLY "Build only test program" OFF)

if(BUILD_TEST_ONLY OR BUILD_TESTING)
    # 测试程序源文件
    set(TEST_SOURCES
        test_webview_simple.cpp
        bridge/WebViewBridge.cpp
        mvc/BaseView.cpp
        mvc/BaseModel.cpp
        mvc/BaseController.cpp
    )
    
    # 添加平台特定的测试源文件
    if(WIN32)
        list(APPEND TEST_SOURCES
            platform/windows/WindowsView.cpp
            platform/windows/WindowsWebViewBridge.cpp
        )
    endif()
    
    # 创建测试可执行文件
    add_executable(test_webview_simple ${TEST_SOURCES})
    
    # 链接测试程序的库
    target_link_libraries(test_webview_simple PRIVATE Qt${QT_VERSION_MAJOR}::Widgets)
    
    # 设置测试程序的包含目录
    target_include_directories(test_webview_simple PRIVATE ${CMAKE_CURRENT_SOURCE_DIR})
    
    # Windows平台特定设置
    if(WIN32)
        target_link_libraries(test_webview_simple PRIVATE ole32 oleaut32 user32 gdi32)
        
        # 查找WebView2
        if(WEBVIEW2_SDK_PATH)
            target_include_directories(test_webview_simple PRIVATE "${WEBVIEW2_SDK_PATH}/build/native/include")
            target_link_libraries(test_webview_simple PRIVATE "${WEBVIEW2_LIB_DIR}/WebView2Loader.dll.lib")
        endif()
    endif()
endif()

# 为 iOS 将 web 目录打包到 Bundle 的 Resources/web 下，供 WKWebView 直接读取
if(APPLE AND IOS)
    set_source_files_properties(
        ${CMAKE_CURRENT_SOURCE_DIR}/web/index.html
        ${CMAKE_CURRENT_SOURCE_DIR}/web/bridge.js
        PROPERTIES MACOSX_PACKAGE_LOCATION "Resources/web"
    )
    target_sources(GGTPassword PRIVATE
        ${CMAKE_CURRENT_SOURCE_DIR}/web/index.html
        ${CMAKE_CURRENT_SOURCE_DIR}/web/bridge.js
    )
endif()
