/****************************************************************************
**
** Copyright (C) 2016 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the test suite of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:GPL-EXCEPT$
** 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 General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 3 as published by the Free Software
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
** 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-3.0.html.
**
** $QT_END_LICENSE$
**
****************************************************************************/
/* -*- C++ -*-
 */

#include <qcoreapplication.h>
#include <qmetatype.h>
#include <QtTest/QtTest>
#include <QtCore/qvariant.h>
#include <QtDBus/QtDBus>
#include <QtDBus/private/qdbus_symbols_p.h>
#include <qdebug.h>
#include "../qdbusmarshall/common.h"
#include "myobject.h"

#define TEST_INTERFACE_NAME "org.qtproject.QtDBus.MyObject"
#define TEST_SIGNAL_NAME "somethingHappened"

static const char serviceName[] = "org.qtproject.autotests.qmyserver";
static const char objectPath[] = "/org/qtproject/qmyserver";
static const char *interfaceName = serviceName;

int MyObject::callCount = 0;
QVariantList MyObject::callArgs;

class MyObjectUnknownType: public QObject
{
    Q_OBJECT
    Q_CLASSINFO("D-Bus Interface", "org.qtproject.QtDBus.MyObject")
    Q_CLASSINFO("D-Bus Introspection", ""
"  <interface name=\"org.qtproject.QtDBus.MyObjectUnknownTypes\" >\n"
"    <property access=\"readwrite\" type=\"~\" name=\"prop1\" />\n"
"    <signal name=\"somethingHappened\" >\n"
"      <arg direction=\"out\" type=\"~\" />\n"
"    </signal>\n"
"    <method name=\"ping\" >\n"
"      <arg direction=\"in\" type=\"~\" name=\"ping\" />\n"
"      <arg direction=\"out\" type=\"~\" name=\"ping\" />\n"
"    </method>\n"
"    <method name=\"regularMethod\" />\n"
"  </interface>\n"
                "")
};

class Spy: public QObject
{
    Q_OBJECT
public:
    QString received;
    int count;

    Spy() : count(0)
    { }

public slots:
    void spySlot(const QString& arg)
    {
        received = arg;
        ++count;
    }
};

class DerivedFromQDBusInterface: public QDBusInterface
{
    Q_OBJECT
public:
    DerivedFromQDBusInterface()
        : QDBusInterface("com.example.Test", "/")
    {}

public slots:
    void method() {}
};

// helper function
void emitSignal(const QString &interface, const QString &name, const QString &arg)
{
    QDBusMessage msg = QDBusMessage::createSignal("/", interface, name);
    msg << arg;
    QDBusConnection::sessionBus().send(msg);

    QTest::qWait(1000);
}

void emitSignalPeer(const QString &interface, const QString &name, const QString &arg)
{
    QDBusMessage req = QDBusMessage::createMethodCall(serviceName, objectPath, interfaceName, "emitSignal");
    req << interface;
    req << name;
    req << arg;
    QDBusConnection::sessionBus().send(req);

    QTest::qWait(1000);
}

int callCountPeer()
{
    QDBusMessage req = QDBusMessage::createMethodCall(serviceName, objectPath, interfaceName, "callCount");
    QDBusMessage reply = QDBusConnection::sessionBus().call(req);
    return reply.arguments().at(0).toInt();
}

QVariantList callArgsPeer()
{
    QDBusMessage req = QDBusMessage::createMethodCall(serviceName, objectPath, interfaceName, "callArgs");
    QDBusMessage reply = QDBusConnection::sessionBus().call(req);
    return qdbus_cast<QVariantList>(reply.arguments().at(0));
}

void setProp1Peer(int val)
{
    QDBusMessage req = QDBusMessage::createMethodCall(serviceName, objectPath, interfaceName, "setProp1");
    req << val;
    QDBusMessage reply = QDBusConnection::sessionBus().call(req);
}

int prop1Peer()
{
    QDBusMessage req = QDBusMessage::createMethodCall(serviceName, objectPath, interfaceName, "prop1");
    QDBusMessage reply = QDBusConnection::sessionBus().call(req);
    return reply.arguments().at(0).toInt();
}

void setComplexPropPeer(QList<int> val)
{
    QDBusMessage req = QDBusMessage::createMethodCall(serviceName, objectPath, interfaceName, "setComplexProp");
    req << QVariant::fromValue(val);
    QDBusMessage reply = QDBusConnection::sessionBus().call(req);
}

QList<int> complexPropPeer()
{
    QDBusMessage req = QDBusMessage::createMethodCall(serviceName, objectPath, interfaceName, "complexProp");
    QDBusMessage reply = QDBusConnection::sessionBus().call(req);
    return qdbus_cast<QList<int> >(reply.arguments().at(0));
}

void resetPeer()
{
    QDBusMessage req = QDBusMessage::createMethodCall(serviceName, objectPath, interfaceName, "reset");
    QDBusConnection::sessionBus().call(req);
}

class tst_QDBusInterface: public QObject
{
    Q_OBJECT
    MyObject obj;

public slots:
    void testServiceOwnerChanged(const QString &service)
    {
        if (service == "com.example.Test")
            QTestEventLoop::instance().exitLoop();
    }

private slots:
    void initTestCase();
    void cleanupTestCase();

    void notConnected();
    void notValid();
    void notValidDerived();
    void invalidAfterServiceOwnerChanged();
    void introspect();
    void introspectUnknownTypes();
    void introspectVirtualObject();
    void callMethod();
    void invokeMethod();
    void invokeMethodWithReturn();
    void invokeMethodWithMultiReturn();
    void invokeMethodWithComplexReturn();

