/****************************************************************************
**
** Copyright (C) 2016 The Qt Company Ltd.
** Copyright (C) 2016 Intel Corporation.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the QtDBus module of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 3 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL3 included in the
** packaging of this file. Please review the following information to
** ensure the GNU Lesser General Public License version 3 requirements
** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 2.0 or (at your option) the GNU General
** Public license version 3 or any later version approved by the KDE Free
** Qt Foundation. The licenses are as published by the Free Software
** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
** included in the packaging of this file. Please review the following
** information to ensure the GNU General Public License requirements will
** be met: https://www.gnu.org/licenses/gpl-2.0.html and
** https://www.gnu.org/licenses/gpl-3.0.html.
**
** $QT_END_LICENSE$
**
****************************************************************************/

#include "qdbusmessage.h"
#include "qdbusmessage_p.h"

#include <qdebug.h>
#include <qstringlist.h>

#include "qdbus_symbols_p.h"

#include "qdbusargument_p.h"
#include "qdbuserror.h"
#include "qdbusmetatype.h"
#include "qdbusconnection_p.h"
#include "qdbusutil_p.h"

#ifndef QT_NO_DBUS

QT_BEGIN_NAMESPACE

Q_STATIC_ASSERT(QDBusMessage::InvalidMessage == DBUS_MESSAGE_TYPE_INVALID);
Q_STATIC_ASSERT(QDBusMessage::MethodCallMessage == DBUS_MESSAGE_TYPE_METHOD_CALL);
Q_STATIC_ASSERT(QDBusMessage::ReplyMessage == DBUS_MESSAGE_TYPE_METHOD_RETURN);
Q_STATIC_ASSERT(QDBusMessage::ErrorMessage == DBUS_MESSAGE_TYPE_ERROR);
Q_STATIC_ASSERT(QDBusMessage::SignalMessage == DBUS_MESSAGE_TYPE_SIGNAL);

static inline const char *data(const QByteArray &arr)
{
    return arr.isEmpty() ? nullptr : arr.constData();
}

QDBusMessagePrivate::QDBusMessagePrivate()
    : msg(nullptr), reply(nullptr), localReply(nullptr), ref(1), type(QDBusMessage::InvalidMessage),
      delayedReply(false), localMessage(false),
      parametersValidated(false), autoStartService(true),
      interactiveAuthorizationAllowed(false)
{
}

QDBusMessagePrivate::~QDBusMessagePrivate()
{
    if (msg)
        q_dbus_message_unref(msg);
    if (reply)
        q_dbus_message_unref(reply);
    delete localReply;
}

/*!
    \since 4.3
     Returns the human-readable message associated with the error that was received.
*/
QString QDBusMessage::errorMessage() const
{
    if (d_ptr->type == ErrorMessage) {
        if (!d_ptr->message.isEmpty())
           return d_ptr->message;
        if (!d_ptr->arguments.isEmpty())
            return d_ptr->arguments.at(0).toString();
    }
    return QString();
}

