/****************************************************************************
**
** Copyright (C) 2016 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the QtQml 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 "qqmlconnections_p.h"

#include <private/qqmlexpression_p.h>
#include <private/qqmlproperty_p.h>
#include <private/qqmlboundsignal_p.h>
#include <qqmlcontext.h>
#include <private/qqmlcontext_p.h>
#include <private/qqmlvmemetaobject_p.h>
#include <qqmlinfo.h>

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

#include <private/qobject_p.h>

QT_BEGIN_NAMESPACE

class QQmlConnectionsPrivate : public QObjectPrivate
{
public:
    QQmlConnectionsPrivate() : target(nullptr), enabled(true), targetSet(false), ignoreUnknownSignals(false), componentcomplete(true) {}

    QList<QQmlBoundSignal*> boundsignals;
    QObject *target;

    bool enabled;
    bool targetSet;
    bool ignoreUnknownSignals;
    bool componentcomplete;

    QQmlRefPointer<QV4::ExecutableCompilationUnit> compilationUnit;
    QList<const QV4::CompiledData::Binding *> bindings;
};

/*!
    \qmltype Connections
    \instantiates QQmlConnections
    \inqmlmodule QtQml
    \ingroup qtquick-interceptors
    \brief Describes generalized connections to signals.

    A Connections object creates a connection to a QML signal.

    When connecting to signals in QML, the usual way is to create an
    "on<Signal>" handler that reacts when a signal is received, like this:

    \qml
    MouseArea {
        onClicked: { foo(parameters) }
    }
    \endqml

    However, it is not possible to connect to a signal in this way in some
    cases, such as when:

    \list
        \li Multiple connections to the same signal are required
        \li Creating connections outside the scope of the signal sender
        \li Connecting to targets not defined in QML
    \endlist

    When any of these are needed, the Connections type can be used instead.

    For example, the above code can be changed to use a Connections object,
    like this:

    \qml
    MouseArea {
        Connections {
            function onClicked(mouse) { foo(mouse) }
        }
    }
    \endqml

    More generally, the Connections object can be a child of some object other than
    the sender of the signal:

    \qml
    MouseArea {
        id: area
    }
    // ...
    \endqml
    \qml
    Connections {
        target: area
        function onClicked(mouse) { foo(mouse) }
    }
    \endqml

    \sa {Qt QML}
*/
QQmlConnections::QQmlConnections(QObject *parent) :
    QObject(*(new QQmlConnectionsPrivate), parent)
{
}

QQmlConnections::~QQmlConnections()
{
}

/*!
    \qmlproperty Object QtQml::Connections::target
    This property holds the object that sends the signal.

    If this property is not set, the \c target defaults to the parent of the Connection.

    If set to null, no connection is made and any signal handlers are ignored
    until the target is not null.
*/
QObject *QQmlConnections::target() const
{
    Q_D(const QQmlConnections);
    return d->targetSet ? d->target : parent();
}

class QQmlBoundSignalDeleter : public QObject
{
public:
    QQmlBoundSignalDeleter(QQmlBoundSignal *signal) : m_signal(signal) { m_signal->removeFromObject(); }
    ~QQmlBoundSignalDeleter() { delete m_signal; }

private:
    QQmlBoundSignal *m_signal;
};

void QQmlConnections::setTarget(QObject *obj)
{
    Q_D(QQmlConnections);
    if (d->targetSet && d->target == obj)
        return;
    d->targetSet = true; // even if setting to 0, it is *set*
    for (QQmlBoundSignal *s : qAsConst(d->boundsignals)) {
        // It is possible that target is being changed due to one of our signal
        // handlers -> use deleteLater().
        if (s->isNotifying())
            (new QQmlBoundSignalDeleter(s))->deleteLater();
        else
            delete s;
    }
    d->boundsignals.clear();
    d->target = obj;
    connectSignals();
    emit targetChanged();
}

/*!
    \qmlproperty bool QtQml::Connections::enabled
    \since 5.7

    This property holds whether the item accepts change events.

    By default, this property is \c true.
*/
bool QQmlConnections::isEnabled() const
{
    Q_D(const QQmlConnections);
    return d->enabled;
}

void QQmlConnections::setEnabled(bool enabled)
{
    Q_D(QQmlConnections);
    if (d->enabled == enabled)
        return;

    d->enabled = enabled;

    for (QQmlBoundSignal *s : qAsConst(d->boundsignals))
        s->setEnabled(d->enabled);

    emit enabledChanged();
}

/*!
    \qmlproperty bool QtQml::Connections::ignoreUnknownSignals

    Normally, a connection to a non-existent signal produces runtime errors.

    If this property is set to \c true, such errors are ignored.
    This is useful if you intend to connect to different types of objects, handling
    a different set of signals for each object.
*/
bool QQmlConnections::ignoreUnknownSignals() const
{
    Q_D(const QQmlConnections);
    return d->ignoreUnknownSignals;
}

void QQmlConnections::setIgnoreUnknownSignals(bool ignore)
{
    Q_D(QQmlConnections);
    d->ignoreUnknownSignals = ignore;
}