    void introspectPeer();
    void callMethodPeer();
    void invokeMethodPeer();
    void invokeMethodWithReturnPeer();
    void invokeMethodWithMultiReturnPeer();
    void invokeMethodWithComplexReturnPeer();

    void signal();
    void signalPeer();

    void propertyRead();
    void propertyWrite();
    void complexPropertyRead();
    void complexPropertyWrite();

    void propertyReadPeer();
    void propertyWritePeer();
    void complexPropertyReadPeer();
    void complexPropertyWritePeer();

    void interactiveAuthorizationRequired();
private:
    QProcess proc;
};

class WaitForQMyServer: public QObject
{
    Q_OBJECT
public:
    WaitForQMyServer();
    bool ok();
public Q_SLOTS:
    void ownerChange(const QString &name)
    {
        if (name == serviceName)
            loop.quit();
    }

private:
    QEventLoop loop;
};

WaitForQMyServer::WaitForQMyServer()
{
    QDBusConnection con = QDBusConnection::sessionBus();
    if (!ok()) {
        connect(con.interface(), SIGNAL(serviceOwnerChanged(QString,QString,QString)),
                SLOT(ownerChange(QString)));
        QTimer::singleShot(2000, &loop, SLOT(quit()));
        loop.exec();
    }
}

bool WaitForQMyServer::ok()
{
    return QDBusConnection::sessionBus().isConnected() &&
        QDBusConnection::sessionBus().interface()->isServiceRegistered(serviceName);
}

void tst_QDBusInterface::initTestCase()
{
    QDBusConnection con = QDBusConnection::sessionBus();
    QVERIFY(con.isConnected());
    QTest::qWait(500);

    con.registerObject("/", &obj, QDBusConnection::ExportAllProperties
                       | QDBusConnection::ExportAllSlots
                       | QDBusConnection::ExportAllInvokables);

#ifdef Q_OS_WIN
#  define EXE ".exe"
#else
#  define EXE ""
#endif
    proc.setProcessChannelMode(QProcess::ForwardedErrorChannel);
    proc.start(QFINDTESTDATA("qmyserver/qmyserver" EXE));
    QVERIFY2(proc.waitForStarted(), qPrintable(proc.errorString()));
    QVERIFY(proc.waitForReadyRead());

    WaitForQMyServer w;
    QVERIFY(w.ok());
    //QTest::qWait(2000);

    // get peer server address
    QDBusMessage req = QDBusMessage::createMethodCall(serviceName, objectPath, interfaceName, "address");
    QDBusMessage rpl = con.call(req);
    QCOMPARE(rpl.type(), QDBusMessage::ReplyMessage);
    QString address = rpl.arguments().at(0).toString();

    // connect to peer server
    QDBusConnection peercon = QDBusConnection::connectToPeer(address, "peer");
    QVERIFY(peercon.isConnected());

    QDBusMessage req2 = QDBusMessage::createMethodCall(serviceName, objectPath, interfaceName, "waitForConnected");
    QDBusMessage rpl2 = con.call(req2);
    QCOMPARE(rpl2.type(), QDBusMessage::ReplyMessage);
    QVERIFY2(rpl2.type() == QDBusMessage::ReplyMessage, rpl2.errorMessage().toLatin1());
}

void tst_QDBusInterface::cleanupTestCase()
{
    QDBusMessage msg = QDBusMessage::createMethodCall(serviceName, objectPath, interfaceName, "quit");
    QDBusConnection::sessionBus().call(msg);
    proc.waitForFinished(200);
    proc.close();
}

void tst_QDBusInterface::notConnected()
{
    QDBusConnection connection("");
    QVERIFY(!connection.isConnected());

    QDBusInterface interface("org.freedesktop.DBus", "/", "org.freedesktop.DBus",
                             connection);

    QVERIFY(!interface.isValid());
    QVERIFY(!QMetaObject::invokeMethod(&interface, "ListNames", Qt::DirectConnection));
}

void tst_QDBusInterface::notValid()
{
    QDBusConnection connection("");
    QVERIFY(!connection.isConnected());

    QDBusInterface interface("com.example.Test", QString(), "org.example.Test",
                             connection);

    QVERIFY(!interface.isValid());
    QVERIFY(!QMetaObject::invokeMethod(&interface, "ListNames", Qt::DirectConnection));
}

void tst_QDBusInterface::notValidDerived()
{
    DerivedFromQDBusInterface c;
    QVERIFY(!c.isValid());
    QMetaObject::invokeMethod(&c, "method", Qt::DirectConnection);
}

void tst_QDBusInterface::invalidAfterServiceOwnerChanged()
{
    // this test is technically the same as tst_QDBusAbstractInterface::followSignal
    QDBusConnection conn = QDBusConnection::sessionBus();
    QDBusConnectionInterface *connIface = conn.interface();

    QDBusInterface validInterface(conn.baseService(), "/");
    QVERIFY(validInterface.isValid());
    QDBusInterface invalidInterface("com.example.Test", "/");
    QVERIFY(!invalidInterface.isValid());

    QTestEventLoop::instance().connect(connIface, SIGNAL(serviceOwnerChanged(QString,QString,QString)),
                                       SLOT(exitLoop()));
    QCOMPARE(connIface->registerService("com.example.Test").value(), QDBusConnectionInterface::ServiceRegistered);

    QTestEventLoop::instance().enterLoop(5);

    QVERIFY(!QTestEventLoop::instance().timeout());
    QVERIFY(invalidInterface.isValid());
}