/*!
    \internal
    Constructs a DBusMessage object from \a message. The returned value must be de-referenced
    with q_dbus_message_unref. The \a capabilities flags indicates which capabilities to use.

    The \a error object is set to indicate the error if anything went wrong with the
    marshalling. Usually, this error message will be placed in the reply, as if the call failed.
    The \a error pointer must not be null.
*/
DBusMessage *QDBusMessagePrivate::toDBusMessage(const QDBusMessage &message, QDBusConnection::ConnectionCapabilities capabilities,
                                                QDBusError *error)
{
    if (!qdbus_loadLibDBus()) {
        *error = QDBusError(QDBusError::Failed, QLatin1String("Could not open lidbus-1 library"));
        return nullptr;
    }

    DBusMessage *msg = nullptr;
    const QDBusMessagePrivate *d_ptr = message.d_ptr;

    switch (d_ptr->type) {
    case QDBusMessage::InvalidMessage:
        //qDebug() << "QDBusMessagePrivate::toDBusMessage" <<  "message is invalid";
        break;
    case QDBusMessage::MethodCallMessage:
        // only service and interface can be empty -> path and name must not be empty
        if (!d_ptr->parametersValidated) {
            if (!QDBusUtil::checkBusName(d_ptr->service, QDBusUtil::EmptyAllowed, error))
                return nullptr;
            if (!QDBusUtil::checkObjectPath(d_ptr->path, QDBusUtil::EmptyNotAllowed, error))
                return nullptr;
            if (!QDBusUtil::checkInterfaceName(d_ptr->interface, QDBusUtil::EmptyAllowed, error))
                return nullptr;
            if (!QDBusUtil::checkMemberName(d_ptr->name, QDBusUtil::EmptyNotAllowed, error, "method"))
                return nullptr;
        }

        msg = q_dbus_message_new_method_call(data(d_ptr->service.toUtf8()), d_ptr->path.toUtf8(),
                                             data(d_ptr->interface.toUtf8()), d_ptr->name.toUtf8());
        q_dbus_message_set_auto_start( msg, d_ptr->autoStartService );
        q_dbus_message_set_allow_interactive_authorization(msg, d_ptr->interactiveAuthorizationAllowed);

        break;
    case QDBusMessage::ReplyMessage:
        msg = q_dbus_message_new(DBUS_MESSAGE_TYPE_METHOD_RETURN);
        if (!d_ptr->localMessage) {
            q_dbus_message_set_destination(msg, q_dbus_message_get_sender(d_ptr->reply));
            q_dbus_message_set_reply_serial(msg, q_dbus_message_get_serial(d_ptr->reply));
        }
        break;
    case QDBusMessage::ErrorMessage:
        // error name can't be empty
        if (!d_ptr->parametersValidated
            && !QDBusUtil::checkErrorName(d_ptr->name, QDBusUtil::EmptyNotAllowed, error))
            return nullptr;

        msg = q_dbus_message_new(DBUS_MESSAGE_TYPE_ERROR);
        q_dbus_message_set_error_name(msg, d_ptr->name.toUtf8());
        if (!d_ptr->localMessage) {
            q_dbus_message_set_destination(msg, q_dbus_message_get_sender(d_ptr->reply));
            q_dbus_message_set_reply_serial(msg, q_dbus_message_get_serial(d_ptr->reply));
        }
        break;
    case QDBusMessage::SignalMessage:
        // only the service name can be empty here
        if (!d_ptr->parametersValidated) {
            if (!QDBusUtil::checkBusName(d_ptr->service, QDBusUtil::EmptyAllowed, error))
                return nullptr;
            if (!QDBusUtil::checkObjectPath(d_ptr->path, QDBusUtil::EmptyNotAllowed, error))
                return nullptr;
            if (!QDBusUtil::checkInterfaceName(d_ptr->interface, QDBusUtil::EmptyAllowed, error))
                return nullptr;
            if (!QDBusUtil::checkMemberName(d_ptr->name, QDBusUtil::EmptyNotAllowed, error, "method"))
                return nullptr;
        }

        msg = q_dbus_message_new_signal(d_ptr->path.toUtf8(), d_ptr->interface.toUtf8(),
                                        d_ptr->name.toUtf8());
        q_dbus_message_set_destination(msg, data(d_ptr->service.toUtf8()));
        break;
    }

    // if we got here, the parameters validated
    // and since the message parameters cannot be changed once the message is created
    // we can record this fact
    d_ptr->parametersValidated = true;

    QDBusMarshaller marshaller(capabilities);
    QVariantList::ConstIterator it =  d_ptr->arguments.constBegin();
    QVariantList::ConstIterator cend = d_ptr->arguments.constEnd();
    q_dbus_message_iter_init_append(msg, &marshaller.iterator);
    if (!d_ptr->message.isEmpty())
        // prepend the error message
        marshaller.append(d_ptr->message);
    for ( ; it != cend; ++it)
        marshaller.appendVariantInternal(*it);

    // check if everything is ok
    if (marshaller.ok)
        return msg;

    // not ok;
    q_dbus_message_unref(msg);
    *error = QDBusError(QDBusError::Failed, QLatin1String("Marshalling failed: ") + marshaller.errorString);
    return nullptr;
}

