# SPDX-License-Identifier: GPL-3.0-or-later
cmake_minimum_required(VERSION 3.20)
project(TapeBrowser LANGUAGES CXX)
option(TAPE_FAST_WASM_LINK "Skip final Binaryen size optimization during Tape QA" ON)
option(TAPE_REUSE_VALENTINA_OBJECTS "Reuse already compiled production library objects" ON)
set(CMAKE_CXX_STANDARD 20)
set(CMAKE_AUTOMOC ON)
set(CMAKE_AUTOUIC ON)
set(CMAKE_AUTORCC ON)
set(PROBE_ROOT "${CMAKE_CURRENT_SOURCE_DIR}/..")
set(VALENTINA_SOURCE "${PROBE_ROOT}/../valentina-src" CACHE PATH "Valentina v0.7.53 source")
set(VALENTINA_SHARED_BUILD "${PROBE_ROOT}/build" CACHE PATH "Existing Valentina object directory")
find_package(Qt6 6.7 REQUIRED COMPONENTS Core Gui Widgets Network Xml Svg SvgWidgets PrintSupport OpenGL OpenGLWidgets Concurrent)
get_target_property(qt_platform_link_options Qt6::Platform INTERFACE_LINK_OPTIONS)
list(TRANSFORM qt_platform_link_options REPLACE "DISABLE_EXCEPTION_CATCHING=1" "DISABLE_EXCEPTION_CATCHING=0")
set_property(TARGET Qt6::Platform PROPERTY INTERFACE_LINK_OPTIONS "${qt_platform_link_options}")
find_package(XercesC 3.2 REQUIRED)
set(libs fervor ifc qmuparser vdxf vformat vgeometry vlayout vmisc vobj vpatterndb vpropertyexplorer vtools vwidgets vganalytics vhpgl)
set(sources)
set(includes "${VALENTINA_SOURCE}/src/libs" "${VALENTINA_SOURCE}/src/app/tape")
foreach(lib IN LISTS libs)
  file(GLOB_RECURSE headers CONFIGURE_DEPENDS "${VALENTINA_SOURCE}/src/libs/${lib}/*.h")
  list(APPEND sources ${headers})
  list(APPEND includes "${VALENTINA_SOURCE}/src/libs/${lib}")
  if(NOT TAPE_REUSE_VALENTINA_OBJECTS)
    file(GLOB_RECURSE cpp CONFIGURE_DEPENDS "${VALENTINA_SOURCE}/src/libs/${lib}/*.cpp" "${VALENTINA_SOURCE}/src/libs/${lib}/*.qrc" "${VALENTINA_SOURCE}/src/libs/${lib}/*.ui")
    list(APPEND sources ${cpp})
  endif()
endforeach()
if(TAPE_REUSE_VALENTINA_OBJECTS)
  file(GLOB_RECURSE shared_objects "${VALENTINA_SHARED_BUILD}/CMakeFiles/valentina.dir/*.o")
  list(FILTER shared_objects INCLUDE REGEX "/src/libs/.*\\.cpp\\.o$|/qrc_(toolcursor|toolicon|cursor|flags|icon|scenestyle|win_dark_theme|win_light_theme|breeze|schema)\\.cpp\\.o$")
  # The shared build may retain stale objects from earlier resource paths.
  # Reuse only objects defined by its current Ninja graph, never every disk .o.
  file(READ "${VALENTINA_SHARED_BUILD}/build.ninja" shared_ninja)
  set(active_objects)
  foreach(object IN LISTS shared_objects)
    file(RELATIVE_PATH relative "${VALENTINA_SHARED_BUILD}" "${object}")
    string(FIND "${shared_ninja}" "build ${relative}:" active_rule)
    if(NOT active_rule EQUAL -1)
      list(APPEND active_objects "${object}")
    endif()
  endforeach()
  set(shared_objects ${active_objects})
  list(LENGTH shared_objects object_count)
  if(object_count LESS 400)
    message(FATAL_ERROR "Expected production library objects; found ${object_count}. Build Valentina first or set TAPE_REUSE_VALENTINA_OBJECTS=OFF.")
  endif()
  list(APPEND sources ${shared_objects})
  set_source_files_properties(${shared_objects} PROPERTIES EXTERNAL_OBJECT TRUE GENERATED TRUE)
  message(STATUS "Tape reuses ${object_count} compiled production library/resource objects")