void tst_QDBusInterface::introspect()
{
    QDBusInterface iface(QDBusConnection::sessionBus().baseService(), QLatin1String("/"),
                         TEST_INTERFACE_NAME);

    const QMetaObject *mo = iface.metaObject();

    QCOMPARE(mo->methodCount() - mo->methodOffset(), 7);
    QVERIFY(mo->indexOfSignal(TEST_SIGNAL_NAME "(QString)") != -1);

    QCOMPARE(mo->propertyCount() - mo->propertyOffset(), 2);
    QVERIFY(mo->indexOfProperty("prop1") != -1);
    QVERIFY(mo->indexOfProperty("complexProp") != -1);
}

void tst_QDBusInterface::introspectUnknownTypes()
{
    QDBusConnection con = QDBusConnection::sessionBus();
    MyObjectUnknownType obj;
    con.registerObject("/unknownTypes", &obj, QDBusConnection::ExportAllContents);
    QDBusInterface iface(QDBusConnection::sessionBus().baseService(), QLatin1String("/unknownTypes"),
                         "org.qtproject.QtDBus.MyObjectUnknownTypes");

    const QMetaObject *mo = iface.metaObject();
    QVERIFY(mo->indexOfMethod("regularMethod()") != -1); // this is the control
    QVERIFY(mo->indexOfMethod("somethingHappened(QDBusRawType<0x7e>*)") != -1);

    QVERIFY(mo->indexOfMethod("ping(QDBusRawType<0x7e>*)") != -1);
    int midx = mo->indexOfMethod("ping(QDBusRawType<0x7e>*)");
    QCOMPARE(mo->method(midx).typeName(), "QDBusRawType<0x7e>*");

    QVERIFY(mo->indexOfProperty("prop1") != -1);
    int pidx = mo->indexOfProperty("prop1");
    QCOMPARE(mo->property(pidx).typeName(), "QDBusRawType<0x7e>*");



    QDBusMessage message = QDBusMessage::createMethodCall(con.baseService(), "/unknownTypes", "org.freedesktop.DBus.Introspectable", "Introspect");
    QDBusMessage reply = con.call(message, QDBus::Block, 5000);
    qDebug() << "REPL: " << reply.arguments();

}


class VirtualObject: public QDBusVirtualObject
{
    Q_OBJECT
public:
    VirtualObject() :success(true) {}

    QString introspect(const QString &path) const {
        Q_ASSERT(QThread::currentThread() == thread());
        if (path == "/some/path/superNode")
            return "zitroneneis";
        if (path == "/some/path/superNode/foo")
            return  "  <interface name=\"org.qtproject.QtDBus.VirtualObject\">\n"
                    "    <method name=\"klingeling\" />\n"
                    "  </interface>\n" ;
        return QString();
    }

    bool handleMessage(const QDBusMessage &message, const QDBusConnection &connection) {
        Q_ASSERT(QThread::currentThread() == thread());
        ++callCount;
        lastMessage = message;

        if (success) {
            QDBusMessage reply = message.createReply(replyArguments);
            connection.send(reply);
        }
        emit messageReceived(message);
        return success;
    }
signals:
    void messageReceived(const QDBusMessage &message) const;

public:
    mutable QDBusMessage lastMessage;
    QVariantList replyArguments;
    mutable int callCount;
    bool success;
};

void tst_QDBusInterface::introspectVirtualObject()
{
    QDBusConnection con = QDBusConnection::sessionBus();
    QVERIFY(con.isConnected());
    VirtualObject obj;

    obj.success = false;

    QString path = "/some/path/superNode";
    QVERIFY(con.registerVirtualObject(path, &obj, QDBusConnection::SubPath));

    QDBusMessage message = QDBusMessage::createMethodCall(con.baseService(), path, "org.freedesktop.DBus.Introspectable", "Introspect");
    QDBusMessage reply = con.call(message, QDBus::Block, 5000);
    QVERIFY(reply.arguments().at(0).toString().contains(
        QRegExp("<node>.*zitroneneis.*<interface name=") ));

    QDBusMessage message2 = QDBusMessage::createMethodCall(con.baseService(), path + "/foo", "org.freedesktop.DBus.Introspectable", "Introspect");
    QDBusMessage reply2 = con.call(message2, QDBus::Block, 5000);
    QVERIFY(reply2.arguments().at(0).toString().contains(
        QRegExp("<node>.*<interface name=\"org.qtproject.QtDBus.VirtualObject\">"
                ".*<method name=\"klingeling\" />\n"
                ".*</interface>.*<interface name=") ));
}

void tst_QDBusInterface::callMethod()
{
    QDBusConnection con = QDBusConnection::sessionBus();
    QDBusInterface iface(QDBusConnection::sessionBus().baseService(), QLatin1String("/"),
                         TEST_INTERFACE_NAME);

    MyObject::callCount = 0;

    // call a SLOT method
    QDBusMessage reply = iface.call("ping", QVariant::fromValue(QDBusVariant("foo")));
    QCOMPARE(MyObject::callCount, 1);
    QCOMPARE(reply.type(), QDBusMessage::ReplyMessage);

    // verify what the callee received
    QCOMPARE(MyObject::callArgs.count(), 1);
    QVariant v = MyObject::callArgs.at(0);
    QDBusVariant dv = qdbus_cast<QDBusVariant>(v);
    QCOMPARE(dv.variant().type(), QVariant::String);
    QCOMPARE(dv.variant().toString(), QString("foo"));

    // verify reply
    QCOMPARE(reply.arguments().count(), 1);
    v = reply.arguments().at(0);
    dv = qdbus_cast<QDBusVariant>(v);
    QCOMPARE(dv.variant().type(), QVariant::String);
    QCOMPARE(dv.variant().toString(), QString("foo"));

    // call an INVOKABLE method
    reply = iface.call("ping_invokable", QVariant::fromValue(QDBusVariant("bar")));
    QCOMPARE(MyObject::callCount, 2);
    QCOMPARE(reply.type(), QDBusMessage::ReplyMessage);

    // verify what the callee received
    QCOMPARE(MyObject::callArgs.count(), 1);
    v = MyObject::callArgs.at(0);
    dv = qdbus_cast<QDBusVariant>(v);
    QCOMPARE(dv.variant().type(), QVariant::String);
    QCOMPARE(dv.variant().toString(), QString("bar"));

    // verify reply
    QCOMPARE(reply.arguments().count(), 1);
    v = reply.arguments().at(0);
    dv = qdbus_cast<QDBusVariant>(v);
    QCOMPARE(dv.variant().type(), QVariant::String);
    QCOMPARE(dv.variant().toString(), QString("bar"));
}