/*
struct DBusMessage
{
    DBusAtomic refcount;
    DBusHeader header;
    DBusString body;
    char byte_order;
    unsigned int locked : 1;
DBUS_DISABLE_CHECKS
    unsigned int in_cache : 1;
#endif
    DBusList *size_counters;
    long size_counter_delta;
    dbus_uint32_t changed_stamp : CHANGED_STAMP_BITS;
    DBusDataSlotList slot_list;
#ifndef DBUS_DISABLE_CHECKS
    int generation;
#endif
};
*/

/*!
    \internal
    Constructs a QDBusMessage by parsing the given DBusMessage object.
*/
QDBusMessage QDBusMessagePrivate::fromDBusMessage(DBusMessage *dmsg, QDBusConnection::ConnectionCapabilities capabilities)
{
    QDBusMessage message;
    if (!dmsg)
        return message;

    message.d_ptr->type = QDBusMessage::MessageType(q_dbus_message_get_type(dmsg));
    message.d_ptr->path = QString::fromUtf8(q_dbus_message_get_path(dmsg));
    message.d_ptr->interface = QString::fromUtf8(q_dbus_message_get_interface(dmsg));
    message.d_ptr->name = message.d_ptr->type == DBUS_MESSAGE_TYPE_ERROR ?
                      QString::fromUtf8(q_dbus_message_get_error_name(dmsg)) :
                      QString::fromUtf8(q_dbus_message_get_member(dmsg));
    message.d_ptr->service = QString::fromUtf8(q_dbus_message_get_sender(dmsg));
    message.d_ptr->signature = QString::fromUtf8(q_dbus_message_get_signature(dmsg));
    message.d_ptr->interactiveAuthorizationAllowed = q_dbus_message_get_allow_interactive_authorization(dmsg);
    message.d_ptr->msg = q_dbus_message_ref(dmsg);

    QDBusDemarshaller demarshaller(capabilities);
    demarshaller.message = q_dbus_message_ref(dmsg);
    if (q_dbus_message_iter_init(demarshaller.message, &demarshaller.iterator))
        while (!demarshaller.atEnd())
            message << demarshaller.toVariantInternal();
    return message;
}

bool QDBusMessagePrivate::isLocal(const QDBusMessage &message)
{
    return message.d_ptr->localMessage;
}

QDBusMessage QDBusMessagePrivate::makeLocal(const QDBusConnectionPrivate &conn,
                                            const QDBusMessage &asSent)
{
    // simulate the message being sent to the bus and then received back
    // the only field that the bus sets when delivering the message
    // (as opposed to the message as we send it), is the sender
    // so we simply set the sender to our unique name

    // determine if we are carrying any complex types
    QString computedSignature;
    QVariantList::ConstIterator it = asSent.d_ptr->arguments.constBegin();
    QVariantList::ConstIterator end = asSent.d_ptr->arguments.constEnd();
    for ( ; it != end; ++it) {
        int id = it->userType();
        const char *signature = QDBusMetaType::typeToSignature(id);
        if ((id != QMetaType::QStringList && id != QMetaType::QByteArray &&
             qstrlen(signature) != 1) || id == qMetaTypeId<QDBusVariant>()) {
            // yes, we are
            // we must marshall and demarshall again so as to create QDBusArgument
            // entries for the complex types
            QDBusError error;
            DBusMessage *message = toDBusMessage(asSent, conn.connectionCapabilities(), &error);
            if (!message) {
                // failed to marshall, so it's a call error
                return QDBusMessage::createError(error);
            }

            q_dbus_message_set_sender(message, conn.baseService.toUtf8());

            QDBusMessage retval = fromDBusMessage(message, conn.connectionCapabilities());
            retval.d_ptr->localMessage = true;
            q_dbus_message_unref(message);
            if (retval.d_ptr->service.isEmpty())
                retval.d_ptr->service = conn.baseService;
            return retval;
        } else {
            computedSignature += QLatin1String(signature);
        }
    }

    // no complex types seen
    // optimize by using the variant list itself
    QDBusMessage retval;
    QDBusMessagePrivate *d = retval.d_ptr;
    d->arguments = asSent.d_ptr->arguments;
    d->path = asSent.d_ptr->path;
    d->interface = asSent.d_ptr->interface;
    d->name = asSent.d_ptr->name;
    d->message = asSent.d_ptr->message;
    d->type = asSent.d_ptr->type;

    d->service = conn.baseService;
    d->signature = computedSignature;
    d->localMessage = true;
    return retval;
}

