/****************************************************************************
**
** 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() ? 0 : arr.constData();
}

QDBusMessagePrivate::QDBusMessagePrivate()
    : msg(0), reply(0), localReply(0), 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 0;
    }

    DBusMessage *msg = 0;
    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 0;
            if (!QDBusUtil::checkObjectPath(d_ptr->path, QDBusUtil::EmptyNotAllowed, error))
                return 0;
            if (!QDBusUtil::checkInterfaceName(d_ptr->interface, QDBusUtil::EmptyAllowed, error))
                return 0;
            if (!QDBusUtil::checkMemberName(d_ptr->name, QDBusUtil::EmptyNotAllowed, error, "method"))
                return 0;
        }

        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 0;

        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 0;
            if (!QDBusUtil::checkObjectPath(d_ptr->path, QDBusUtil::EmptyNotAllowed, error))
                return 0;
            if (!QDBusUtil::checkInterfaceName(d_ptr->interface, QDBusUtil::EmptyAllowed, error))
                return 0;
            if (!QDBusUtil::checkMemberName(d_ptr->name, QDBusUtil::EmptyNotAllowed, error, "method"))
                return 0;
        }

        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 0;
}

/*
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 != QVariant::StringList && id != QVariant::ByteArray &&
             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.capabilities, &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.capabilities);
            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
