/****************************************************************************
**
** 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 "qdbusabstractinterface.h"
#include "qdbusabstractinterface_p.h"

#include <qcoreapplication.h>
#include <qthread.h>

#include "qdbusargument.h"
#include "qdbuspendingcall.h"
#include "qdbusmessage_p.h"
#include "qdbusmetaobject_p.h"
#include "qdbusmetatype_p.h"
#include "qdbusservicewatcher.h"
#include "qdbusutil_p.h"

#include <qdebug.h>

#ifndef QT_NO_DBUS

QT_BEGIN_NAMESPACE

namespace {
// ### Qt6: change to a regular QEvent (customEvent)
// We need to use a QMetaCallEvent here because we can't override customEvent() in
// Qt 5. Since QDBusAbstractInterface is meant to be derived from, the vtables of
// classes in generated code will have a pointer to QObject::customEvent instead
// of to QDBusAbstractInterface::customEvent.
// See solution in Patch Set 1 of this change in the Qt Gerrit servers.
// (https://codereview.qt-project.org/#/c/126384/1)
class DisconnectRelayEvent : public QAbstractMetaCallEvent
{
public:
    DisconnectRelayEvent(QObject *sender, const QMetaMethod &m)
        : QAbstractMetaCallEvent(sender, m.methodIndex())
    {}

    void placeMetaCall(QObject *object) override
    {
        QDBusAbstractInterface *iface = static_cast<QDBusAbstractInterface *>(object);
        QDBusAbstractInterfacePrivate::finishDisconnectNotify(iface, signalId());
    }
};
}

static QDBusError checkIfValid(const QString &service, const QString &path,
                               const QString &interface, bool isDynamic, bool isPeer)
{
    // We should be throwing exceptions here... oh well
    QDBusError error;

    // dynamic interfaces (QDBusInterface) can have empty interfaces, but not service and object paths
    // non-dynamic is the opposite: service and object paths can be empty, but not the interface
    if (!isDynamic) {
        // use assertion here because this should never happen, at all
        Q_ASSERT_X(!interface.isEmpty(), "QDBusAbstractInterface", "Interface name cannot be empty");
    }
    if (!QDBusUtil::checkBusName(service, (isDynamic && !isPeer) ? QDBusUtil::EmptyNotAllowed : QDBusUtil::EmptyAllowed, &error))
        return error;
    if (!QDBusUtil::checkObjectPath(path, isDynamic ? QDBusUtil::EmptyNotAllowed : QDBusUtil::EmptyAllowed, &error))
        return error;
    if (!QDBusUtil::checkInterfaceName(interface, QDBusUtil::EmptyAllowed, &error))
        return error;

    // no error
    return QDBusError();
}

QDBusAbstractInterfacePrivate::QDBusAbstractInterfacePrivate(const QString &serv,
                                                             const QString &p,
                                                             const QString &iface,
                                                             const QDBusConnection& con,
                                                             bool isDynamic)
    : connection(con), service(serv), path(p), interface(iface),
      lastError(checkIfValid(serv, p, iface, isDynamic, (connectionPrivate() &&
                                                         connectionPrivate()->mode == QDBusConnectionPrivate::PeerMode))),
      timeout(-1),
      isValid(!lastError.isValid())
{
    if (!isValid)
        return;

    if (!connection.isConnected()) {
        lastError = QDBusError(QDBusError::Disconnected,
                               QDBusUtil::disconnectedErrorMessage());
    }
}

void QDBusAbstractInterfacePrivate::initOwnerTracking()
{
    if (!isValid || !connection.isConnected() || !connectionPrivate()->shouldWatchService(service))
        return;

    QObject::connect(new QDBusServiceWatcher(service, connection, QDBusServiceWatcher::WatchForOwnerChange, q_func()),
                     SIGNAL(serviceOwnerChanged(QString,QString,QString)),
                     q_func(), SLOT(_q_serviceOwnerChanged(QString,QString,QString)));

    currentOwner = connectionPrivate()->getNameOwner(service);
    if (currentOwner.isEmpty())
        lastError = connectionPrivate()->lastError;
}

bool QDBusAbstractInterfacePrivate::canMakeCalls() const
{
    // recheck only if we have a wildcard (i.e. empty) service or path
    // if any are empty, set the error message according to QDBusUtil
    if (service.isEmpty() && connectionPrivate()->mode != QDBusConnectionPrivate::PeerMode)
        return QDBusUtil::checkBusName(service, QDBusUtil::EmptyNotAllowed, &lastError);
    if (path.isEmpty())
        return QDBusUtil::checkObjectPath(path, QDBusUtil::EmptyNotAllowed, &lastError);
    return true;
}

bool QDBusAbstractInterfacePrivate::property(const QMetaProperty &mp, void *returnValuePtr) const
{
    if (!isValid || !canMakeCalls())   // can't make calls
        return false;

    const int type = mp.userType();
    // is this metatype registered?
    const char *expectedSignature = "";
    if (int(mp.userType()) != QMetaType::QVariant) {
        expectedSignature = QDBusMetaType::typeToSignature(type);
        if (expectedSignature == nullptr) {
            qWarning("QDBusAbstractInterface: type %s must be registered with Qt D-Bus before it can be "
                     "used to read property %s.%s",
                     mp.typeName(), qPrintable(interface), mp.name());
            lastError = QDBusError(QDBusError::Failed,
                                   QLatin1String("Unregistered type %1 cannot be handled")
                                   .arg(QLatin1String(mp.typeName())));
            return false;
        }
    }

    // try to read this property
    QDBusMessage msg = QDBusMessage::createMethodCall(service, path,
                                                      QDBusUtil::dbusInterfaceProperties(),
                                                      QStringLiteral("Get"));
    QDBusMessagePrivate::setParametersValidated(msg, true);
    msg << interface << QString::fromUtf8(mp.name());
    QDBusMessage reply = connection.call(msg, QDBus::Block, timeout);

    if (reply.type() != QDBusMessage::ReplyMessage) {
        lastError = QDBusError(reply);
        return false;
    }
    if (reply.signature() != QLatin1String("v")) {
        QString errmsg = QLatin1String("Invalid signature `%1' in return from call to "
                                       DBUS_INTERFACE_PROPERTIES);
        lastError = QDBusError(QDBusError::InvalidSignature, std::move(errmsg).arg(reply.signature()));
        return false;
    }

    QByteArray foundSignature;
    const char *foundType = nullptr;
    QVariant value = qvariant_cast<QDBusVariant>(reply.arguments().at(0)).variant();

    if (value.userType() == type || type == QMetaType::QVariant
        || (expectedSignature[0] == 'v' && expectedSignature[1] == '\0')) {
        // simple match
        if (type == QMetaType::QVariant) {
            *reinterpret_cast<QVariant*>(returnValuePtr) = value;
        } else {
            QMetaType::destruct(type, returnValuePtr);
            QMetaType::construct(type, returnValuePtr, value.constData());
        }
        return true;
    }

    if (value.userType() == qMetaTypeId<QDBusArgument>()) {
        QDBusArgument arg = qvariant_cast<QDBusArgument>(value);

        foundType = "user type";
        foundSignature = arg.currentSignature().toLatin1();
        if (foundSignature == expectedSignature) {
            // signatures match, we can demarshall
            return QDBusMetaType::demarshall(arg, type, returnValuePtr);
        }
    } else {
        foundType = value.typeName();
        foundSignature = QDBusMetaType::typeToSignature(value.userType());
    }

    // there was an error...
    const auto errmsg = QLatin1String("Unexpected `%1' (%2) when retrieving property `%3.%4' "
                                      "(expected type `%5' (%6))");
    lastError = QDBusError(QDBusError::InvalidSignature,
                           errmsg.arg(QLatin1String(foundType),
                                      QLatin1String(foundSignature),
                                      interface,
                                      QLatin1String(mp.name()),
                                      QLatin1String(mp.typeName()),
                                      QLatin1String(expectedSignature)));
    return false;
}

bool QDBusAbstractInterfacePrivate::setProperty(const QMetaProperty &mp, const QVariant &value)
{
    if (!isValid || !canMakeCalls())    // can't make calls
        return false;

    // send the value
    QDBusMessage msg = QDBusMessage::createMethodCall(service, path,
                                                      QDBusUtil::dbusInterfaceProperties(),
                                                      QStringLiteral("Set"));
    QDBusMessagePrivate::setParametersValidated(msg, true);
    msg << interface << QString::fromUtf8(mp.name()) << QVariant::fromValue(QDBusVariant(value));
    QDBusMessage reply = connection.call(msg, QDBus::Block, timeout);

    if (reply.type() != QDBusMessage::ReplyMessage) {
        lastError = QDBusError(reply);
        return false;
    }
    return true;
}

void QDBusAbstractInterfacePrivate::_q_serviceOwnerChanged(const QString &name,
                                                           const QString &oldOwner,
                                                           const QString &newOwner)
{
    Q_UNUSED(oldOwner);
    Q_UNUSED(name);
    //qDebug() << "QDBusAbstractInterfacePrivate serviceOwnerChanged" << name << oldOwner << newOwner;
    Q_ASSERT(name == service);
    currentOwner = newOwner;
}

QDBusAbstractInterfaceBase::QDBusAbstractInterfaceBase(QDBusAbstractInterfacePrivate &d, QObject *parent)
    : QObject(d, parent)
{
}

int QDBusAbstractInterfaceBase::qt_metacall(QMetaObject::Call _c, int _id, void **_a)
{
    int saved_id = _id;
    _id = QObject::qt_metacall(_c, _id, _a);
    if (_id < 0)
        return _id;

    if (_c == QMetaObject::ReadProperty || _c == QMetaObject::WriteProperty) {
        QMetaProperty mp = metaObject()->property(saved_id);
        int &status = *reinterpret_cast<int *>(_a[2]);

        if (_c == QMetaObject::WriteProperty) {
            QVariant value;
            if (mp.userType() == qMetaTypeId<QDBusVariant>())
                value = reinterpret_cast<const QDBusVariant*>(_a[0])->variant();
            else
                value = QVariant(mp.userType(), _a[0]);
            status = d_func()->setProperty(mp, value) ? 1 : 0;
        } else {
            bool readStatus = d_func()->property(mp, _a[0]);
            // Caller supports QVariant returns? Then we can also report errors
            // by storing an invalid variant.
            if (!readStatus && _a[1]) {
                status = 0;
                reinterpret_cast<QVariant*>(_a[1])->clear();
            }
        }
        _id = -1;
    }
    return _id;
}

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

    \brief The QDBusAbstractInterface class is the base class for all D-Bus interfaces in the Qt D-Bus binding, allowing access to remote interfaces.

    Generated-code classes also derive from QDBusAbstractInterface,
    all methods described here are also valid for generated-code
    classes. In addition to those described here, generated-code
    classes provide member functions for the remote methods, which
    allow for compile-time checking of the correct parameters and
    return values, as well as property type-matching and signal
    parameter-matching.

    \sa {qdbusxml2cpp.html}{The QDBus compiler}, QDBusInterface
*/

