# SPDX-FileCopyrightText: 2026 Maciej Sopyło <me@klh.io>
# SPDX-FileCopyrightText: 2026 ChromiumOS-Guy <chromiumos-guy-opensource@proton.me>
# SPDX-License-Identifier: GPL-3.0-or-later

# src/CMakeLists.txt
find_package(Qt6 REQUIRED COMPONENTS Core DBus Gui)

add_library(lomiri-portal-api INTERFACE)
target_include_directories(lomiri-portal-api INTERFACE ${CMAKE_CURRENT_SOURCE_DIR})
target_link_libraries(lomiri-portal-api INTERFACE Qt6::Core Qt6::DBus Qt6::Gui)

set_property(GLOBAL PROPERTY LOMIRI_PORTAL_TARGETS "")
set_property(GLOBAL PROPERTY LOMIRI_PORTAL_CLASSES "")

# portal helper. A portal's CMakeLists.txt is just:
#     add_portal(Settings Settings.cpp)
# Convention: folder/class/interface all share <NAME>. Each portal is built as a Qt *static* plugin
# (OBJECT library + QT_STATICPLUGIN) that compiles into the single executable so no shared objects.
function(add_portal NAME)
    string(TOLOWER ${NAME} lname)

    # qtdbusxml2cpp emits C++ keywords as arg names; rename the "namespace" arg with xmlstarlet first.
    set(xmlOut ${CMAKE_CURRENT_BINARY_DIR}/org.freedesktop.impl.portal.${NAME}.xml)
    execute_process(
        COMMAND xmlstarlet ed -u "//arg[@name=\"namespace\"]/@name" -v ns
                /usr/share/dbus-1/interfaces/org.freedesktop.impl.portal.${NAME}.xml
        OUTPUT_FILE ${xmlOut}
    )

    set(gen)
    qt_add_dbus_adaptor(gen
        ${xmlOut}
        ${CMAKE_CURRENT_SOURCE_DIR}/${NAME}.h
        portals::${NAME}
        portal_${lname}_adaptor
    )

    add_library(lomiri-portal-${lname} OBJECT ${ARGN} ${gen})
    # QT_STATICPLUGIN makes meta object compiler emit the static-plugin registration for Q_PLUGIN_METADATA.
    target_compile_definitions(lomiri-portal-${lname} PRIVATE QT_STATICPLUGIN)
    # LOMIRI_PORTAL_PLUGIN hides Q_OBJECT/Q_PLUGIN_METADATA in a macro; tell AutoMoc about it.
    set_property(TARGET lomiri-portal-${lname} APPEND PROPERTY AUTOMOC_MACRO_NAMES "LOMIRI_PORTAL_PLUGIN")

    target_include_directories(lomiri-portal-${lname} PRIVATE
        ${CMAKE_CURRENT_SOURCE_DIR}
        ${CMAKE_CURRENT_BINARY_DIR}
    )
    target_link_libraries(lomiri-portal-${lname} PRIVATE lomiri-portal-api)

    set_property(GLOBAL APPEND PROPERTY LOMIRI_PORTAL_TARGETS lomiri-portal-${lname})
    set_property(GLOBAL APPEND PROPERTY LOMIRI_PORTAL_CLASSES ${NAME}PortalPlugin)
endfunction()

add_subdirectory(portals)

# Generate the Q_IMPORT_PLUGIN() calls that register each static portal so staticInstances() sees it.
get_property(portal_targets GLOBAL PROPERTY LOMIRI_PORTAL_TARGETS)
get_property(portal_classes GLOBAL PROPERTY LOMIRI_PORTAL_CLASSES)
set(importsContent "#include <QtPlugin>\n")
foreach(cls IN LISTS portal_classes)
    string(APPEND importsContent "Q_IMPORT_PLUGIN(${cls})\n")
endforeach()
file(GENERATE OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/static_portals.cpp CONTENT "${importsContent}")

# The Request interface is shared by every portal; generate its adaptor from the xdg-provided XML
# (no "namespace" arg to rename, so no xmlstarlet pass needed).
qt_add_dbus_adaptor(request_adaptor_src
    /usr/share/dbus-1/interfaces/org.freedesktop.impl.portal.Request.xml
    ${CMAKE_CURRENT_SOURCE_DIR}/request.h
    Request
    request_adaptor
    RequestAdaptor
)

# generate the standalone executable with the portals statically built in (easier to deal with).
add_executable(xdg-desktop-portal-lomiri
    main.cpp
    DesktopPortal.cpp
    ObjectProxy.cpp
    dbus_types.cpp
    request.cpp
    ${request_adaptor_src}
    ${CMAKE_CURRENT_BINARY_DIR}/static_portals.cpp
)
target_include_directories(xdg-desktop-portal-lomiri PRIVATE ${CMAKE_CURRENT_BINARY_DIR})
target_link_libraries(xdg-desktop-portal-lomiri PRIVATE lomiri-portal-api ${portal_targets})
