/****************************************************************************
**
** Copyright (C) 2016 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.com, author Milian Wolff <milian.wolff@kdab.com>
** Contact: https://www.qt.io/licensing/
**
** This file is part of the QtWebChannel 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$
**
****************************************************************************/

#ifndef SIGNALHANDLER_H
#define SIGNALHANDLER_H

//
//  W A R N I N G
//  -------------
//
// This file is not part of the Qt API.  It exists purely as an
// implementation detail.  This header file may change from version to
// version without notice, or even be removed.
//
// We mean it.
//

#include <QObject>
#include <QHash>
#include <QVector>
#include <QMetaMethod>
#include <QDebug>

QT_BEGIN_NAMESPACE

static const int s_destroyedSignalIndex = QObject::staticMetaObject.indexOfMethod("destroyed(QObject*)");

/**
 * The signal handler is similar to QSignalSpy, but geared towards the usecase of the web channel.
 *
 * It allows connecting to any number of signals of arbitrary objects and forwards the signal
 * invocations to the Receiver by calling its signalEmitted function, which takes the object,
 * signal index and a QVariantList of arguments.
 */
template<class Receiver>
class SignalHandler : public QObject
{
public:
    SignalHandler(Receiver *receiver, QObject *parent = 0);

    /**
     * Connect to a signal of @p object identified by @p signalIndex.
     *
     * If the handler is already connected to the signal, an internal counter is increased,
     * i.e. the handler never connects multiple times to the same signal.
     */
    void connectTo(const QObject *object, const int signalIndex);

    /**
     * Decrease the connection counter for the connection to the given signal.
     *
     * When the counter drops to zero, the connection is disconnected.
     */
    void disconnectFrom(const QObject *object, const int signalIndex);

    /**
     * @internal
     *
     * Custom implementation of qt_metacall which calls dispatch() for connected signals.
     */
    int qt_metacall(QMetaObject::Call call, int methodId, void **args) override;

    /**
     * Reset all connections, useful for benchmarks.
     */
    void clear();

    /**
     * Fully remove and disconnect an object from handler
     */
    void remove(const QObject *object);

private:
    /**
     * Exctract the arguments of a signal call and pass them to the receiver.
     *
     * The @p argumentData is converted to a QVariantList and then passed to the receiver's
     * signalEmitted method.
     */
    void dispatch(const QObject *object, const int signalIdx, void **argumentData);

    void setupSignalArgumentTypes(const QMetaObject *metaObject, const QMetaMethod &signal);

    Receiver *m_receiver;

    // maps meta object -> signalIndex -> list of arguments
    // NOTE: This data is "leaked" on disconnect until deletion of the handler, is this a problem?
    typedef QVector<int> ArgumentTypeList;
    typedef QHash<int, ArgumentTypeList> SignalArgumentHash;
    QHash<const QMetaObject *, SignalArgumentHash > m_signalArgumentTypes;

    /*
     * Tracks how many connections are active to object signals.
     *
     * Maps object -> signalIndex -> pair of connection and number of connections
     *
     * Note that the handler is connected to the signal only once, whereas clients
     * may have connected multiple times.
     *
     * TODO: Move more of this logic to the HTML client side, esp. the connection counting.
     */
    typedef QPair<QMetaObject::Connection, int> ConnectionPair;
    typedef QHash<int, ConnectionPair> SignalConnectionHash;
    typedef QHash<const QObject*, SignalConnectionHash> ConnectionHash;
    ConnectionHash m_connectionsCounter;
};

template<class Receiver>
SignalHandler<Receiver>::SignalHandler(Receiver *receiver, QObject *parent)
    : QObject(parent)
    , m_receiver(receiver)
{
    // we must know the arguments of a destroyed signal for the global static meta object of QObject
    // otherwise, we might end up with missing m_signalArgumentTypes information in dispatch
    setupSignalArgumentTypes(&QObject::staticMetaObject, QObject::staticMetaObject.method(s_destroyedSignalIndex));
}

/**
 * Find and return the signal of index @p signalIndex in the meta object of @p object and return it.
 *
 * The return value is also verified to ensure it is a signal.
 */
inline QMetaMethod findSignal(const QMetaObject *metaObject, const int signalIndex)
{
    QMetaMethod signal = metaObject->method(signalIndex);
    if (!signal.isValid()) {
        qWarning("Cannot find signal with index %d of object %s", signalIndex, metaObject->className());
        return QMetaMethod();
    }
    Q_ASSERT(signal.methodType() == QMetaMethod::Signal);
    return signal;
}