/*!
    \internal
    This is the constructor called from QDBusInterface::QDBusInterface.
*/
QDBusAbstractInterface::QDBusAbstractInterface(QDBusAbstractInterfacePrivate &d, QObject *parent)
    : QDBusAbstractInterfaceBase(d, parent)
{
    d.initOwnerTracking();
}

/*!
    \internal
    This is the constructor called from static classes derived from
    QDBusAbstractInterface (i.e., those generated by dbusxml2cpp).
*/
QDBusAbstractInterface::QDBusAbstractInterface(const QString &service, const QString &path,
                                               const char *interface, const QDBusConnection &con,
                                               QObject *parent)
    : QDBusAbstractInterfaceBase(*new QDBusAbstractInterfacePrivate(service, path, QString::fromLatin1(interface),
                                                 con, false), parent)
{
    // keep track of the service owner
    d_func()->initOwnerTracking();
}

/*!
    Releases this object's resources.
*/
QDBusAbstractInterface::~QDBusAbstractInterface()
{
}

/*!
    Returns \c true if this is a valid reference to a remote object. It returns \c false if
    there was an error during the creation of this interface (for instance, if the remote
    application does not exist).

    Note: when dealing with remote objects, it is not always possible to determine if it
    exists when creating a QDBusInterface.
*/
bool QDBusAbstractInterface::isValid() const
{
    Q_D(const QDBusAbstractInterface);
    /* We don't retrieve the owner name for peer connections */
    if (d->connectionPrivate() && d->connectionPrivate()->mode == QDBusConnectionPrivate::PeerMode) {
        return d->isValid;
    } else {
        return !d->currentOwner.isEmpty();
    }
}