endif()
file(GLOB_RECURSE tape_sources CONFIGURE_DEPENDS "${VALENTINA_SOURCE}/src/app/tape/*.cpp" "${VALENTINA_SOURCE}/src/app/tape/*.h" "${VALENTINA_SOURCE}/src/app/tape/*.ui" "${VALENTINA_SOURCE}/src/app/tape/*.qrc")
list(APPEND sources ${tape_sources})
list(FILTER sources EXCLUDE REGEX "/(stable|appimage|vtestapplication)\\.cpp$")
list(FILTER sources EXCLUDE REGEX "/crashhandler/")
list(FILTER sources EXCLUDE REGEX "/(mac_light_theme|mac_dark_theme|win_light_theme|win_dark_theme)\\.qrc$")
list(FILTER sources EXCLUDE REGEX "/theme\\.qrc$")
if(NOT TAPE_REUSE_VALENTINA_OBJECTS)
  list(APPEND sources "${PROBE_ROOT}/resources/win_light_theme.qrc" "${PROBE_ROOT}/resources/win_dark_theme.qrc")
endif()
qt_add_executable(tape ${sources})
# Library headers generate independent moc code. Their UI search paths are
# retained for the clean-source fallback; reused .cpp.o already contain UIs.
set(ui_dirs)
file(GLOB_RECURSE library_ui "${VALENTINA_SOURCE}/src/libs/*.ui")
foreach(source IN LISTS sources library_ui)
  if(source MATCHES "\\.ui$")
    get_filename_component(ui_dir "${source}" DIRECTORY)
    list(APPEND ui_dirs "${ui_dir}")
  endif()
endforeach()
list(REMOVE_DUPLICATES ui_dirs)
set_target_properties(tape PROPERTIES AUTOUIC_SEARCH_PATHS "${ui_dirs}")
target_include_directories(tape PRIVATE ${includes})
target_link_libraries(tape PRIVATE Qt6::Core Qt6::Gui Qt6::Widgets Qt6::Network Qt6::Xml Qt6::Svg Qt6::SvgWidgets Qt6::PrintSupport Qt6::OpenGL Qt6::OpenGLWidgets Qt6::Concurrent XercesC::XercesC)
target_compile_definitions(tape PRIVATE QBS_BUILD V_NO_ASSERT QT_MESSAGELOGCONTEXT QT_NO_FOREACH QMU_PARSER_STATIC VPROPERTYEXPLORER_STATIC BINDIR="/" DATADIR="/" PKGDATADIR="/" BUILD_REVISION="f9b773" LATEST_TAG_DISTANCE=0)
target_compile_options(tape PRIVATE -fexceptions)
target_link_options(tape PRIVATE -fexceptions -sASYNCIFY -sASYNCIFY_STACK_SIZE=1048576 -sALLOW_MEMORY_GROWTH=1 -sINITIAL_MEMORY=268435456 -sSTACK_SIZE=8388608 -sPTHREAD_POOL_SIZE=8 "-sEXPORTED_RUNTIME_METHODS=['FS','ccall']")
if(TAPE_FAST_WASM_LINK)
  target_link_options(tape PRIVATE -O0)
else()
  target_link_options(tape PRIVATE -Os)
endif()
set_target_properties(tape PROPERTIES QT_WASM_INITIAL_MEMORY 268435456 QT_WASM_PTHREAD_POOL_SIZE 8 QT_WASM_EXTRA_EXPORTED_METHODS ccall)
find_package(Python3 REQUIRED COMPONENTS Interpreter)
set(BUILD_PYTHON "${Python3_EXECUTABLE}")
add_custom_command(TARGET tape POST_BUILD
  COMMAND "${BUILD_PYTHON}" "${PROBE_ROOT}/patch_runtime.py" "$<TARGET_FILE:tape>"
  COMMAND "${BUILD_PYTHON}" "${CMAKE_CURRENT_SOURCE_DIR}/write_build_profile.py" "$<TARGET_FILE:tape>"
  VERBATIM)
