/****************************************************************************
**
** 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 "qtqmlworkerscriptglobal_p.h"
#include "qquickworkerscript_p.h"
#include <private/qqmlengine_p.h>
#include <private/qqmlexpression_p.h>

#include <QtCore/qcoreevent.h>
#include <QtCore/qcoreapplication.h>
#include <QtCore/qdebug.h>
#include <QtQml/qjsengine.h>
#include <QtCore/qmutex.h>
#include <QtCore/qwaitcondition.h>
#include <QtCore/qfile.h>
#include <QtCore/qdatetime.h>
#include <QtQml/qqmlinfo.h>
#include <QtQml/qqmlfile.h>
#if QT_CONFIG(qml_network)
#include <QtNetwork/qnetworkaccessmanager.h>
#include "qqmlnetworkaccessmanagerfactory.h"
#endif

#include <private/qv4serialize_p.h>

#include <private/qv4value_p.h>
#include <private/qv4functionobject_p.h>
#include <private/qv4script_p.h>
#include <private/qv4scopedvalue_p.h>
#include <private/qv4jscall_p.h>

QT_BEGIN_NAMESPACE

class WorkerDataEvent : public QEvent
{
public:
    enum Type { WorkerData = QEvent::User };

    WorkerDataEvent(int workerId, const QByteArray &data);
    virtual ~WorkerDataEvent();

    int workerId() const;
    QByteArray data() const;

private:
    int m_id;
    QByteArray m_data;
};

class WorkerLoadEvent : public QEvent
{
public:
    enum Type { WorkerLoad = WorkerDataEvent::WorkerData + 1 };

    WorkerLoadEvent(int workerId, const QUrl &url);

    int workerId() const;
    QUrl url() const;

private:
    int m_id;
    QUrl m_url;
};

class WorkerRemoveEvent : public QEvent
{
public:
    enum Type { WorkerRemove = WorkerLoadEvent::WorkerLoad + 1 };

    WorkerRemoveEvent(int workerId);

    int workerId() const;

private:
    int m_id;
};

class WorkerErrorEvent : public QEvent
{
public:
    enum Type { WorkerError = WorkerRemoveEvent::WorkerRemove + 1 };

    WorkerErrorEvent(const QQmlError &error);

    QQmlError error() const;

private:
    QQmlError m_error;
};

struct WorkerScript : public QV4::ExecutionEngine {
    WorkerScript(int id, QQuickWorkerScriptEnginePrivate *parent);

    QQuickWorkerScriptEnginePrivate *p = nullptr;
    QUrl source;
    QQuickWorkerScript *owner = nullptr;
    QScopedPointer<QNetworkAccessManager> scriptLocalNAM;
    int id = -1;
};

class QQuickWorkerScriptEnginePrivate : public QObject
{
    Q_OBJECT
public:
    enum WorkerEventTypes {
        WorkerDestroyEvent = QEvent::User + 100
    };

    QQuickWorkerScriptEnginePrivate(QQmlEngine *eng);

    QQmlEngine *qmlengine;

    QMutex m_lock;
    QWaitCondition m_wait;

    QHash<int, WorkerScript *> workers;
    QV4::ReturnedValue getWorker(WorkerScript *);

    int m_nextId;

    static QV4::ReturnedValue method_sendMessage(const QV4::FunctionObject *, const QV4::Value *thisObject, const QV4::Value *argv, int argc);

signals:
    void stopThread();

protected:
    bool event(QEvent *) override;

private:
    void processMessage(int, const QByteArray &);
    void processLoad(int, const QUrl &);
    void reportScriptException(WorkerScript *, const QQmlError &error);
};

QQuickWorkerScriptEnginePrivate::QQuickWorkerScriptEnginePrivate(QQmlEngine *engine)
: qmlengine(engine), m_nextId(0)
{
}

QV4::ReturnedValue QQuickWorkerScriptEnginePrivate::method_sendMessage(const QV4::FunctionObject *b,
                                                                       const QV4::Value *, const QV4::Value *argv, int argc)
{
    QV4::Scope scope(b);
    WorkerScript *script = static_cast<WorkerScript *>(scope.engine);

    QV4::ScopedValue v(scope, argc > 0 ? argv[0] : QV4::Value::undefinedValue());
    QByteArray data = QV4::Serialize::serialize(v, scope.engine);

    QMutexLocker locker(&script->p->m_lock);
    if (script && script->owner)
        QCoreApplication::postEvent(script->owner, new WorkerDataEvent(0, data));

    return QV4::Encode::undefined();
}

bool QQuickWorkerScriptEnginePrivate::event(QEvent *event)
{
    if (event->type() == (QEvent::Type)WorkerDataEvent::WorkerData) {
        WorkerDataEvent *workerEvent = static_cast<WorkerDataEvent *>(event);
        processMessage(workerEvent->workerId(), workerEvent->data());
        return true;
    } else if (event->type() == (QEvent::Type)WorkerLoadEvent::WorkerLoad) {
        WorkerLoadEvent *workerEvent = static_cast<WorkerLoadEvent *>(event);
        processLoad(workerEvent->workerId(), workerEvent->url());
        return true;
    } else if (event->type() == (QEvent::Type)WorkerDestroyEvent) {
        emit stopThread();
        return true;
    } else if (event->type() == (QEvent::Type)WorkerRemoveEvent::WorkerRemove) {
        QMutexLocker locker(&m_lock);
        WorkerRemoveEvent *workerEvent = static_cast<WorkerRemoveEvent *>(event);
        QHash<int, WorkerScript *>::iterator itr = workers.find(workerEvent->workerId());
        if (itr != workers.end()) {
            delete itr.value();
            workers.erase(itr);
        }
        return true;
    } else {
        return QObject::event(event);
    }
}

void QQuickWorkerScriptEnginePrivate::processMessage(int id, const QByteArray &data)
{
    WorkerScript *script = workers.value(id);
    if (!script)
        return;

    QV4::Scope scope(script);
    QV4::ScopedString v(scope);
    QV4::ScopedObject worker(scope, script->globalObject->get((v = script->newString(QStringLiteral("WorkerScript")))));
    QV4::ScopedFunctionObject onmessage(scope);
    if (worker)
        onmessage = worker->get((v = script->newString(QStringLiteral("onMessage"))));

    if (!onmessage)
        return;

    QV4::ScopedValue value(scope, QV4::Serialize::deserialize(data, script));

    QV4::JSCallData jsCallData(scope, 1);
    *jsCallData->thisObject = script->global();
    jsCallData->args[0] = value;
    onmessage->call(jsCallData);
    if (scope.hasException()) {
        QQmlError error = scope.engine->catchExceptionAsQmlError();
        reportScriptException(script, error);
    }
}

void QQuickWorkerScriptEnginePrivate::processLoad(int id, const QUrl &url)
{
    if (url.isRelative())
        return;

    QString fileName = QQmlFile::urlToLocalFileOrQrc(url);

    WorkerScript *script = workers.value(id);
    if (!script)
        return;

    script->source = url;

    if (fileName.endsWith(QLatin1String(".mjs"))) {
        auto moduleUnit = script->loadModule(url);
        if (moduleUnit) {
            if (moduleUnit->instantiate(script))
                moduleUnit->evaluate();
        } else {
            script->throwError(QStringLiteral("Could not load module file"));
        }
    } else {
        QString error;
        QV4::Scope scope(script);
        QScopedPointer<QV4::Script> program;
        program.reset(QV4::Script::createFromFileOrCache(script, /*qmlContext*/nullptr, fileName, url, &error));
        if (program.isNull()) {
            if (!error.isEmpty())
                qWarning().nospace() << error;
            return;
        }

        if (!script->hasException)
            program->run();
    }

    if (script->hasException) {
        QQmlError error = script->catchExceptionAsQmlError();
        reportScriptException(script, error);
    }
}