/*!
    Returns the connection this interface is associated with.
*/
QDBusConnection QDBusAbstractInterface::connection() const
{
    return d_func()->connection;
}

/*!
    Returns the name of the service this interface is associated with.
*/
QString QDBusAbstractInterface::service() const
{
    return d_func()->service;
}

/*!
    Returns the object path that this interface is associated with.
*/
QString QDBusAbstractInterface::path() const
{
    return d_func()->path;
}

/*!
    Returns the name of this interface.
*/
QString QDBusAbstractInterface::interface() const
{
    return d_func()->interface;
}

/*!
    Returns the error the last operation produced, or an invalid error if the last operation did not
    produce an error.
*/
QDBusError QDBusAbstractInterface::lastError() const
{
    return d_func()->lastError;
}

/*!
    Sets the timeout in milliseconds for all future DBus calls to \a timeout.
    -1 means the default DBus timeout (usually 25 seconds).

    \since 4.8
*/
void QDBusAbstractInterface::setTimeout(int timeout)
{
    d_func()->timeout = timeout;
}

/*!
    Returns the current value of the timeout in milliseconds.
    -1 means the default DBus timeout (usually 25 seconds).

    \since 4.8
*/
int QDBusAbstractInterface::timeout() const
{
    return d_func()->timeout;
}