QDBusMessage QDBusMessagePrivate::makeLocalReply(const QDBusConnectionPrivate &conn,
                                                 const QDBusMessage &callMsg)
{
    // simulate the reply (return or error) message being sent to the bus and
    // then received back.
    if (callMsg.d_ptr->localReply)
        return makeLocal(conn, *callMsg.d_ptr->localReply);
    return QDBusMessage();      // failed
}

/*!
    \class QDBusMessage
    \inmodule QtDBus
    \since 4.2

    \brief The QDBusMessage class represents one message sent or
    received over the D-Bus bus.

    This object can represent any of the four different types of
    messages (MessageType) that can occur on the bus:

    \list
      \li Method calls
      \li Method return values
      \li Signal emissions
      \li Error codes
    \endlist

    Objects of this type are created with the static createError(),
    createMethodCall() and createSignal() functions. Use the
    QDBusConnection::send() function to send the messages.
*/

/*!
    \enum QDBusMessage::MessageType
    The possible message types:

    \value MethodCallMessage    a message representing an outgoing or incoming method call
    \value SignalMessage        a message representing an outgoing or incoming signal emission
    \value ReplyMessage         a message representing the return values of a method call
    \value ErrorMessage         a message representing an error condition in response to a method call
    \value InvalidMessage       an invalid message: this is never set on messages received from D-Bus
*/

/*!
    Constructs a new DBus message with the given \a path, \a interface
    and \a name, representing a signal emission.

    A DBus signal is emitted from one application and is received by
    all applications that are listening for that signal from that
    interface.

    The QDBusMessage object that is returned can be sent using the
    QDBusConnection::send() function.
*/
QDBusMessage QDBusMessage::createSignal(const QString &path, const QString &interface,
                                        const QString &name)
{
    QDBusMessage message;
    message.d_ptr->type = SignalMessage;
    message.d_ptr->path = path;
    message.d_ptr->interface = interface;
    message.d_ptr->name = name;

    return message;
}

/*!
    \since 5.6

    Constructs a new DBus message with the given \a path, \a interface
    and \a name, representing a signal emission to a specific destination.

    A DBus signal is emitted from one application and is received only by
    the application owning the destination \a service name.

    The QDBusMessage object that is returned can be sent using the
    QDBusConnection::send() function.
*/
QDBusMessage QDBusMessage::createTargetedSignal(const QString &service, const QString &path,
                                                const QString &interface, const QString &name)
{
    QDBusMessage message;
    message.d_ptr->type = SignalMessage;
    message.d_ptr->service = service;
    message.d_ptr->path = path;
    message.d_ptr->interface = interface;
    message.d_ptr->name = name;

    return message;
}

/*!
    Constructs a new DBus message representing a method call.
    A method call always informs its destination address
    (\a service, \a path, \a interface and \a method).

    The DBus bus allows calling a method on a given remote object without specifying the
    destination interface, if the method name is unique. However, if two interfaces on the
    remote object export the same method name, the result is undefined (one of the two may be
    called or an error may be returned).

    When using DBus in a peer-to-peer context (i.e., not on a bus), the \a service parameter is
    optional.

    The QDBusInterface class provides a simpler abstraction to synchronous
    method calling.

    This function returns a QDBusMessage object that can be sent with
    QDBusConnection::call().
*/
QDBusMessage QDBusMessage::createMethodCall(const QString &service, const QString &path,
                                            const QString &interface, const QString &method)
{
    QDBusMessage message;
    message.d_ptr->type = MethodCallMessage;
    message.d_ptr->service = service;
    message.d_ptr->path = path;
    message.d_ptr->interface = interface;
    message.d_ptr->name = method;

    return message;
}

/*!
    Constructs a new DBus message representing an error,
    with the given \a name and \a msg.
*/
QDBusMessage QDBusMessage::createError(const QString &name, const QString &msg)
{
    QDBusMessage error;
    error.d_ptr->type = ErrorMessage;
    error.d_ptr->name = name;
    error.d_ptr->message = msg;

    return error;
}