void QQuickWorkerScriptEnginePrivate::reportScriptException(WorkerScript *script,
                                                                  const QQmlError &error)
{
    QMutexLocker locker(&script->p->m_lock);
    if (script->owner)
        QCoreApplication::postEvent(script->owner, new WorkerErrorEvent(error));
}

WorkerDataEvent::WorkerDataEvent(int workerId, const QByteArray &data)
: QEvent((QEvent::Type)WorkerData), m_id(workerId), m_data(data)
{
}

WorkerDataEvent::~WorkerDataEvent()
{
}

int WorkerDataEvent::workerId() const
{
    return m_id;
}

QByteArray WorkerDataEvent::data() const
{
    return m_data;
}

WorkerLoadEvent::WorkerLoadEvent(int workerId, const QUrl &url)
: QEvent((QEvent::Type)WorkerLoad), m_id(workerId), m_url(url)
{
}

int WorkerLoadEvent::workerId() const
{
    return m_id;
}

QUrl WorkerLoadEvent::url() const
{
    return m_url;
}

WorkerRemoveEvent::WorkerRemoveEvent(int workerId)
: QEvent((QEvent::Type)WorkerRemove), m_id(workerId)
{
}

int WorkerRemoveEvent::workerId() const
{
    return m_id;
}

WorkerErrorEvent::WorkerErrorEvent(const QQmlError &error)
: QEvent((QEvent::Type)WorkerError), m_error(error)
{
}