/*!
    Places a call to the remote method specified by \a method on this interface, using \a args as
    arguments. This function returns the message that was received as a reply, which can be a normal
    QDBusMessage::ReplyMessage (indicating success) or QDBusMessage::ErrorMessage (if the call
    failed). The \a mode parameter specifies how this call should be placed.

    If the call succeeds, lastError() will be cleared; otherwise, it will contain the error this
    call produced.

    Normally, you should place calls using call().

    \warning If you use \c UseEventLoop, your code must be prepared to deal with any reentrancy:
             other method calls and signals may be delivered before this function returns, as well
             as other Qt queued signals and events.

    \threadsafe
*/
QDBusMessage QDBusAbstractInterface::callWithArgumentList(QDBus::CallMode mode,
                                                          const QString& method,
                                                          const QList<QVariant>& args)
{
    Q_D(QDBusAbstractInterface);

    if (!d->isValid || !d->canMakeCalls())
        return QDBusMessage::createError(d->lastError);

    QString m = method;
    // split out the signature from the method
    int pos = method.indexOf(QLatin1Char('.'));
    if (pos != -1)
        m.truncate(pos);

    if (mode == QDBus::AutoDetect) {
        // determine if this a sync or async call
        mode = QDBus::Block;
        const QMetaObject *mo = metaObject();
        QByteArray match = m.toLatin1();

        for (int i = staticMetaObject.methodCount(); i < mo->methodCount(); ++i) {
            QMetaMethod mm = mo->method(i);
            if (mm.name() == match) {
                // found a method with the same name as what we're looking for
                // hopefully, nobody is overloading asynchronous and synchronous methods with
                // the same name

                QList<QByteArray> tags = QByteArray(mm.tag()).split(' ');
                if (tags.contains("Q_NOREPLY"))
                    mode = QDBus::NoBlock;

                break;
            }
        }
    }

//    qDebug() << "QDBusAbstractInterface" << "Service" << service() << "Path:" << path();
    QDBusMessage msg = QDBusMessage::createMethodCall(service(), path(), interface(), m);
    QDBusMessagePrivate::setParametersValidated(msg, true);
    msg.setArguments(args);

    QDBusMessage reply = d->connection.call(msg, mode, d->timeout);
    if (thread() == QThread::currentThread())
        d->lastError = QDBusError(reply);       // will clear if reply isn't an error

    // ensure that there is at least one element
    if (reply.arguments().isEmpty())
        reply << QVariant();

    return reply;
}

/*!
    \since 4.5
    Places a call to the remote method specified by \a method on this
    interface, using \a args as arguments. This function returns a
    QDBusPendingCall object that can be used to track the status of the
    reply and access its contents once it has arrived.

    Normally, you should place calls using asyncCall().

    \threadsafe
*/
QDBusPendingCall QDBusAbstractInterface::asyncCallWithArgumentList(const QString& method,
                                                                   const QList<QVariant>& args)
{
    Q_D(QDBusAbstractInterface);

    if (!d->isValid || !d->canMakeCalls())
        return QDBusPendingCall::fromError(d->lastError);

    QDBusMessage msg = QDBusMessage::createMethodCall(service(), path(), interface(), method);
    QDBusMessagePrivate::setParametersValidated(msg, true);
    msg.setArguments(args);
    return d->connection.asyncCall(msg, d->timeout);
}

