/*******************************************************************************
 *
 * SPDX-FileCopyrightText: 2023-2024 Open Mobile Platform LLC <community@omp.ru>
 * SPDX-License-Identifier: MIT
 *
 ******************************************************************************/

#ifndef RM_LIB_INTENTS_INVOKER_H
#define RM_LIB_INTENTS_INVOKER_H

#include "error.h"
#include "global.h"

#include <QObject>
#include <QScopedPointer>
#include <QUrl>

class QJsonObject;
namespace RuntimeManager {

class IntentsInvokerPrivate;
/**
 * @brief Intent invoker.
 * @class IntentsInvoker intents_invoker.h <RuntimeManager/IntentsInvoker>
 *
 * Allow applications invoke actions on other applications.
 */
class RM_EXPORT IntentsInvoker: public QObject
{
    Q_OBJECT
public:
    /**
     * Construct an intent invoker. Note that this object must not be destroyed
     * before the replyReceived() signal is emitted, or a reply will not be
     * received.
     */
    IntentsInvoker(QObject *parent = Q_NULLPTR);
    ~IntentsInvoker();

    /**
     * @brief Invoke specified intent.
     *
     * The intents defined by the OS are listed in the @ref standard-intents
     * "Standard intents" page. This method can also be used to invoke
     * non-standard intents (make sure that the intent name starts with an "X-"
     * prefix.
     *
     * Since intents need some time to processed, the reply will be delivered
     * asynchronously by replyReceived() signal.
     *
     * @param intentName The name of the intent to invoke
     * @param hints Optional hints to the RuntimeManager service. Currently the
     *        following hints are supported:
     *        \li \c preferredHandler specifies the application ID of the
     *            desired handler (this will be honoured only if the two
     *            applications come from the same Organization).
     *        \li \c onlyPreferred returns an error if the application
     *            specified in \c preferredHandler is not available.
     *        \li \c readFiles and \c writeFiles are used to share files with
     *            the intent handler (in read-only or read-write mode,
     *            respectively): each of these properties can hold a list of
     *            strings, each of which is a JSON path indicating which values
     *            in the \c params dictionary contain the paths to the files
     *            that need to be made available to the target application. For
     *            example, if the \c inputFile key in the \c params dictionary
     *            contains the path to a file that needs to be accessed by the
     *            intent handler in read-only mode, the \c readFiles hint
     *            should be set to \c ["inputFile"].
     *        \li \c ignoreHosts and \c ignoreSchemes are only valid for the \c
     *            OpenURI intent and contain lists of hosts (or URI schemes)
     *            that will be ignored when looking up for an intent handler:
     *            the first will cause all desktop file rules of the type \c
     *            x-url-handler to be ignored, the second the rules of type \c
     *            x-scheme-handler. The special value \c "all" is supported by
     *            both hints.
     * @param params The parameters for the intent
     */
    void invoke(const QString &intentName,
                const QJsonObject &hints,
                const QJsonObject &params);

    /**
     * @brief Convert an intent to a URI
     *
     * @param intentName The name of the intent to invoke
     * @param hints Hints to the RuntimeManager service; see the invoke()
     *        method for details
     * @param params The parameters for the intent
     */
    static QUrl intentToUri(const QString &intentName,
                            const QJsonObject &hints,
                            const QJsonObject &params);

Q_SIGNALS:
    /**
     * @brief Completion callback
     *
     * This signal will be emitted when the reply is received. \a error will be
     * empty on valid reply.
     *
     * @param reply The response data. Semantics depends on the intent.
     * @param error Set to a valid error if an error occurred.
     */
    void replyReceived(const QJsonObject &reply, const Error &error);

private:
    Q_DECLARE_PRIVATE(IntentsInvoker)
    QScopedPointer<IntentsInvokerPrivate> d_ptr;
};

} // namespace RuntimeManager

#endif // RM_LIB_INTENTS_INVOKER_H