QQmlError WorkerErrorEvent::error() const
{
    return m_error;
}

QQuickWorkerScriptEngine::QQuickWorkerScriptEngine(QQmlEngine *parent)
: QThread(parent), d(new QQuickWorkerScriptEnginePrivate(parent))
{
    d->m_lock.lock();
    connect(d, SIGNAL(stopThread()), this, SLOT(quit()), Qt::DirectConnection);
    start(QThread::LowestPriority);
    d->m_wait.wait(&d->m_lock);
    d->moveToThread(this);
    d->m_lock.unlock();
}

QQuickWorkerScriptEngine::~QQuickWorkerScriptEngine()
{
    d->m_lock.lock();
    QCoreApplication::postEvent(d, new QEvent((QEvent::Type)QQuickWorkerScriptEnginePrivate::WorkerDestroyEvent));
    d->m_lock.unlock();

    //We have to force to cleanup the main thread's event queue here
    //to make sure the main GUI release all pending locks/wait conditions which
    //some worker script/agent are waiting for (QQmlListModelWorkerAgent::sync() for example).
    while (!isFinished()) {
        // We can't simply wait here, because the worker thread will not terminate
        // until the main thread processes the last data event it generates
        QCoreApplication::processEvents();
        yieldCurrentThread();
    }

    delete d;
}

WorkerScript::WorkerScript(int id, QQuickWorkerScriptEnginePrivate *parent)
    : p(parent)
    , id(id)
{
    initQmlGlobalObject();

    QV4::Scope scope(this);
    QV4::ScopedObject api(scope, scope.engine->newObject());
    QV4::ScopedString name(scope, newString(QStringLiteral("sendMessage")));
    QV4::ScopedValue sendMessage(scope, QV4::FunctionObject::createBuiltinFunction(this, name, QQuickWorkerScriptEnginePrivate::method_sendMessage, 1));
    api->put(QV4::ScopedString(scope, scope.engine->newString(QStringLiteral("sendMessage"))), sendMessage);
    globalObject->put(QV4::ScopedString(scope, scope.engine->newString(QStringLiteral("WorkerScript"))), api);
    networkAccessManager = [](QV4::ExecutionEngine *engine){
        auto *workerScript = static_cast<WorkerScript *>(engine);
        if (workerScript->scriptLocalNAM)
            return workerScript->scriptLocalNAM.get();
        if (auto *namFactory = workerScript->p->qmlengine->networkAccessManagerFactory())
            workerScript->scriptLocalNAM.reset(namFactory->create(workerScript->p));
        else
            workerScript->scriptLocalNAM.reset(new QNetworkAccessManager(workerScript->p));
        return workerScript->scriptLocalNAM.get();
    };
}