/*!
    Places a call to the remote method specified by \a method
    on this interface, using \a args as arguments. This function
    returns immediately after queueing the call. The reply from
    the remote function is delivered to the \a returnMethod on
    object \a receiver. If an error occurs, the \a errorMethod
    on object \a receiver is called instead.

    This function returns \c true if the queueing succeeds. It does
    not indicate that the executed call succeeded. If it fails,
    the \a errorMethod is called. If the queueing failed, this
    function returns \c false and no slot will be called.

    The \a returnMethod must have as its parameters the types returned
    by the function call. Optionally, it may have a QDBusMessage
    parameter as its last or only parameter.  The \a errorMethod must
    have a QDBusError as its only parameter.

    \since 4.3
    \sa QDBusError, QDBusMessage
 */
bool QDBusAbstractInterface::callWithCallback(const QString &method,
                                              const QList<QVariant> &args,
                                              QObject *receiver,
                                              const char *returnMethod,
                                              const char *errorMethod)
{
    Q_D(QDBusAbstractInterface);

    if (!d->isValid || !d->canMakeCalls())
        return false;

    QDBusMessage msg = QDBusMessage::createMethodCall(service(),
                                                      path(),
                                                      interface(),
                                                      method);
    QDBusMessagePrivate::setParametersValidated(msg, true);
    msg.setArguments(args);

    d->lastError = QDBusError();
    return d->connection.callWithCallback(msg,
                                          receiver,
                                          returnMethod,
                                          errorMethod,
                                          d->timeout);
}

/*!
    \overload

    This function is deprecated. Please use the overloaded version.

    Places a call to the remote method specified by \a method
    on this interface, using \a args as arguments. This function
    returns immediately after queueing the call. The reply from
    the remote function or any errors emitted by it are delivered
    to the \a slot slot on object \a receiver.

    This function returns \c true if the queueing succeeded: it does
    not indicate that the call succeeded. If it failed, the slot
    will be called with an error message. lastError() will not be
    set under those circumstances.

    \sa QDBusError, QDBusMessage
*/
bool QDBusAbstractInterface::callWithCallback(const QString &method,
                                              const QList<QVariant> &args,
                                              QObject *receiver,
                                              const char *slot)
{
    return callWithCallback(method, args, receiver, slot, nullptr);
}

/*!
    \internal
    Catch signal connections.
*/
void QDBusAbstractInterface::connectNotify(const QMetaMethod &signal)
{
    // someone connecting to one of our signals
    Q_D(QDBusAbstractInterface);
    if (!d->isValid)
        return;

    // we end up recursing here, so optimize away
    static const QMetaMethod destroyedSignal = QMetaMethod::fromSignal(&QDBusAbstractInterface::destroyed);
    if (signal == destroyedSignal)
        return;

    QDBusConnectionPrivate *conn = d->connectionPrivate();
    if (conn) {
        conn->connectRelay(d->service, d->path, d->interface,
                           this, signal);
    }
}

/*!
    \internal
    Catch signal disconnections.
*/
void QDBusAbstractInterface::disconnectNotify(const QMetaMethod &signal)
{
    // someone disconnecting from one of our signals
    Q_D(QDBusAbstractInterface);
    if (!d->isValid)
        return;

    // disconnection is just resource freeing, so it can be delayed;
    // let's do that later, after all the QObject mutexes have been unlocked.
    QCoreApplication::postEvent(this, new DisconnectRelayEvent(this, signal));
}

/*!
    \internal
    Continues the disconnect notification from above.
*/
void QDBusAbstractInterfacePrivate::finishDisconnectNotify(QDBusAbstractInterface *ptr, int signalId)
{
    QDBusAbstractInterfacePrivate *d = ptr->d_func();
    QDBusConnectionPrivate *conn = d->connectionPrivate();
    if (!conn)
        return;

    const QMetaObject *mo = ptr->metaObject();
    QMetaMethod signal = signalId >= 0 ? mo->method(signalId) : QMetaMethod();
    if (signal.isValid()) {
        if (!ptr->isSignalConnected(signal))
            return conn->disconnectRelay(d->service, d->path, d->interface,
                                         ptr, signal);
    } else {
        // wildcard disconnecting, we need to figure out which of our signals are
        // no longer connected to anything
        int midx = QObject::staticMetaObject.methodCount();
        const int end = mo->methodCount();
        for ( ; midx < end; ++midx) {
            QMetaMethod mm = mo->method(midx);
            if (mm.methodType() == QMetaMethod::Signal && !ptr->isSignalConnected(mm))
                conn->disconnectRelay(d->service, d->path, d->interface, ptr, mm);
        }
    }
}