/*!
    \fn QDBusMessage QDBusMessage::createError(const QDBusError &error)

    Constructs a new DBus message representing the given \a error.
*/

/*!
  \fn QDBusMessage QDBusMessage::createError(QDBusError::ErrorType type, const QString &msg)

  Constructs a new DBus message for the error type \a type using
  the message \a msg. Returns the DBus message.
*/

/*!
    \fn QDBusMessage QDBusMessage::createReply(const QList<QVariant> &arguments) const

    Constructs a new DBus message representing a reply, with the given
    \a arguments.
*/
QDBusMessage QDBusMessage::createReply(const QVariantList &arguments) const
{
    QDBusMessage reply;
    reply.setArguments(arguments);
    reply.d_ptr->type = ReplyMessage;
    if (d_ptr->msg)
        reply.d_ptr->reply = q_dbus_message_ref(d_ptr->msg);
    if (d_ptr->localMessage) {
        reply.d_ptr->localMessage = true;
        d_ptr->localReply = new QDBusMessage(reply); // keep an internal copy
    }

    // the reply must have a msg or be a local-loop optimization
    Q_ASSERT(reply.d_ptr->reply || reply.d_ptr->localMessage);
    return reply;
}

/*!
    Constructs a new DBus message representing an error reply message,
    with the given \a name and \a msg.
*/
#if QT_VERSION >= QT_VERSION_CHECK(6,0,0)
QDBusMessage QDBusMessage::createErrorReply(const QString &name, const QString &msg) const
#else
QDBusMessage QDBusMessage::createErrorReply(const QString name, const QString &msg) const
#endif
{
    QDBusMessage reply = QDBusMessage::createError(name, msg);
    if (d_ptr->msg)
        reply.d_ptr->reply = q_dbus_message_ref(d_ptr->msg);
    if (d_ptr->localMessage) {
        reply.d_ptr->localMessage = true;
        d_ptr->localReply = new QDBusMessage(reply); // keep an internal copy
    }

    // the reply must have a msg or be a local-loop optimization
    Q_ASSERT(reply.d_ptr->reply || reply.d_ptr->localMessage);
    return reply;
}

/*!
   \fn QDBusMessage QDBusMessage::createReply(const QVariant &argument) const

    Constructs a new DBus message representing a reply, with the
    given \a argument.
*/

/*!
    \fn QDBusMessage QDBusMessage::createErrorReply(const QDBusError &error) const

    Constructs a new DBus message representing an error reply message,
    from the given \a error object.
*/

/*!
  \fn QDBusMessage QDBusMessage::createErrorReply(QDBusError::ErrorType type, const QString &msg) const

  Constructs a new DBus reply message for the error type \a type using
  the message \a msg. Returns the DBus message.
*/
QDBusMessage QDBusMessage::createErrorReply(QDBusError::ErrorType atype, const QString &amsg) const
{
    QDBusMessage msg = createErrorReply(QDBusError::errorString(atype), amsg);
    msg.d_ptr->parametersValidated = true;
    return msg;
}


/*!
    Constructs an empty, invalid QDBusMessage object.

    \sa createError(), createMethodCall(), createSignal()
*/
QDBusMessage::QDBusMessage()
{
    d_ptr = new QDBusMessagePrivate;
}

/*!
    Constructs a copy of the object given by \a other.

    Note: QDBusMessage objects are shared. Modifications made to the
    copy will affect the original one as well. See setDelayedReply()
    for more information.
*/
QDBusMessage::QDBusMessage(const QDBusMessage &other)
{
    d_ptr = other.d_ptr;
    d_ptr->ref.ref();
}

/*!
    Disposes of the object and frees any resources that were being held.
*/
QDBusMessage::~QDBusMessage()
{
    if (!d_ptr->ref.deref())
        delete d_ptr;
}

/*!
    Copies the contents of the object given by \a other.

    Note: QDBusMessage objects are shared. Modifications made to the
    copy will affect the original one as well. See setDelayedReply()
    for more information.
*/
QDBusMessage &QDBusMessage::operator=(const QDBusMessage &other)
{
    qAtomicAssign(d_ptr, other.d_ptr);
    return *this;
}