int QQuickWorkerScriptEngine::registerWorkerScript(QQuickWorkerScript *owner)
{
    WorkerScript *script = new WorkerScript(d->m_nextId++, d);

    script->owner = owner;

    d->m_lock.lock();
    d->workers.insert(script->id, script);
    d->m_lock.unlock();

    return script->id;
}

void QQuickWorkerScriptEngine::removeWorkerScript(int id)
{
    if (WorkerScript *script = d->workers.value(id)) {
        script->owner = nullptr;
        QCoreApplication::postEvent(d, new WorkerRemoveEvent(id));
    }
}

void QQuickWorkerScriptEngine::executeUrl(int id, const QUrl &url)
{
    QCoreApplication::postEvent(d, new WorkerLoadEvent(id, url));
}

void QQuickWorkerScriptEngine::sendMessage(int id, const QByteArray &data)
{
    QCoreApplication::postEvent(d, new WorkerDataEvent(id, data));
}

void QQuickWorkerScriptEngine::run()
{
    d->m_lock.lock();

    d->m_wait.wakeAll();

    d->m_lock.unlock();

    exec();

    qDeleteAll(d->workers);
    d->workers.clear();
}


/*!
    \qmltype WorkerScript
    \instantiates QQuickWorkerScript
    \ingroup qtquick-threading
    \inqmlmodule QtQml.WorkerScript
    \brief Enables the use of threads in a Qt Quick application.

    Use WorkerScript to run operations in a new thread.
    This is useful for running operations in the background so
    that the main GUI thread is not blocked.

    Messages can be passed between the new thread and the parent thread
    using \l sendMessage() and the \c onMessage() handler.

    An example:

    \snippet qml/workerscript/workerscript.qml 0

    The above worker script specifies a JavaScript file, "script.mjs", that handles
    the operations to be performed in the new thread. Here is \c script.mjs:

    \quotefile qml/workerscript/script.mjs

    When the user clicks anywhere within the rectangle, \c sendMessage() is
    called, triggering the \tt WorkerScript.onMessage() handler in
    \tt script.mjs. This in turn sends a reply message that is then received
    by the \tt onMessage() handler of \tt myWorker.

    The example uses a script that is an ECMAScript module, because it has the ".mjs" extension.
    It can use import statements to access functionality from other modules and it is run in JavaScript
    strict mode.

    If a worker script has the extension ".js" instead, then it is considered to contain plain JavaScript
    statements and it is run in non-strict mode.

    \note Each WorkerScript element will instantiate a separate JavaScript engine to ensure perfect
    isolation and thread-safety. If the impact of that results in a memory consumption that is too
    high for your environment, then consider sharing a WorkerScript element.

    \section3 Restrictions

    Since the \c WorkerScript.onMessage() function is run in a separate thread, the
    JavaScript file is evaluated in a context separate from the main QML engine. This means
    that unlike an ordinary JavaScript file that is imported into QML, the \c script.mjs
    in the above example cannot access the properties, methods or other attributes
    of the QML item, nor can it access any context properties set on the QML object
    through QQmlContext.

    Additionally, there are restrictions on the types of values that can be passed to and
    from the worker script. See the sendMessage() documentation for details.

    Worker scripts that are plain JavaScript sources can not use \l {qtqml-javascript-imports.html}{.import} syntax.
    Scripts that are ECMAScript modules can freely use import and export statements.

    \sa {Qt Quick Examples - Threading},
        {Threaded ListModel Example}
*/
QQuickWorkerScript::QQuickWorkerScript(QObject *parent)
: QObject(parent), m_engine(nullptr), m_scriptId(-1), m_componentComplete(true)
{
}

QQuickWorkerScript::~QQuickWorkerScript()
{
    if (m_scriptId != -1) m_engine->removeWorkerScript(m_scriptId);
}

