cmake_minimum_required(VERSION 3.16)
project(cst-agent-app LANGUAGES C CXX VERSION 0.1.0)

# The Qt front end (app/) embeds the C engine in-process: it links libcstcore
# and never opens a port. Two targets:
#
#   cst-app-selftest  pure C smoke test of the embedding path (no Qt), so the
#                     C side is still guarded on machines without Qt Quick
#   cst-agent-app     the GUI (Qt 6 Quick + QML), built when the Qt modules
#                     are there
#
# Standalone build (builds the engine from ../ too):
#   cmake -S app -B build-app -DCMAKE_BUILD_TYPE=Debug && cmake --build build-app -j
# Inside the repo build (the parent defines the cstcore target, shared with the CLI):
#   cmake -B build -DCST_BUILD_APP=ON && cmake --build build --target cst-agent-app
#
# Extra QML import paths, e.g. a Kirigami installed away from the Qt prefix:
#   -DCST_APP_QML_IMPORT=...   (added to QML2_IMPORT_PATH / the app's runtime)

option(CST_APP_GUI "build the Qt GUI (needs Qt6 Quick, Qml, QuickControls2)" ON)
option(CST_APP_SELFTEST "build the C embedding smoke test" ON)

# --- the engine ----------------------------------------------------------
# Used as a subproject (../CMakeLists.txt already defined cstcore, engine
# compiled once for CLI and app) or built here from the sources next door.
if(NOT TARGET cstcore)
  set(CST_APP_ROOT "${CMAKE_CURRENT_SOURCE_DIR}/..")
  include_directories("${CST_APP_ROOT}/include" "${CST_APP_ROOT}/vendor/cjson")
  file(GLOB CST_APP_CORE_SRC
    "${CST_APP_ROOT}/src/*.c"
    "${CST_APP_ROOT}/src/tools/*.c"
    "${CST_APP_ROOT}/vendor/cjson/cJSON.c")
  list(REMOVE_ITEM CST_APP_CORE_SRC
    "${CST_APP_ROOT}/src/main.c"
    "${CST_APP_ROOT}/src/tui.c"
    "${CST_APP_ROOT}/src/tui_stub.c"
    "${CST_APP_ROOT}/src/textsel.c")
  # The HTTP front end is not part of an in-process app: no server, no port.
  list(REMOVE_ITEM CST_APP_CORE_SRC
    "${CST_APP_ROOT}/src/net.c"
    "${CST_APP_ROOT}/src/http_srv.c"
    "${CST_APP_ROOT}/src/webui.c"
    "${CST_APP_ROOT}/src/web_md.c")
  if(EXISTS "${CST_APP_ROOT}/.gen/models_builtin.inc")
    include_directories("${CST_APP_ROOT}/.gen")
  endif()
  add_library(cstcore STATIC ${CST_APP_CORE_SRC})
  target_compile_definitions(cstcore PRIVATE CST_NO_WEBUI=1)
  find_package(CURL REQUIRED)
  find_package(Threads REQUIRED)
  target_link_libraries(cstcore PUBLIC ${CURL_LIBRARIES} Threads::Threads m)
  message(STATUS "app: building the engine from ${CST_APP_ROOT}")
else()
  message(STATUS "app: linking the cstcore target of the parent build")
endif()

# --- the C smoke test ----------------------------------------------------
if(CST_APP_SELFTEST)
  add_executable(cst-app-selftest tools/selftest.c)
  target_link_libraries(cst-app-selftest PRIVATE cstcore)
  enable_testing()
  add_test(NAME cst-app-selftest COMMAND cst-app-selftest)
endif()

# --- the GUI -------------------------------------------------------------
if(CST_APP_GUI)
  find_package(Qt6 6.4 COMPONENTS Core Gui Qml Quick QuickControls2 Test QUIET)
  if(NOT Qt6_FOUND)
    message(WARNING
      "app: Qt 6 Quick/Qml not found, skipping cst-agent-app "
      "(the C selftest still builds; install e.g. qt6.qtdeclarative / "
      "qt6.qtquickcontrols2 and reconfigure)")
  else()
    qt_standard_project_setup()
    # Qt 6.5+ policies: keep the module resource at :/qt/qml/<URI>/ (what
    # main.cpp loads) and let CMake generate the qmldir of qml/ for us.
    qt_policy(SET QTP0001 NEW)
    qt_policy(SET QTP0004 NEW)
    qt_add_executable(cst-agent-app
      src/main.cpp
      src/core/AgentCore.cpp
      src/core/ToolProvider.cpp
      src/ui/UiTest.cpp
      src/platform/linux/NotifyTool.cpp)
    target_include_directories(cst-agent-app PRIVATE
      src "${CMAKE_CURRENT_SOURCE_DIR}/../include")
    target_compile_definitions(cst-agent-app PRIVATE CST_APP_VERSION="${PROJECT_VERSION}")
    if(CST_APP_QML_IMPORT)
      target_compile_definitions(cst-agent-app PRIVATE
        CST_APP_QML_IMPORT="${CST_APP_QML_IMPORT}")
    endif()
    target_link_libraries(cst-agent-app PRIVATE
      Qt6::Core Qt6::Gui Qt6::Qml Qt6::Quick Qt6::QuickControls2 Qt6::Test cstcore)
    if(WIN32)
      set_target_properties(cst-agent-app PROPERTIES WIN32_EXECUTABLE TRUE)
    endif()

    # Theme is read by every component, so it is a QML singleton (one instance,
    # no object needed in the tree).
    set_source_files_properties(qml/Theme.qml PROPERTIES QT_QML_SINGLETON_TYPE TRUE)
    # Keep the module flat in the resource tree (:qt/qml/CstAgent/Main.qml).
    # Sources live in qml/, but a module whose files sit in a subdirectory of
    # the URI makes Qt register the types with relative URLs ("qmlRegisterType
    # requires absolute URLs" on every start).
    foreach(_qml Main ChatView Sidebar SessionRow MessageCard ToolCard ThinkBlock
                 NoteLine TodoPanel Composer ConsentDialog AskDialog SettingsDialog
                 Theme)
      set_source_files_properties(qml/${_qml}.qml PROPERTIES QT_RESOURCE_ALIAS ${_qml}.qml)
    endforeach()
    qt_add_qml_module(cst-agent-app
      URI CstAgent
      VERSION 1.0
      QML_FILES
        qml/Main.qml
        qml/ChatView.qml
        qml/Sidebar.qml
        qml/SessionRow.qml
        qml/MessageCard.qml
        qml/ToolCard.qml
        qml/ThinkBlock.qml
        qml/NoteLine.qml
        qml/TodoPanel.qml
        qml/Composer.qml
        qml/ConsentDialog.qml
        qml/AskDialog.qml
        qml/SettingsDialog.qml
        qml/Theme.qml)
  endif()
endif()