void tst_QDBusInterface::invokeMethod()
{
    QDBusConnection con = QDBusConnection::sessionBus();
    QDBusInterface iface(QDBusConnection::sessionBus().baseService(), QLatin1String("/"),
                         TEST_INTERFACE_NAME);

    MyObject::callCount = 0;

    // make the SLOT call without a return type
    QDBusVariant arg("foo");
    QVERIFY(QMetaObject::invokeMethod(&iface, "ping", Q_ARG(QDBusVariant, arg)));
    QCOMPARE(MyObject::callCount, 1);

    // verify what the callee received
    QCOMPARE(MyObject::callArgs.count(), 1);
    QVariant v = MyObject::callArgs.at(0);
    QDBusVariant dv = qdbus_cast<QDBusVariant>(v);
    QCOMPARE(dv.variant().type(), QVariant::String);
    QCOMPARE(dv.variant().toString(), QString("foo"));

    // make the INVOKABLE call without a return type
    QDBusVariant arg2("bar");
    QVERIFY(QMetaObject::invokeMethod(&iface, "ping_invokable", Q_ARG(QDBusVariant, arg2)));
    QCOMPARE(MyObject::callCount, 2);

    // verify what the callee received
    QCOMPARE(MyObject::callArgs.count(), 1);
    v = MyObject::callArgs.at(0);
    dv = qdbus_cast<QDBusVariant>(v);
    QCOMPARE(dv.variant().type(), QVariant::String);
    QCOMPARE(dv.variant().toString(), QString("bar"));
}

void tst_QDBusInterface::invokeMethodWithReturn()
{
    QDBusConnection con = QDBusConnection::sessionBus();
    QDBusInterface iface(QDBusConnection::sessionBus().baseService(), QLatin1String("/"),
                         TEST_INTERFACE_NAME);

    MyObject::callCount = 0;
    QDBusVariant retArg;

    // make the SLOT call without a return type
    QDBusVariant arg("foo");
    QVERIFY(QMetaObject::invokeMethod(&iface, "ping", Q_RETURN_ARG(QDBusVariant, retArg), Q_ARG(QDBusVariant, arg)));
    QCOMPARE(MyObject::callCount, 1);

    // verify what the callee received
    QCOMPARE(MyObject::callArgs.count(), 1);
    QVariant v = MyObject::callArgs.at(0);
    QDBusVariant dv = qdbus_cast<QDBusVariant>(v);
    QCOMPARE(dv.variant().type(), QVariant::String);
    QCOMPARE(dv.variant().toString(), arg.variant().toString());

    // verify that we got the reply as expected
    QCOMPARE(retArg.variant(), arg.variant());

    // make the INVOKABLE call without a return type
    QDBusVariant arg2("bar");
    QVERIFY(QMetaObject::invokeMethod(&iface, "ping_invokable", Q_RETURN_ARG(QDBusVariant, retArg), Q_ARG(QDBusVariant, arg2)));
    QCOMPARE(MyObject::callCount, 2);

    // verify what the callee received
    QCOMPARE(MyObject::callArgs.count(), 1);
    v = MyObject::callArgs.at(0);
    dv = qdbus_cast<QDBusVariant>(v);
    QCOMPARE(dv.variant().type(), QVariant::String);
    QCOMPARE(dv.variant().toString(), arg2.variant().toString());

    // verify that we got the reply as expected
    QCOMPARE(retArg.variant(), arg2.variant());
}

void tst_QDBusInterface::invokeMethodWithMultiReturn()
{
    QDBusConnection con = QDBusConnection::sessionBus();
    QDBusInterface iface(QDBusConnection::sessionBus().baseService(), QLatin1String("/"),
                         TEST_INTERFACE_NAME);

    MyObject::callCount = 0;
    QDBusVariant retArg, retArg2;

    // make the SLOT call without a return type
    QDBusVariant arg("foo"), arg2("bar");
    QVERIFY(QMetaObject::invokeMethod(&iface, "ping",
                                      Q_RETURN_ARG(QDBusVariant, retArg),
                                      Q_ARG(QDBusVariant, arg),
                                      Q_ARG(QDBusVariant, arg2),
                                      Q_ARG(QDBusVariant&, retArg2)));
    QCOMPARE(MyObject::callCount, 1);

    // verify what the callee received
    QCOMPARE(MyObject::callArgs.count(), 2);
    QVariant v = MyObject::callArgs.at(0);
    QDBusVariant dv = qdbus_cast<QDBusVariant>(v);
    QCOMPARE(dv.variant().type(), QVariant::String);
    QCOMPARE(dv.variant().toString(), arg.variant().toString());

    v = MyObject::callArgs.at(1);
    dv = qdbus_cast<QDBusVariant>(v);
    QCOMPARE(dv.variant().type(), QVariant::String);
    QCOMPARE(dv.variant().toString(), arg2.variant().toString());

    // verify that we got the replies as expected
    QCOMPARE(retArg.variant(), arg.variant());
    QCOMPARE(retArg2.variant(), arg2.variant());

    // make the INVOKABLE call without a return type
    QDBusVariant arg3("hello"), arg4("world");
    QVERIFY(QMetaObject::invokeMethod(&iface, "ping_invokable",
                                      Q_RETURN_ARG(QDBusVariant, retArg),
                                      Q_ARG(QDBusVariant, arg3),
                                      Q_ARG(QDBusVariant, arg4),
                                      Q_ARG(QDBusVariant&, retArg2)));
    QCOMPARE(MyObject::callCount, 2);

    // verify what the callee received
    QCOMPARE(MyObject::callArgs.count(), 2);
    v = MyObject::callArgs.at(0);
    dv = qdbus_cast<QDBusVariant>(v);
    QCOMPARE(dv.variant().type(), QVariant::String);
    QCOMPARE(dv.variant().toString(), arg3.variant().toString());

    v = MyObject::callArgs.at(1);
    dv = qdbus_cast<QDBusVariant>(v);
    QCOMPARE(dv.variant().type(), QVariant::String);
    QCOMPARE(dv.variant().toString(), arg4.variant().toString());

    // verify that we got the replies as expected
    QCOMPARE(retArg.variant(), arg3.variant());
    QCOMPARE(retArg2.variant(), arg4.variant());
}

