/*
 * SPDX-FileCopyrightText: 2026 ChromiumOS-Guy <chromiumos-guy-opensource@proton.me>
 * SPDX-License-Identifier: GPL-3.0-or-later
 */

#pragma once

#include <QObject>

// Marker interface so DesktopPortal can pick portal plugins out of
// QPluginLoader::staticInstances() with qobject_cast. It carries no methods each plugin is
// already a QObject that owns its portal (and its D-Bus adaptor), so DesktopPortal just reparents
// the plugin and registers the adaptors it finds; there is nothing for a factory to do.
class PortalFactory
{
public:
    virtual ~PortalFactory() = default;
};

#define LomiriPortalFactory_iid "io.lomiri.xdg-desktop-portal.PortalFactory/1.0"
Q_DECLARE_INTERFACE(PortalFactory, LomiriPortalFactory_iid)

// plugin boilerplate: write a portal as a normal QObject in `namespace portals`, then
// AFTER the namespace closes drop
//   LOMIRI_PORTAL_PLUGIN(YourClass)
// at end of file. add_portal() generates the matching Q_IMPORT_PLUGIN(YourClassPortalPlugin) and
// registers LOMIRI_PORTAL_PLUGIN as an AUTOMOC macro name, so there is nothing else to wire up.
// The plugin owns the portal as its child; the portal's constructor creates its adaptor, so the
// whole tree (plugin -> portal -> adaptor) exists as soon as the static plugin is instantiated.
#define LOMIRI_PORTAL_PLUGIN(CLASS)                                                                 \
    class CLASS##PortalPlugin : public QObject, public PortalFactory                                \
    {                                                                                               \
        Q_OBJECT                                                                                    \
        Q_PLUGIN_METADATA(IID LomiriPortalFactory_iid)                                              \
        Q_INTERFACES(PortalFactory)                                                                 \
    public:                                                                                         \
        CLASS##PortalPlugin() { new portals::CLASS(this); }                                         \
    };