/*!
    \qmlproperty url WorkerScript::source

    This holds the url of the JavaScript file that implements the
    \tt WorkerScript.onMessage() handler for threaded operations.

    If the file name component of the url ends with ".mjs", then the script
    is parsed as an ECMAScript module and run in strict mode. Otherwise it is considered to be
    plain script.
*/
QUrl QQuickWorkerScript::source() const
{
    return m_source;
}

void QQuickWorkerScript::setSource(const QUrl &source)
{
    if (m_source == source)
        return;

    m_source = source;

    if (engine())
        m_engine->executeUrl(m_scriptId, m_source);

    emit sourceChanged();
}

/*!
    \qmlmethod WorkerScript::sendMessage(jsobject message)

    Sends the given \a message to a worker script handler in another
    thread. The other worker script handler can receive this message
    through the onMessage() handler.

    The \c message object may only contain values of the following
    types:

    \list
    \li boolean, number, string
    \li JavaScript objects and arrays
    \li ListModel objects (any other type of QObject* is not allowed)
    \endlist

    All objects and arrays are copied to the \c message. With the exception
    of ListModel objects, any modifications by the other thread to an object
    passed in \c message will not be reflected in the original object.
*/
void QQuickWorkerScript::sendMessage(QQmlV4Function *args)
{
    if (!engine()) {
        qWarning("QQuickWorkerScript: Attempt to send message before WorkerScript establishment");
        return;
    }

    QV4::Scope scope(args->v4engine());
    QV4::ScopedValue argument(scope, QV4::Value::undefinedValue());
    if (args->length() != 0)
        argument = (*args)[0];

    m_engine->sendMessage(m_scriptId, QV4::Serialize::serialize(argument, scope.engine));
}

void QQuickWorkerScript::classBegin()
{
    m_componentComplete = false;
}

QQuickWorkerScriptEngine *QQuickWorkerScript::engine()
{
    if (m_engine) return m_engine;
    if (m_componentComplete) {
        QQmlEngine *engine = qmlEngine(this);
        if (!engine) {
            qWarning("QQuickWorkerScript: engine() called without qmlEngine() set");
            return nullptr;
        }

        QQmlEnginePrivate *enginePrivate = QQmlEnginePrivate::get(engine);
        if (enginePrivate->workerScriptEngine == nullptr)
            enginePrivate->workerScriptEngine = new QQuickWorkerScriptEngine(engine);
        m_engine = qobject_cast<QQuickWorkerScriptEngine *>(enginePrivate->workerScriptEngine);
        Q_ASSERT(m_engine);
        m_scriptId = m_engine->registerWorkerScript(this);

        if (m_source.isValid())
            m_engine->executeUrl(m_scriptId, m_source);

        return m_engine;
    }
    return nullptr;
}

void QQuickWorkerScript::componentComplete()
{
    m_componentComplete = true;
    engine(); // Get it started now.
}

/*!
    \qmlsignal WorkerScript::message(jsobject msg)

    This signal is emitted when a message \a msg is received from a worker
    script in another thread through a call to sendMessage().

    The corresponding handler is \c onMessage.
*/

bool QQuickWorkerScript::event(QEvent *event)
{
    if (event->type() == (QEvent::Type)WorkerDataEvent::WorkerData) {
        if (QQmlEngine *engine = qmlEngine(this)) {
            QV4::ExecutionEngine *v4 = engine->handle();
            WorkerDataEvent *workerEvent = static_cast<WorkerDataEvent *>(event);
            emit message(QJSValue(v4, QV4::Serialize::deserialize(workerEvent->data(), v4)));
        }
        return true;
    } else if (event->type() == (QEvent::Type)WorkerErrorEvent::WorkerError) {
        WorkerErrorEvent *workerEvent = static_cast<WorkerErrorEvent *>(event);
        QQmlEnginePrivate::warning(qmlEngine(this), workerEvent->error());
        return true;
    } else {
        return QObject::event(event);
    }
}

QT_END_NAMESPACE

#include <qquickworkerscript.moc>

#include "moc_qquickworkerscript_p.cpp"