/*!
    Returns the name of the service or the bus address of the remote method call.
*/
QString QDBusMessage::service() const
{
    return d_ptr->service;
}

/*!
    Returns the path of the object that this message is being sent to (in the case of a
    method call) or being received from (for a signal).
*/
QString QDBusMessage::path() const
{
    return d_ptr->path;
}

/*!
    Returns the interface of the method being called (in the case of a method call) or of
    the signal being received from.
*/
QString QDBusMessage::interface() const
{
    return d_ptr->interface;
}

/*!
    Returns the name of the signal that was emitted or the name of the method that was called.
*/
QString QDBusMessage::member() const
{
    if (d_ptr->type != ErrorMessage)
        return d_ptr->name;
    return QString();
}

/*!
    Returns the name of the error that was received.
*/
QString QDBusMessage::errorName() const
{
    if (d_ptr->type == ErrorMessage)
        return d_ptr->name;
    return QString();
}

/*!
    Returns the signature of the signal that was received or for the output arguments
    of a method call.
*/
QString QDBusMessage::signature() const
{
    return d_ptr->signature;
}

/*!
    Returns the flag that indicates if this message should see a reply
    or not. This is only meaningful for \l {MethodCallMessage}{method
    call messages}: any other kind of message cannot have replies and
    this function will always return false for them.
*/
bool QDBusMessage::isReplyRequired() const
{
    // Only method calls can have replies
    if (d_ptr->type != QDBusMessage::MethodCallMessage)
        return false;

    if (!d_ptr->msg)
        return d_ptr->localMessage; // if it's a local message, reply is required
    return !q_dbus_message_get_no_reply(d_ptr->msg);
}

/*!
    Sets whether the message will be replied later (if \a enable is
    true) or if an automatic reply should be generated by Qt D-Bus
    (if \a enable is false).

    In D-Bus, all method calls must generate a reply to the caller, unless the
    caller explicitly indicates otherwise (see isReplyRequired()). QtDBus
    automatically generates such replies for any slots being called, but it
    also allows slots to indicate whether they will take responsibility
    of sending the reply at a later time, after the function has finished
    processing.

    \sa {Delayed Replies}
*/
void QDBusMessage::setDelayedReply(bool enable) const
{
    d_ptr->delayedReply = enable;
}

/*!
    Returns the delayed reply flag, as set by setDelayedReply(). By default, this
    flag is false, which means Qt D-Bus will generate automatic replies
    when necessary.
*/
bool QDBusMessage::isDelayedReply() const
{
    return d_ptr->delayedReply;
}

/*!
    Sets the auto start flag to \a enable. This flag only makes sense
    for method call messages, where it tells the D-Bus server to
    either auto start the service responsible for the service name, or
    not to auto start it.

    By default this flag is true, i.e. a service is autostarted.
    This means:

    When the service that this method call is sent to is already
    running, the method call is sent to it. If the service is not
    running yet, the D-Bus daemon is requested to autostart the
    service that is assigned to this service name. This is
    handled by .service files that are placed in a directory known
    to the D-Bus server. These files then each contain a service
    name and the path to a program that should be executed when
    this service name is requested.

    \since 4.7
*/
void QDBusMessage::setAutoStartService(bool enable)
{
    d_ptr->autoStartService = enable;
}

/*!
    Returns the auto start flag, as set by setAutoStartService(). By default, this
    flag is true, which means Qt D-Bus will auto start a service, if it is
    not running already.

    \sa setAutoStartService()

    \since 4.7
*/
bool QDBusMessage::autoStartService() const
{
    return d_ptr->autoStartService;
}

/*!
    Sets the interactive authorization flag to \a enable.
    This flag only makes sense for method call messages, where it
    tells the D-Bus server that the caller of the method is prepared
    to wait for interactive authorization to take place (for instance
    via Polkit) before the actual method is processed.

    By default this flag is false and the other end is expected to
    make any authorization decisions non-interactively and promptly.

    The \c org.freedesktop.DBus.Error.InteractiveAuthorizationRequired
    error indicates that authorization failed, but could have succeeded
    if this flag had been set.

    \sa isInteractiveAuthorizationAllowed()

    \since 5.12
*/
void QDBusMessage::setInteractiveAuthorizationAllowed(bool enable)
{
    d_ptr->interactiveAuthorizationAllowed = enable;
}