void tst_QDBusInterface::invokeMethodWithComplexReturn()
{
    QDBusConnection con = QDBusConnection::sessionBus();
    QDBusInterface iface(QDBusConnection::sessionBus().baseService(), QLatin1String("/"),
                         TEST_INTERFACE_NAME);

    MyObject::callCount = 0;
    QList<int> retArg;

    // make the SLOT call without a return type
    QList<int> arg = QList<int>() << 42 << -47;
    QVERIFY(QMetaObject::invokeMethod(&iface, "ping", Q_RETURN_ARG(QList<int>, retArg), Q_ARG(QList<int>, arg)));
    QCOMPARE(MyObject::callCount, 1);

    // verify what the callee received
    QCOMPARE(MyObject::callArgs.count(), 1);
    QVariant v = MyObject::callArgs.at(0);
    QCOMPARE(v.userType(), qMetaTypeId<QDBusArgument>());
    QCOMPARE(qdbus_cast<QList<int> >(v), arg);

    // verify that we got the reply as expected
    QCOMPARE(retArg, arg);

    // make the INVOKABLE call without a return type
    QList<int> arg2 = QList<int>() << 24 << -74;
    QVERIFY(QMetaObject::invokeMethod(&iface, "ping", Q_RETURN_ARG(QList<int>, retArg), Q_ARG(QList<int>, arg2)));
    QCOMPARE(MyObject::callCount, 2);

    // verify what the callee received
    QCOMPARE(MyObject::callArgs.count(), 1);
    v = MyObject::callArgs.at(0);
    QCOMPARE(v.userType(), qMetaTypeId<QDBusArgument>());
    QCOMPARE(qdbus_cast<QList<int> >(v), arg2);

    // verify that we got the reply as expected
    QCOMPARE(retArg, arg2);
}

void tst_QDBusInterface::introspectPeer()
{
    QDBusConnection con("peer");
    QDBusInterface iface(QString(), QLatin1String("/"),
                         TEST_INTERFACE_NAME, con);

    const QMetaObject *mo = iface.metaObject();

    QCOMPARE(mo->methodCount() - mo->methodOffset(), 7);
    QVERIFY(mo->indexOfSignal(TEST_SIGNAL_NAME "(QString)") != -1);

    QCOMPARE(mo->propertyCount() - mo->propertyOffset(), 2);
    QVERIFY(mo->indexOfProperty("prop1") != -1);
    QVERIFY(mo->indexOfProperty("complexProp") != -1);
}

void tst_QDBusInterface::callMethodPeer()
{
    QDBusConnection con("peer");
    QDBusInterface iface(QString(), QLatin1String("/"),
                         TEST_INTERFACE_NAME, con);

    resetPeer();

    // call a SLOT method
    QDBusMessage reply = iface.call("ping", QVariant::fromValue(QDBusVariant("foo")));
    QCOMPARE(callCountPeer(), 1);
    QCOMPARE(reply.type(), QDBusMessage::ReplyMessage);

    // verify what the callee received
    QVariantList callArgs = callArgsPeer();
    QCOMPARE(callArgs.count(), 1);
    QVariant v = callArgs.at(0);
    QDBusVariant dv = qdbus_cast<QDBusVariant>(v);
    QCOMPARE(dv.variant().type(), QVariant::String);
    QCOMPARE(dv.variant().toString(), QString("foo"));

    // verify reply
    QCOMPARE(reply.arguments().count(), 1);
    v = reply.arguments().at(0);
    dv = qdbus_cast<QDBusVariant>(v);
    QCOMPARE(dv.variant().type(), QVariant::String);
    QCOMPARE(dv.variant().toString(), QString("foo"));

    // call an INVOKABLE method
    reply = iface.call("ping_invokable", QVariant::fromValue(QDBusVariant("bar")));
    QCOMPARE(callCountPeer(), 2);
    QCOMPARE(reply.type(), QDBusMessage::ReplyMessage);

    // verify what the callee received
    callArgs = callArgsPeer();
    QCOMPARE(callArgs.count(), 1);
    v = callArgs.at(0);
    dv = qdbus_cast<QDBusVariant>(v);
    QCOMPARE(dv.variant().type(), QVariant::String);
    QCOMPARE(dv.variant().toString(), QString("bar"));

    // verify reply
    QCOMPARE(reply.arguments().count(), 1);
    v = reply.arguments().at(0);
    dv = qdbus_cast<QDBusVariant>(v);
    QCOMPARE(dv.variant().type(), QVariant::String);
    QCOMPARE(dv.variant().toString(), QString("bar"));
}