void QQmlConnectionsParser::verifyBindings(const QQmlRefPointer<QV4::ExecutableCompilationUnit> &compilationUnit, const QList<const QV4::CompiledData::Binding *> &props)
{
    for (int ii = 0; ii < props.count(); ++ii) {
        const QV4::CompiledData::Binding *binding = props.at(ii);
        const QString &propName = compilationUnit->stringAt(binding->propertyNameIndex);

        if (!propName.startsWith(QLatin1String("on")) || (propName.length() < 3 || !propName.at(2).isUpper())) {
            error(props.at(ii), QQmlConnections::tr("Cannot assign to non-existent property \"%1\"").arg(propName));
            return;
        }

        if (binding->type >= QV4::CompiledData::Binding::Type_Object) {
            const QV4::CompiledData::Object *target = compilationUnit->objectAt(binding->value.objectIndex);
            if (!compilationUnit->stringAt(target->inheritedTypeNameIndex).isEmpty())
                error(binding, QQmlConnections::tr("Connections: nested objects not allowed"));
            else
                error(binding, QQmlConnections::tr("Connections: syntax error"));
            return;
        } if (binding->type != QV4::CompiledData::Binding::Type_Script) {
            error(binding, QQmlConnections::tr("Connections: script expected"));
            return;
        }
    }
}

void QQmlConnectionsParser::applyBindings(QObject *object, const QQmlRefPointer<QV4::ExecutableCompilationUnit> &compilationUnit, const QList<const QV4::CompiledData::Binding *> &bindings)
{
    QQmlConnectionsPrivate *p =
        static_cast<QQmlConnectionsPrivate *>(QObjectPrivate::get(object));
    p->compilationUnit = compilationUnit;
    p->bindings = bindings;
}

void QQmlConnections::connectSignals()
{
    Q_D(QQmlConnections);
    if (!d->componentcomplete || (d->targetSet && !target()))
        return;

    if (d->bindings.isEmpty()) {
        connectSignalsToMethods();
    } else {
#if QT_VERSION >= QT_VERSION_CHECK(5, 15, 0)
        qmlWarning(this) << tr("Implicitly defined onFoo properties in Connections are deprecated. "
                               "Use this syntax instead: function onFoo(<arguments>) { ... }");
#endif
        connectSignalsToBindings();
    }
}

void QQmlConnections::connectSignalsToMethods()
{
    Q_D(QQmlConnections);

    QObject *target = this->target();
    QQmlData *ddata = QQmlData::get(this);
    if (!ddata)
        return;

    QV4::ExecutionEngine *engine = ddata->context->engine->handle();

    QQmlContextData *ctxtdata = ddata->outerContext;
    for (int i = ddata->propertyCache->methodOffset(),
             end = ddata->propertyCache->methodOffset() + ddata->propertyCache->methodCount();
         i < end;
         ++i) {

        QQmlPropertyData *handler = ddata->propertyCache->method(i);
        if (!handler || !handler->isVMEFunction())
            continue;

        const QString propName = handler->name(this);

        QQmlProperty prop(target, propName);
        if (prop.isValid() && (prop.type() & QQmlProperty::SignalProperty)) {
            int signalIndex = QQmlPropertyPrivate::get(prop)->signalIndex();
            auto *signal = new QQmlBoundSignal(target, signalIndex, this, qmlEngine(this));
            signal->setEnabled(d->enabled);

            QV4::Scope scope(engine);
            QV4::ScopedContext global(scope, engine->rootContext());

            QQmlVMEMetaObject *vmeMetaObject = QQmlVMEMetaObject::get(this);
            Q_ASSERT(vmeMetaObject); // the fact we found the property above should guarentee this

            QV4::ScopedFunctionObject method(scope, vmeMetaObject->vmeMethod(handler->coreIndex()));

            QQmlBoundSignalExpression *expression =
                    ctxtdata ? new QQmlBoundSignalExpression(
                                       target, signalIndex, ctxtdata, this,
                                       method->as<QV4::FunctionObject>()->function())
                             : nullptr;

            signal->takeExpression(expression);
            d->boundsignals += signal;
        } else if (!d->ignoreUnknownSignals
                   && propName.startsWith(QLatin1String("on")) && propName.length() > 2
                   && propName.at(2).isUpper()) {
            qmlWarning(this) << tr("Detected function \"%1\" in Connections element. "
                                   "This is probably intended to be a signal handler but no "
                                   "signal of the target matches the name.").arg(propName);
        }
    }
}

// TODO: Drop this as soon as we can
void QQmlConnections::connectSignalsToBindings()
{
    Q_D(QQmlConnections);
    QObject *target = this->target();
    QQmlData *ddata = QQmlData::get(this);
    QQmlContextData *ctxtdata = ddata ? ddata->outerContext : nullptr;

    for (const QV4::CompiledData::Binding *binding : qAsConst(d->bindings)) {
        Q_ASSERT(binding->type == QV4::CompiledData::Binding::Type_Script);
        QString propName = d->compilationUnit->stringAt(binding->propertyNameIndex);

        QQmlProperty prop(target, propName);
        if (prop.isValid() && (prop.type() & QQmlProperty::SignalProperty)) {
            int signalIndex = QQmlPropertyPrivate::get(prop)->signalIndex();
            QQmlBoundSignal *signal =
                new QQmlBoundSignal(target, signalIndex, this, qmlEngine(this));
            signal->setEnabled(d->enabled);

            auto f = d->compilationUnit->runtimeFunctions[binding->value.compiledScriptIndex];
            QQmlBoundSignalExpression *expression =
                    ctxtdata ? new QQmlBoundSignalExpression(target, signalIndex, ctxtdata, this, f)
                             : nullptr;
            signal->takeExpression(expression);
            d->boundsignals += signal;
        } else {
            if (!d->ignoreUnknownSignals)
                qmlWarning(this) << tr("Cannot assign to non-existent property \"%1\"").arg(propName);
        }
    }
}

void QQmlConnections::classBegin()
{
    Q_D(QQmlConnections);
    d->componentcomplete=false;
}

void QQmlConnections::componentComplete()
{
    Q_D(QQmlConnections);
    d->componentcomplete=true;
    connectSignals();
}

QT_END_NAMESPACE

#include "moc_qqmlconnections_p.cpp"