/*!
    \internal
    Get the value of the property \a propname.
*/
QVariant QDBusAbstractInterface::internalPropGet(const char *propname) const
{
    // assume this property exists and is readable
    // we're only called from generated code anyways

    return property(propname);
}

/*!
    \internal
    Set the value of the property \a propname to \a value.
*/
void QDBusAbstractInterface::internalPropSet(const char *propname, const QVariant &value)
{
    setProperty(propname, value);
}

/*!
    \fn QDBusAbstractInterface::call(const QString &message)
    \internal
*/

/*!
    \fn template <typename...Args> QDBusMessage QDBusAbstractInterface::call(const QString &method, Args&&...args)

    Calls the method \a method on this interface and passes \a args to the method.
    All \a args must be convertible to QVariant.

    The parameters to \c call are passed on to the remote function via D-Bus as input
    arguments. Output arguments are returned in the QDBusMessage reply. If the reply is an error
    reply, lastError() will also be set to the contents of the error message.

    It can be used the following way:

    \snippet code/src_qdbus_qdbusabstractinterface.cpp 0

    This example illustrates function calling with 0, 1 and 2 parameters and illustrates different
    parameter types passed in each (the first call to \c "ProcessWorkUnicode" will contain one
    Unicode string, the second call to \c "ProcessWork" will contain one string and one byte array).

    \note Before Qt 5.14, this function accepted a maximum of just eight (8) arguments.

    \sa callWithArgumentList()
*/

#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
/*!
    \internal

    This function exists for binary compatibility with Qt versions < 5.14.
    Programs recompiled against Qt 5.14 will use the variadic template function
    instead.
*/
QDBusMessage QDBusAbstractInterface::call(const QString &method, const QVariant &arg1,
                                          const QVariant &arg2,
                                          const QVariant &arg3,
                                          const QVariant &arg4,
                                          const QVariant &arg5,
                                          const QVariant &arg6,
                                          const QVariant &arg7,
                                          const QVariant &arg8)
{
    return call(QDBus::AutoDetect, method, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8);
}
#endif

/*!
    \fn QDBusAbstractInterface::call(QDBus::CallMode mode, const QString &message)
    \internal
*/

/*!
    \fn template <typename...Args> QDBusMessage QDBusAbstractInterface::call(QDBus::CallMode mode, const QString &method, Args&&...args)

    \overload

    Calls the method \a method on this interface and passes \a args to the method.
    All \a args must be convertible to QVariant.

    If \a mode is \c NoWaitForReply, then this function will return immediately after
    placing the call, without waiting for a reply from the remote
    method. Otherwise, \a mode indicates whether this function should
    activate the Qt Event Loop while waiting for the reply to arrive.

    If this function reenters the Qt event loop in order to wait for the
    reply, it will exclude user input. During the wait, it may deliver
    signals and other method calls to your application. Therefore, it
    must be prepared to handle a reentrancy whenever a call is placed
    with call().

    \note Before Qt 5.14, this function accepted a maximum of just eight (8) arguments.

    \sa callWithArgumentList()
*/

#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
/*!
    \internal

    This function exists for binary compatibility with Qt versions < 5.14.
    Programs recompiled against Qt 5.14 will use the variadic template function
    instead.
*/
QDBusMessage QDBusAbstractInterface::call(QDBus::CallMode mode, const QString &method,
                                          const QVariant &arg1,
                                          const QVariant &arg2,
                                          const QVariant &arg3,
                                          const QVariant &arg4,
                                          const QVariant &arg5,
                                          const QVariant &arg6,
                                          const QVariant &arg7,
                                          const QVariant &arg8)
{
    QList<QVariant> argList;
    int count = 0 + arg1.isValid() + arg2.isValid() + arg3.isValid() + arg4.isValid() +
                arg5.isValid() + arg6.isValid() + arg7.isValid() + arg8.isValid();

    switch (count) {
    case 8:
        argList.prepend(arg8);
        Q_FALLTHROUGH();
    case 7:
        argList.prepend(arg7);
        Q_FALLTHROUGH();
    case 6:
        argList.prepend(arg6);
        Q_FALLTHROUGH();
    case 5:
        argList.prepend(arg5);
        Q_FALLTHROUGH();
    case 4:
        argList.prepend(arg4);
        Q_FALLTHROUGH();
    case 3:
        argList.prepend(arg3);
        Q_FALLTHROUGH();
    case 2:
        argList.prepend(arg2);
        Q_FALLTHROUGH();
    case 1:
        argList.prepend(arg1);
        break;
    }

    return callWithArgumentList(mode, method, argList);
}
#endif // Qt 5