void tst_QDBusInterface::invokeMethodPeer()
{
    QDBusConnection con("peer");
    QDBusInterface iface(QString(), QLatin1String("/"),
                         TEST_INTERFACE_NAME, con);

    resetPeer();

    // make the SLOT call without a return type
    QDBusVariant arg("foo");
    QVERIFY(QMetaObject::invokeMethod(&iface, "ping", Q_ARG(QDBusVariant, arg)));
    QCOMPARE(callCountPeer(), 1);

    // verify what the callee received
    QVariantList callArgs = callArgsPeer();
    QCOMPARE(callArgs.count(), 1);
    QVariant v = callArgs.at(0);
    QDBusVariant dv = qdbus_cast<QDBusVariant>(v);
    QCOMPARE(dv.variant().type(), QVariant::String);
    QCOMPARE(dv.variant().toString(), QString("foo"));

    // make the INVOKABLE call without a return type
    QDBusVariant arg2("bar");
    QVERIFY(QMetaObject::invokeMethod(&iface, "ping_invokable", Q_ARG(QDBusVariant, arg2)));
    QCOMPARE(callCountPeer(), 2);

    // verify what the callee received
    callArgs = callArgsPeer();
    QCOMPARE(callArgs.count(), 1);
    v = callArgs.at(0);
    dv = qdbus_cast<QDBusVariant>(v);
    QCOMPARE(dv.variant().type(), QVariant::String);
    QCOMPARE(dv.variant().toString(), QString("bar"));
}

void tst_QDBusInterface::invokeMethodWithReturnPeer()
{
    QDBusConnection con("peer");
    QDBusInterface iface(QString(), QLatin1String("/"),
                         TEST_INTERFACE_NAME, con);

    resetPeer();
    QDBusVariant retArg;

    // make the SLOT call without a return type
    QDBusVariant arg("foo");
    QVERIFY(QMetaObject::invokeMethod(&iface, "ping", Q_RETURN_ARG(QDBusVariant, retArg), Q_ARG(QDBusVariant, arg)));
    QCOMPARE(callCountPeer(), 1);

    // verify what the callee received
    QVariantList callArgs = callArgsPeer();
    QCOMPARE(callArgs.count(), 1);
    QVariant v = callArgs.at(0);
    QDBusVariant dv = qdbus_cast<QDBusVariant>(v);
    QCOMPARE(dv.variant().type(), QVariant::String);
    QCOMPARE(dv.variant().toString(), arg.variant().toString());

    // verify that we got the reply as expected
    QCOMPARE(retArg.variant(), arg.variant());

    // make the INVOKABLE call without a return type
    QDBusVariant arg2("bar");
    QVERIFY(QMetaObject::invokeMethod(&iface, "ping_invokable", Q_RETURN_ARG(QDBusVariant, retArg), Q_ARG(QDBusVariant, arg2)));
    QCOMPARE(callCountPeer(), 2);

    // verify what the callee received
    callArgs = callArgsPeer();
    QCOMPARE(callArgs.count(), 1);
    v = callArgs.at(0);
    dv = qdbus_cast<QDBusVariant>(v);
    QCOMPARE(dv.variant().type(), QVariant::String);
    QCOMPARE(dv.variant().toString(), arg2.variant().toString());

    // verify that we got the reply as expected
    QCOMPARE(retArg.variant(), arg2.variant());
}

void tst_QDBusInterface::invokeMethodWithMultiReturnPeer()
{
    QDBusConnection con("peer");
    QDBusInterface iface(QString(), QLatin1String("/"),
                         TEST_INTERFACE_NAME, con);

    resetPeer();
    QDBusVariant retArg, retArg2;

    // make the SLOT call without a return type
    QDBusVariant arg("foo"), arg2("bar");
    QVERIFY(QMetaObject::invokeMethod(&iface, "ping",
                                      Q_RETURN_ARG(QDBusVariant, retArg),
                                      Q_ARG(QDBusVariant, arg),
                                      Q_ARG(QDBusVariant, arg2),
                                      Q_ARG(QDBusVariant&, retArg2)));
    QCOMPARE(callCountPeer(), 1);

    // verify what the callee received
    QVariantList callArgs = callArgsPeer();
    QCOMPARE(callArgs.count(), 2);
    QVariant v = callArgs.at(0);
    QDBusVariant dv = qdbus_cast<QDBusVariant>(v);
    QCOMPARE(dv.variant().type(), QVariant::String);
    QCOMPARE(dv.variant().toString(), arg.variant().toString());

    v = callArgs.at(1);
    dv = qdbus_cast<QDBusVariant>(v);
    QCOMPARE(dv.variant().type(), QVariant::String);
    QCOMPARE(dv.variant().toString(), arg2.variant().toString());

    // verify that we got the replies as expected
    QCOMPARE(retArg.variant(), arg.variant());
    QCOMPARE(retArg2.variant(), arg2.variant());

    // make the INVOKABLE call without a return type
    QDBusVariant arg3("hello"), arg4("world");
    QVERIFY(QMetaObject::invokeMethod(&iface, "ping_invokable",
                                      Q_RETURN_ARG(QDBusVariant, retArg),
                                      Q_ARG(QDBusVariant, arg3),
                                      Q_ARG(QDBusVariant, arg4),
                                      Q_ARG(QDBusVariant&, retArg2)));
    QCOMPARE(callCountPeer(), 2);

    // verify what the callee received
    callArgs = callArgsPeer();
    QCOMPARE(callArgs.count(), 2);
    v = callArgs.at(0);
    dv = qdbus_cast<QDBusVariant>(v);
    QCOMPARE(dv.variant().type(), QVariant::String);
    QCOMPARE(dv.variant().toString(), arg3.variant().toString());

    v = callArgs.at(1);
    dv = qdbus_cast<QDBusVariant>(v);
    QCOMPARE(dv.variant().type(), QVariant::String);
    QCOMPARE(dv.variant().toString(), arg4.variant().toString());

    // verify that we got the replies as expected
    QCOMPARE(retArg.variant(), arg3.variant());
    QCOMPARE(retArg2.variant(), arg4.variant());
}