/*!
    Returns the interactive authorization allowed flag, as set by
    setInteractiveAuthorizationAllowed(). By default this flag
    is false and the other end is expected to make any authorization
    decisions non-interactively and promptly.

    \sa setInteractiveAuthorizationAllowed()

    \since 5.12
*/
bool QDBusMessage::isInteractiveAuthorizationAllowed() const
{
    return d_ptr->interactiveAuthorizationAllowed;
}

/*!
    Sets the arguments that are going to be sent over D-Bus to \a arguments. Those
    will be the arguments to a method call or the parameters in the signal.

    \sa arguments()
*/
void QDBusMessage::setArguments(const QList<QVariant> &arguments)
{
    // FIXME: should we detach?
    d_ptr->arguments = arguments;
}

/*!
    Returns the list of arguments that are going to be sent or were received from
    D-Bus.
*/
QList<QVariant> QDBusMessage::arguments() const
{
    return d_ptr->arguments;
}

/*!
    Appends the argument \a arg to the list of arguments to be sent over D-Bus in
    a method call or signal emission.
*/

QDBusMessage &QDBusMessage::operator<<(const QVariant &arg)
{
    // FIXME: should we detach?
    d_ptr->arguments.append(arg);
    return *this;
}

/*!
    Returns the message type.
*/
QDBusMessage::MessageType QDBusMessage::type() const
{
    switch (d_ptr->type) {
    case DBUS_MESSAGE_TYPE_METHOD_CALL:
        return MethodCallMessage;
    case DBUS_MESSAGE_TYPE_METHOD_RETURN:
        return ReplyMessage;
    case DBUS_MESSAGE_TYPE_ERROR:
        return ErrorMessage;
    case DBUS_MESSAGE_TYPE_SIGNAL:
        return SignalMessage;
    default:
        break;
    }
    return InvalidMessage;
}

#ifndef QT_NO_DEBUG_STREAM
static QDebug operator<<(QDebug dbg, QDBusMessage::MessageType t)
{
    switch (t)
    {
    case QDBusMessage::MethodCallMessage:
        return dbg << "MethodCall";
    case QDBusMessage::ReplyMessage:
        return dbg << "MethodReturn";
    case QDBusMessage::SignalMessage:
        return dbg << "Signal";
    case QDBusMessage::ErrorMessage:
        return dbg << "Error";
    default:
        return dbg << "Invalid";
    }
}

static void debugVariantList(QDebug dbg, const QVariantList &list)
{
    bool first = true;
    QVariantList::ConstIterator it = list.constBegin();
    QVariantList::ConstIterator end = list.constEnd();
    for ( ; it != end; ++it) {
        if (!first)
            dbg.nospace() << ", ";
        dbg.nospace() << qPrintable(QDBusUtil::argumentToString(*it));
        first = false;
    }
}

QDebug operator<<(QDebug dbg, const QDBusMessage &msg)
{
    QDebugStateSaver saver(dbg);
    dbg.nospace() << "QDBusMessage(type=" << msg.type()
                  << ", service=" << msg.service();
    if (msg.type() == QDBusMessage::MethodCallMessage ||
        msg.type() == QDBusMessage::SignalMessage)
        dbg.nospace() << ", path=" << msg.path()
                      << ", interface=" << msg.interface()
                      << ", member=" << msg.member();
    if (msg.type() == QDBusMessage::ErrorMessage)
        dbg.nospace() << ", error name=" << msg.errorName()
                      << ", error message=" << msg.errorMessage();
    dbg.nospace() << ", signature=" << msg.signature()
                  << ", contents=(";
    debugVariantList(dbg, msg.arguments());
    dbg.nospace() << ") )";
    return dbg;
}
#endif

/*!
    \fn void QDBusMessage::swap(QDBusMessage &other)

    Swaps this QDBusMessage instance with \a other.
*/

QT_END_NAMESPACE

#endif // QT_NO_DBUS