template<class Receiver>
void SignalHandler<Receiver>::connectTo(const QObject *object, const int signalIndex)
{
    const QMetaObject *metaObject = object->metaObject();
    const QMetaMethod &signal = findSignal(metaObject, signalIndex);
    if (!signal.isValid()) {
        return;
    }

    ConnectionPair &connectionCounter = m_connectionsCounter[object][signalIndex];
    if (connectionCounter.first) {
        // increase connection counter if already connected
        ++connectionCounter.second;
        return;
    } // otherwise not yet connected, do so now

    static const int memberOffset = QObject::staticMetaObject.methodCount();
    QMetaObject::Connection connection = QMetaObject::connect(object, signal.methodIndex(), this, memberOffset + signalIndex, Qt::AutoConnection, 0);
    if (!connection) {
        qWarning() << "SignalHandler: QMetaObject::connect returned false. Unable to connect to" << object << signal.name() << signal.methodSignature();
        return;
    }
    connectionCounter.first = connection;
    connectionCounter.second = 1;

    setupSignalArgumentTypes(metaObject, signal);
}

template<class Receiver>
void SignalHandler<Receiver>::setupSignalArgumentTypes(const QMetaObject *metaObject, const QMetaMethod &signal)
{
    if (m_signalArgumentTypes.value(metaObject).contains(signal.methodIndex())) {
        return;
    }
    // find the type ids of the signal parameters, see also QSignalSpy::initArgs
    QVector<int> args;
    args.reserve(signal.parameterCount());
    for (int i = 0; i < signal.parameterCount(); ++i) {
        int tp = signal.parameterType(i);
        if (tp == QMetaType::UnknownType) {
            qWarning("Don't know how to handle '%s', use qRegisterMetaType to register it.",
                    signal.parameterNames().at(i).constData());
        }
        args << tp;
    }

    m_signalArgumentTypes[metaObject][signal.methodIndex()] = args;
}

template<class Receiver>
void SignalHandler<Receiver>::dispatch(const QObject *object, const int signalIdx, void **argumentData)
{
    Q_ASSERT(m_signalArgumentTypes.contains(object->metaObject()));
    const QHash<int, QVector<int> > &objectSignalArgumentTypes = m_signalArgumentTypes.value(object->metaObject());
    QHash<int, QVector<int> >::const_iterator signalIt = objectSignalArgumentTypes.constFind(signalIdx);
    if (signalIt == objectSignalArgumentTypes.constEnd()) {
        // not connected to this signal, skip
        return;
    }
    const QVector<int> &argumentTypes = *signalIt;
    QVariantList arguments;
    arguments.reserve(argumentTypes.count());
    // TODO: basic overload resolution based on number of arguments?
    for (int i = 0; i < argumentTypes.count(); ++i) {
        const QMetaType::Type type = static_cast<QMetaType::Type>(argumentTypes.at(i));
        QVariant arg;
        if (type == QMetaType::QVariant) {
            arg = *reinterpret_cast<QVariant *>(argumentData[i + 1]);
        } else {
            arg = QVariant(type, argumentData[i + 1]);
        }
        arguments.append(arg);
    }
    m_receiver->signalEmitted(object, signalIdx, arguments);
}

template<class Receiver>
void SignalHandler<Receiver>::disconnectFrom(const QObject *object, const int signalIndex)
{
    Q_ASSERT(m_connectionsCounter.value(object).contains(signalIndex));
    ConnectionPair &connection = m_connectionsCounter[object][signalIndex];
    --connection.second;
    if (!connection.second || !connection.first) {
        QObject::disconnect(connection.first);
        m_connectionsCounter[object].remove(signalIndex);
        if (m_connectionsCounter[object].isEmpty()) {
            m_connectionsCounter.remove(object);
        }
    }
}

template<class Receiver>
int SignalHandler<Receiver>::qt_metacall(QMetaObject::Call call, int methodId, void **args)
{
    methodId = QObject::qt_metacall(call, methodId, args);
    if (methodId < 0)
        return methodId;

    if (call == QMetaObject::InvokeMetaMethod) {
        const QObject *object = sender();
        Q_ASSERT(object);
        Q_ASSERT(senderSignalIndex() == methodId);
        Q_ASSERT(m_connectionsCounter.contains(object));
        Q_ASSERT(m_connectionsCounter.value(object).contains(methodId));

        dispatch(object, methodId, args);

        return -1;
    }
    return methodId;
}

template<class Receiver>
void SignalHandler<Receiver>::clear()
{
    foreach (const SignalConnectionHash &connections, m_connectionsCounter) {
        foreach (const ConnectionPair &connection, connections) {
            QObject::disconnect(connection.first);
        }
    }
    m_connectionsCounter.clear();
    const SignalArgumentHash keep = m_signalArgumentTypes.take(&QObject::staticMetaObject);
    m_signalArgumentTypes.clear();
    m_signalArgumentTypes[&QObject::staticMetaObject] = keep;
}

template<class Receiver>
void SignalHandler<Receiver>::remove(const QObject *object)
{
    Q_ASSERT(m_connectionsCounter.contains(object));
    const SignalConnectionHash &connections = m_connectionsCounter.value(object);
    foreach (const ConnectionPair &connection, connections) {
        QObject::disconnect(connection.first);
    }
    m_connectionsCounter.remove(object);
}

QT_END_NAMESPACE

#endif // SIGNALHANDLER_H