void tst_QDBusInterface::invokeMethodWithComplexReturnPeer()
{
    QDBusConnection con("peer");
    QDBusInterface iface(QString(), QLatin1String("/"),
                         TEST_INTERFACE_NAME, con);

    resetPeer();
    QList<int> retArg;

    // make the SLOT call without a return type
    QList<int> arg = QList<int>() << 42 << -47;
    QVERIFY(QMetaObject::invokeMethod(&iface, "ping", Q_RETURN_ARG(QList<int>, retArg), Q_ARG(QList<int>, arg)));
    QCOMPARE(callCountPeer(), 1);

    // verify what the callee received
    QVariantList callArgs = callArgsPeer();
    QCOMPARE(callArgs.count(), 1);
    QVariant v = callArgs.at(0);
    QCOMPARE(v.userType(), qMetaTypeId<QDBusArgument>());
    QCOMPARE(qdbus_cast<QList<int> >(v), arg);

    // verify that we got the reply as expected
    QCOMPARE(retArg, arg);

    // make the INVOKABLE call without a return type
    QList<int> arg2 = QList<int>() << 24 << -74;
    QVERIFY(QMetaObject::invokeMethod(&iface, "ping", Q_RETURN_ARG(QList<int>, retArg), Q_ARG(QList<int>, arg2)));
    QCOMPARE(callCountPeer(), 2);

    // verify what the callee received
    callArgs = callArgsPeer();
    QCOMPARE(callArgs.count(), 1);
    v = callArgs.at(0);
    QCOMPARE(v.userType(), qMetaTypeId<QDBusArgument>());
    QCOMPARE(qdbus_cast<QList<int> >(v), arg2);

    // verify that we got the reply as expected
    QCOMPARE(retArg, arg2);
}

void tst_QDBusInterface::signal()
{
    QDBusConnection con = QDBusConnection::sessionBus();
    QDBusInterface iface(QDBusConnection::sessionBus().baseService(), QLatin1String("/"),
                         TEST_INTERFACE_NAME);

    QString arg = "So long and thanks for all the fish";
    {
        Spy spy;
        spy.connect(&iface, SIGNAL(somethingHappened(QString)), SLOT(spySlot(QString)));

        emitSignal(TEST_INTERFACE_NAME, TEST_SIGNAL_NAME, arg);
        QCOMPARE(spy.count, 1);
        QCOMPARE(spy.received, arg);
    }

    QDBusInterface iface2(QDBusConnection::sessionBus().baseService(), QLatin1String("/"),
                          TEST_INTERFACE_NAME);
    {
        Spy spy;
        spy.connect(&iface, SIGNAL(somethingHappened(QString)), SLOT(spySlot(QString)));
        spy.connect(&iface2, SIGNAL(somethingHappened(QString)), SLOT(spySlot(QString)));

        emitSignal(TEST_INTERFACE_NAME, TEST_SIGNAL_NAME, arg);
        QCOMPARE(spy.count, 2);
        QCOMPARE(spy.received, arg);
    }

    {
        Spy spy, spy2;
        spy.connect(&iface, SIGNAL(somethingHappened(QString)), SLOT(spySlot(QString)));
        spy2.connect(&iface2, SIGNAL(somethingHappened(QString)), SLOT(spySlot(QString)));

        emitSignal(TEST_INTERFACE_NAME, TEST_SIGNAL_NAME, arg);
        QCOMPARE(spy.count, 1);
        QCOMPARE(spy.received, arg);
        QCOMPARE(spy2.count, 1);
        QCOMPARE(spy2.received, arg);
    }
}

void tst_QDBusInterface::signalPeer()
{
    QDBusConnection con("peer");
    QDBusInterface iface(QString(), QLatin1String("/"),
                         TEST_INTERFACE_NAME, con);

    QString arg = "So long and thanks for all the fish";
    {
        Spy spy;
        spy.connect(&iface, SIGNAL(somethingHappened(QString)), SLOT(spySlot(QString)));

        emitSignalPeer(TEST_INTERFACE_NAME, TEST_SIGNAL_NAME, arg);
        QCOMPARE(spy.count, 1);
        QCOMPARE(spy.received, arg);
    }

    QDBusInterface iface2(QString(), QLatin1String("/"),
                          TEST_INTERFACE_NAME, con);
    {
        Spy spy;
        spy.connect(&iface, SIGNAL(somethingHappened(QString)), SLOT(spySlot(QString)));
        spy.connect(&iface2, SIGNAL(somethingHappened(QString)), SLOT(spySlot(QString)));

        emitSignalPeer(TEST_INTERFACE_NAME, TEST_SIGNAL_NAME, arg);
        QCOMPARE(spy.count, 2);
        QCOMPARE(spy.received, arg);
    }

    {
        Spy spy, spy2;
        spy.connect(&iface, SIGNAL(somethingHappened(QString)), SLOT(spySlot(QString)));
        spy2.connect(&iface2, SIGNAL(somethingHappened(QString)), SLOT(spySlot(QString)));

        emitSignalPeer(TEST_INTERFACE_NAME, TEST_SIGNAL_NAME, arg);
        QCOMPARE(spy.count, 1);
        QCOMPARE(spy.received, arg);
        QCOMPARE(spy2.count, 1);
        QCOMPARE(spy2.received, arg);
    }
}