/*!
    \fn QDBusAbstractInterface::asyncCall(const QString &message)
    \internal
*/

/*!
    \fn template <typename...Args> QDBusPendingCall QDBusAbstractInterface::asyncCall(const QString &method, Args&&...args)

    Calls the method \a method on this interface and passes \a args to the method.
    All \a args must be convertible to QVariant.

    The parameters to \c call are passed on to the remote function via D-Bus as input
    arguments. The returned QDBusPendingCall object can be used to find out information about
    the reply.

    It can be used the following way:

    \snippet code/src_qdbus_qdbusabstractinterface.cpp 1

    This example illustrates function calling with 0, 1 and 2 parameters and illustrates different
    parameter types passed in each (the first call to \c "ProcessWorkUnicode" will contain one
    Unicode string, the second call to \c "ProcessWork" will contain one string and one byte array).

    \note Before Qt 5.14, this function accepted a maximum of just eight (8) arguments.

    \sa asyncCallWithArgumentList()
*/

#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
/*!
    \internal

    This function exists for binary compatibility with Qt versions < 5.14.
    Programs recompiled against Qt 5.14 will use the variadic template function
    instead.
*/
QDBusPendingCall QDBusAbstractInterface::asyncCall(const QString &method, const QVariant &arg1,
                                                   const QVariant &arg2,
                                                   const QVariant &arg3,
                                                   const QVariant &arg4,
                                                   const QVariant &arg5,
                                                   const QVariant &arg6,
                                                   const QVariant &arg7,
                                                   const QVariant &arg8)
{
    QList<QVariant> argList;
    int count = 0 + arg1.isValid() + arg2.isValid() + arg3.isValid() + arg4.isValid() +
                arg5.isValid() + arg6.isValid() + arg7.isValid() + arg8.isValid();

    switch (count) {
    case 8:
        argList.prepend(arg8);
        Q_FALLTHROUGH();
    case 7:
        argList.prepend(arg7);
        Q_FALLTHROUGH();
    case 6:
        argList.prepend(arg6);
        Q_FALLTHROUGH();
    case 5:
        argList.prepend(arg5);
        Q_FALLTHROUGH();
    case 4:
        argList.prepend(arg4);
        Q_FALLTHROUGH();
    case 3:
        argList.prepend(arg3);
        Q_FALLTHROUGH();
    case 2:
        argList.prepend(arg2);
        Q_FALLTHROUGH();
    case 1:
        argList.prepend(arg1);
        break;
    }

    return asyncCallWithArgumentList(method, argList);
}
#endif // Qt 5

/*!
    \internal
*/
QDBusMessage QDBusAbstractInterface::internalConstCall(QDBus::CallMode mode,
                                                       const QString &method,
                                                       const QList<QVariant> &args) const
{
    // ### move the code here, and make the other functions call this
    return const_cast<QDBusAbstractInterface*>(this)->callWithArgumentList(mode, method, args);
}

QDBusMessage QDBusAbstractInterface::doCall(QDBus::CallMode mode, const QString &method, const QVariant *args, size_t numArgs)
{
    QList<QVariant> list;
    list.reserve(int(numArgs));
    for (size_t i = 0; i < numArgs; ++i)
        list.append(args[i]);
    return callWithArgumentList(mode, method, list);
}

QDBusPendingCall QDBusAbstractInterface::doAsyncCall(const QString &method, const QVariant *args, size_t numArgs)
{
    QList<QVariant> list;
    list.reserve(int(numArgs));
    for (size_t i = 0; i < numArgs; ++i)
        list.append(args[i]);
    return asyncCallWithArgumentList(method, list);
}

QT_END_NAMESPACE

#endif // QT_NO_DBUS

#include "moc_qdbusabstractinterface.cpp"