void tst_QDBusInterface::propertyRead()
{
    QDBusConnection con = QDBusConnection::sessionBus();
    QDBusInterface iface(QDBusConnection::sessionBus().baseService(), QLatin1String("/"),
                         TEST_INTERFACE_NAME);

    int arg = obj.m_prop1 = 42;
    MyObject::callCount = 0;

    QVariant v = iface.property("prop1");
    QVERIFY(v.isValid());
    QCOMPARE(v.userType(), int(QVariant::Int));
    QCOMPARE(v.toInt(), arg);
    QCOMPARE(MyObject::callCount, 1);
}

void tst_QDBusInterface::propertyWrite()
{
    QDBusConnection con = QDBusConnection::sessionBus();
    QDBusInterface iface(QDBusConnection::sessionBus().baseService(), QLatin1String("/"),
                         TEST_INTERFACE_NAME);

    int arg = 42;
    obj.m_prop1 = 0;
    MyObject::callCount = 0;

    QVERIFY(iface.setProperty("prop1", arg));
    QCOMPARE(MyObject::callCount, 1);
    QCOMPARE(obj.m_prop1, arg);
}

void tst_QDBusInterface::complexPropertyRead()
{
    QDBusConnection con = QDBusConnection::sessionBus();
    QDBusInterface iface(QDBusConnection::sessionBus().baseService(), QLatin1String("/"),
                         TEST_INTERFACE_NAME);

    QList<int> arg = obj.m_complexProp = QList<int>() << 42 << -47;
    MyObject::callCount = 0;

    QVariant v = iface.property("complexProp");
    QVERIFY(v.isValid());
    QCOMPARE(v.userType(), qMetaTypeId<QList<int> >());
    QCOMPARE(v.value<QList<int> >(), arg);
    QCOMPARE(MyObject::callCount, 1);
}

void tst_QDBusInterface::complexPropertyWrite()
{
    QDBusConnection con = QDBusConnection::sessionBus();
    QDBusInterface iface(QDBusConnection::sessionBus().baseService(), QLatin1String("/"),
                         TEST_INTERFACE_NAME);

    QList<int> arg = QList<int>() << -47 << 42;
    obj.m_complexProp.clear();
    MyObject::callCount = 0;

    QVERIFY(iface.setProperty("complexProp", QVariant::fromValue(arg)));
    QCOMPARE(MyObject::callCount, 1);
    QCOMPARE(obj.m_complexProp, arg);
}

void tst_QDBusInterface::propertyReadPeer()
{
    QDBusConnection con("peer");
    QDBusInterface iface(QString(), QLatin1String("/"),
                         TEST_INTERFACE_NAME, con);

    resetPeer();
    int arg = 42;
    setProp1Peer(42);

    QVariant v = iface.property("prop1");
    QVERIFY(v.isValid());
    QCOMPARE(v.userType(), int(QVariant::Int));
    QCOMPARE(v.toInt(), arg);
    QCOMPARE(callCountPeer(), 1);
}

void tst_QDBusInterface::propertyWritePeer()
{
    QDBusConnection con("peer");
    QDBusInterface iface(QString(), QLatin1String("/"),
                         TEST_INTERFACE_NAME, con);

    resetPeer();
    int arg = 42;
    setProp1Peer(0);

    QVERIFY(iface.setProperty("prop1", arg));
    QCOMPARE(callCountPeer(), 1);
    QCOMPARE(prop1Peer(), arg);
}

void tst_QDBusInterface::complexPropertyReadPeer()
{
    QDBusConnection con("peer");
    QDBusInterface iface(QString(), QLatin1String("/"),
                         TEST_INTERFACE_NAME, con);

    resetPeer();
    QList<int> arg = QList<int>() << 42 << -47;
    setComplexPropPeer(arg);

    QVariant v = iface.property("complexProp");
    QVERIFY(v.isValid());
    QCOMPARE(v.userType(), qMetaTypeId<QList<int> >());
    QCOMPARE(v.value<QList<int> >(), arg);
    QCOMPARE(callCountPeer(), 1);
}

void tst_QDBusInterface::complexPropertyWritePeer()
{
    QDBusConnection con("peer");
    QDBusInterface iface(QString(), QLatin1String("/"),
                         TEST_INTERFACE_NAME, con);

    resetPeer();
    QList<int> arg = QList<int>() << -47 << 42;

    QVERIFY(iface.setProperty("complexProp", QVariant::fromValue(arg)));
    QCOMPARE(callCountPeer(), 1);
    QCOMPARE(complexPropPeer(), arg);
}

void tst_QDBusInterface::interactiveAuthorizationRequired()
{
    int major;
    int minor;
    int micro;
    q_dbus_get_version(&major, &minor, &micro);

    QVersionNumber dbusVersion(major, minor, micro);
    if (dbusVersion < QVersionNumber(1, 9, 2))
        QSKIP("Your DBus library is too old to support interactive authorization");

    QDBusMessage req = QDBusMessage::createMethodCall(serviceName, objectPath, interfaceName, "interactiveAuthorization");
    QDBusMessage reply = QDBusConnection::sessionBus().call(req);

    QCOMPARE(reply.type(), QDBusMessage::ErrorMessage);
    QCOMPARE(reply.errorName(), QStringLiteral("org.freedesktop.DBus.Error.InteractiveAuthorizationRequired"));

    req.setInteractiveAuthorizationAllowed(true);
    reply = QDBusConnection::sessionBus().call(req);

    QCOMPARE(reply.type(), QDBusMessage::ReplyMessage);
    QVERIFY(reply.arguments().at(0).toBool());
}

QTEST_MAIN(tst_QDBusInterface)

#include "tst_qdbusinterface.moc"
