/****************************************************************************
**
** Copyright (C) 2014 Klaralvdalens Datakonsult AB (KDAB).
** Contact: https://www.qt.io/licensing/
**
** This file is part of the Qt3D 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 "qaspectengine.h"
#include "qaspectengine_p.h"

#include <Qt3DCore/qabstractaspect.h>
#include <Qt3DCore/qcomponent.h>
#include <Qt3DCore/qentity.h>
#include <Qt3DCore/qnode.h>
#include <QtCore/QMetaObject>

#include <Qt3DCore/private/corelogging_p.h>
#include <Qt3DCore/private/qaspectmanager_p.h>
#include <Qt3DCore/private/qchangearbiter_p.h>
#include <Qt3DCore/private/qeventfilterservice_p.h>
#include <Qt3DCore/private/qnode_p.h>
#include <Qt3DCore/private/qnodevisitor_p.h>
#include <Qt3DCore/private/qpostman_p.h>
#include <Qt3DCore/private/qscene_p.h>
#include <Qt3DCore/private/qservicelocator_p.h>
#include <Qt3DCore/qt3dcore-config.h>

#if QT_CONFIG(qt3d_profile_jobs)
#include <Qt3DCore/private/aspectcommanddebugger_p.h>
#endif

QT_BEGIN_NAMESPACE

namespace{

QVector<Qt3DCore::QNode *> getNodesForCreation(Qt3DCore::QNode *root)
{
    using namespace Qt3DCore;

    QVector<QNode *> nodes;
    QNodeVisitor visitor;
    visitor.traverse(root, [&nodes](QNode *node) {
        nodes.append(node);

        // Store the metaobject of the node in the QNode so that we have it available
        // to us during destruction in the QNode destructor. This allows us to send
        // the QNodeId and the metaobject as typeinfo to the backend aspects so they
        // in turn can find the correct QBackendNodeMapper object to handle the destruction
        // of the corresponding backend nodes.
        QNodePrivate *d = QNodePrivate::get(node);
        d->m_typeInfo = const_cast<QMetaObject*>(QNodePrivate::findStaticMetaObject(node->metaObject()));

        // Mark this node as having been handled for creation so that it is picked up
        d->m_hasBackendNode = true;
    });

    return nodes;
}

QVector<Qt3DCore::QNode *> getNodesForRemoval(Qt3DCore::QNode *root)
{
    using namespace Qt3DCore;

    QVector<QNode *> nodes;
    QNodeVisitor visitor;
    visitor.traverse(root, [&nodes](QNode *node) {
        nodes.append(node);

        // Mark this node as having been handled for destruction so we don't
        // repeat it unnecessarily in an O(n^2) manner
        QNodePrivate::get(node)->m_hasBackendNode = false;
    });

    return nodes;
}

}

namespace Qt3DCore {

QAspectEnginePrivate *QAspectEnginePrivate::get(QAspectEngine *q)
{
    return q->d_func();
}

QAspectEnginePrivate::QAspectEnginePrivate()
    : QObjectPrivate()
    , m_aspectManager(nullptr)
    , m_postman(nullptr)
    , m_scene(nullptr)
    , m_initialized(false)
    , m_runMode(QAspectEngine::Automatic)
    #if QT_CONFIG(qt3d_profile_jobs)
    , m_commandDebugger(new Debug::AspectCommandDebugger(q_func()))
    #endif
{
    qRegisterMetaType<Qt3DCore::QAbstractAspect *>();
    qRegisterMetaType<Qt3DCore::QObserverInterface *>();
    qRegisterMetaType<Qt3DCore::QNode *>();
    qRegisterMetaType<Qt3DCore::QEntity *>();
    qRegisterMetaType<Qt3DCore::QScene *>();
    qRegisterMetaType<Qt3DCore::QAbstractPostman *>();
}

QAspectEnginePrivate::~QAspectEnginePrivate()
{
    qDeleteAll(m_aspects);
}

/*!
 * \internal
 *
 * Used to init the scene tree when the Qt3D aspect is first started. Basically,
 * sets the scene/change arbiter on the items and stores the entity - component
 * pairs in the scene
 */
void QAspectEnginePrivate::initNode(QNode *node)
{
    m_scene->addObservable(node);
    QNodePrivate::get(node)->setScene(m_scene);
}

void QAspectEnginePrivate::initEntity(QEntity *entity)
{
    const auto components = entity->components();
    for (QComponent *comp : components) {
        if (!m_scene->hasEntityForComponent(comp->id(), entity->id())) {
            if (!comp->isShareable() && !m_scene->entitiesForComponent(comp->id()).isEmpty())
                qWarning() << "Trying to assign a non shareable component to more than one Entity";
            m_scene->addEntityForComponent(comp->id(), entity->id());
        }
    }
}

void QAspectEnginePrivate::addNode(QNode *node)
{
    m_aspectManager->addNodes(getNodesForCreation(node));
}

void QAspectEnginePrivate::removeNode(QNode *node)
{
    m_aspectManager->removeNodes(getNodesForRemoval(node));
}

/*!
 * \class Qt3DCore::QAspectEngine
 * \inheaderfile Qt3DCore/QAspectEngine
 * \inherits QObject
 * \inmodule Qt3DCore
 *
 * \brief Responsible for handling all the QAbstractAspect subclasses that have
 * been registered with the scene.
 *
 * The Qt3D run loop is controlled by the Qt3DRender::QAspectEngine.
 *
 * Qt3DCore::QAbstractAspect subclasses can be registered by calling
 * Qt3DCore::QAspectEngine::registerAspect() which will take care of registering
 * the aspect and in turn that will call Qt3DCore::QAbstractAspect::onRegistered();
 *
 * The simulation loop is launched as soon as a root Qt3DCore::QEntity
 * is set on the Qt3DCore::QAspectEngine. This is followed by a call to
 * onEngineStartup() on each aspect so that they can start their simulation
 * work.
 *
 * The simulation loop is stopped when the root entity is set to
 * Qt3DCore::QEntityPtr(). This calls onEngineShutdown() on each aspect so
 * that they can stop performing their simulation work.
 *
 * Setting a new valid root entity would restart the simulation loop again.
 */

/*!
 * \internal
 * This loop is executed in a separate thread called the AspectThread in
 * Qt3DCore::QAspectThread. This thread is started when the
 * Qt3DCore::QAspectEngine is created and provides the
 * Qt3DCore::QAspectManager which lives in this thread for as long as it's
 * running.
 *
 * Once the AspectThread is running, it starts the run loop and waits for
 * aspects to be registered.
 *
 * Destroying the Qt3DCore::QAspectEngine instance stops the AspectThread and
 * properly terminates the run loop.
 */

/*!
 * \typedef Qt3DCore::QEntityPtr
 * \relates Qt3DCore::QAspectEngine
 *
 * A shared pointer for QEntity.
 */

/*!
 * Constructs a new QAspectEngine with \a parent.
 */
QAspectEngine::QAspectEngine(QObject *parent)
    : QObject(*new QAspectEnginePrivate, parent)
{
    qCDebug(Aspects) << Q_FUNC_INFO;
    Q_D(QAspectEngine);
    d->m_scene = new QScene(this);
    d->m_postman = new QPostman(this);
    d->m_postman->setScene(d->m_scene);
    d->m_aspectManager = new QAspectManager(this);
}

/*!
 * Destroys the engine.
 */
QAspectEngine::~QAspectEngine()
{
    Q_D(QAspectEngine);

    // Shutdown the simulation loop by setting an empty scene
    // Note: this sets an atomic which allows the AspectThread to break out of
    // the inner simulation loop in the AspectThread::exec function
    setRootEntity(QEntityPtr());

    // Unregister all aspects and exit the main loop
    const auto aspects = d->m_aspects;
    for (auto aspect : aspects)
        unregisterAspect(aspect);

    delete d->m_postman;
    delete d->m_scene;
}

void QAspectEnginePrivate::initNodeTree(QNode *node)
{
    // Set the root entity on the scene
    m_scene->setRootNode(node);
    QNodeVisitor visitor;
    visitor.traverse(node, this, &QAspectEnginePrivate::initNode, &QAspectEnginePrivate::initEntity);
}

void QAspectEnginePrivate::initialize()
{
    m_aspectManager->initialize();
    QChangeArbiter *arbiter = m_aspectManager->changeArbiter();
    m_scene->setArbiter(arbiter);
    QChangeArbiter::createUnmanagedThreadLocalChangeQueue(arbiter);
    arbiter->setPostman(m_postman);
    arbiter->setScene(m_scene);
    m_initialized = true;
    m_aspectManager->setPostConstructorInit(m_scene->postConstructorInit());
#if QT_CONFIG(qt3d_profile_jobs)
    m_commandDebugger->setAspectEngine(q_func());
    m_commandDebugger->initialize();
#endif
}

/*!
 * \internal
 *
 * Called when we unset the root entity. Causes the QAspectManager's simulation
 * loop to be exited. The main loop should keep processing events ready
 * to start up the simulation again with a new root entity.
 */
void QAspectEnginePrivate::shutdown()
{
    qCDebug(Aspects) << Q_FUNC_INFO;

    // Flush any change batch waiting in the postman that may contain node
    // destruction changes that the aspects should process before we exit
    // the simulation loop
    m_postman->submitChangeBatch();

    // Exit the simulation loop. Waits for this to be completed on the aspect
    // thread before returning
    exitSimulationLoop();

    // Cleanup the scene before quitting the backend
    m_scene->setArbiter(nullptr);
    QChangeArbiter *arbiter = m_aspectManager->changeArbiter();
    QChangeArbiter::destroyUnmanagedThreadLocalChangeQueue(arbiter);
    m_initialized = false;
}

void QAspectEnginePrivate::exitSimulationLoop()
{
    m_aspectManager->exitSimulationLoop();
}

/*!
 Registers a new \a aspect to the AspectManager. The QAspectEngine takes
 ownership of the aspect and will delete it when the aspect is unregistered.
 //! Called in the main thread
 */
void QAspectEngine::registerAspect(QAbstractAspect *aspect)
{
    Q_D(QAspectEngine);
    // The aspect is moved to the AspectThread
    // AspectManager::registerAspect is called in the context
    // of the AspectThread. This is turns call aspect->onInitialize
    // still in the same AspectThread context
    d->m_aspects << aspect;
    d->m_aspectManager->registerAspect(aspect);
}

/*!
 * Registers a new aspect to the AspectManager based on its \a name
 * Uses the currently set aspect factory to create the actual aspect
 * instance.
 */
void QAspectEngine::registerAspect(const QString &name)
{
    Q_D(QAspectEngine);
    QAbstractAspect *aspect = d->m_factory.createAspect(QLatin1String(name.toUtf8()));
    if (aspect) {
        registerAspect(aspect);
        d->m_namedAspects.insert(name, aspect);
    }
}

/*!
 * Unregisters and deletes the given \a aspect.
 */
void QAspectEngine::unregisterAspect(QAbstractAspect *aspect)
{
    Q_D(QAspectEngine);
    if (!d->m_aspects.contains(aspect)) {
        qWarning() << "Attempting to unregister an aspect that is not registered";
        return;
    }

    // Cleanly shutdown this aspect by setting its root entity to null which
    // will cause its onEngineShutdown() virtual to be called to allow it to
    // cleanup any resources. Then remove it from the QAspectManager's list
    // of aspects.
    // TODO: Implement this once we are able to cleanly shutdown

    // Tell the aspect manager to give the aspect a chance to do some cleanup
    // in its QAbstractAspect::onUnregistered() virtual
    d->m_aspectManager->unregisterAspect(aspect);

    // Remove from our collection of named aspects (if present)
    const auto it = std::find_if(d->m_namedAspects.begin(), d->m_namedAspects.end(),
                                 [aspect](QAbstractAspect *v) { return v == aspect; });
    if (it != d->m_namedAspects.end())
        d->m_namedAspects.erase(it);

    // Finally, scheduly the aspect for deletion. Do this via the event loop
    // in case we are unregistering the aspect in response to a signal from it.
    aspect->deleteLater();
    d->m_aspects.removeOne(aspect);
}

/*!
 * Unregisters and deletes the aspect with the given \a name.
 */
void QAspectEngine::unregisterAspect(const QString &name)
{
    Q_D(QAspectEngine);
    if (!d->m_namedAspects.contains(name)) {
        qWarning() << "Attempting to unregister an aspect that is not registered";
        return;
    }

    // Delegate unregistering and removal to the overload
    QAbstractAspect *aspect = d->m_namedAspects.value(name);
    unregisterAspect(aspect);
}

/*!
 * \return the aspects owned by the aspect engine.
 */
QVector<QAbstractAspect *> QAspectEngine::aspects() const
{
    Q_D(const QAspectEngine);
    return d->m_aspects;
}

/*!
 * Executes the given \a command on aspect engine. Valid commands are:
 * \list
 * \li "list aspects"
 * \endlist
 *
 * \return the reply for the command.
 */
QVariant QAspectEngine::executeCommand(const QString &command)
{
    Q_D(QAspectEngine);

    if (command == QLatin1String("list aspects")) {
        if (d->m_aspects.isEmpty())
            return QLatin1String("No loaded aspect");

        QString reply;
        reply += QLatin1String("Loaded aspects:");
        for (QAbstractAspect *aspect : qAsConst(d->m_aspects)) {
            const QString name = d->m_factory.aspectName(aspect);
            if (!name.isEmpty())
                reply += QLatin1String("\n * ") + name;
            else
                reply += QLatin1String("\n * <unnamed>");
        }
        return reply;
    }

    QStringList args = command.split(QLatin1Char(' '));
    QString aspectName = args.takeFirst();

    for (QAbstractAspect *aspect : qAsConst(d->m_aspects)) {
        if (aspectName == d->m_factory.aspectName(aspect))
            return aspect->executeCommand(args);
    }

    return QVariant();
}

/*!
 * If using the manual run mode, this function executes the jobs for each aspect.
 * It is blocking and won't return until all jobs have been completed.
 *
 * If you are using the QRenderAspect,
 */
void QAspectEngine::processFrame()
{
    Q_D(QAspectEngine);
    Q_ASSERT(d->m_runMode == QAspectEngine::Manual);
    d->m_aspectManager->processFrame();
}

/*!
 * Sets the \a root entity for the aspect engine.
 */
void QAspectEngine::setRootEntity(QEntityPtr root)
{
    qCDebug(Aspects) << Q_FUNC_INFO << "root =" << root;
    Q_D(QAspectEngine);
    if (d->m_root == root)
        return;

    const bool shutdownNeeded = d->m_root && d->m_initialized;

    // Set the new root object. This will cause the old tree to be deleted
    // and the deletion of the old frontend tree will cause the backends to
    // free any related resources
    d->m_root = root;

    if (shutdownNeeded)
        d->shutdown();

    // Do we actually have a new scene?
    if (!d->m_root)
        return;

    // Set postman/scene/arbiter ...
    d->initialize();

    // The aspect engine takes ownership of the scene root. We also set the
    // parent of the scene root to be the engine
    static_cast<QObject *>(d->m_root.data())->setParent(this);

    // Prepare the frontend tree for use by giving each node a pointer to the
    // scene object and adding each node to the scene
    // TODO: We probably need a call symmetric to this one above in order to
    // deregister the nodes from the scene
    d->initNodeTree(root.data());

    const QVector<QNode *> nodes = getNodesForCreation(root.data());

    // Specify if the AspectManager should be driving the simulation loop or not
    d->m_aspectManager->setRunMode(d->m_runMode);

    // Finally, tell the aspects about the new scene object tree. This is done
    // in a blocking manner to allow the aspects to get synchronized before the
    // main thread starts triggering potentially more notifications

    // TODO: Pass the creation changes via the arbiter rather than relying upon
    // an invokeMethod call.
    qCDebug(Aspects) << "Begin setting scene root on aspect manager";
    d->m_aspectManager->setRootEntity(root.data(), nodes);
    qCDebug(Aspects) << "Done setting scene root on aspect manager";
    d->m_aspectManager->enterSimulationLoop();
}

/*!
 * \return the root entity of the aspect engine.
 */
QEntityPtr QAspectEngine::rootEntity() const
{
    Q_D(const QAspectEngine);
    return d->m_root;
}

void QAspectEngine::setRunMode(QAspectEngine::RunMode mode)
{
    Q_D(QAspectEngine);
    d->m_runMode = mode;
    if (d->m_aspectManager)
        d->m_aspectManager->setRunMode(mode);
}

QAspectEngine::RunMode QAspectEngine::runMode() const
{
    Q_D(const QAspectEngine);
    return d->m_runMode;
}

} // namespace Qt3DCore

QT_END_NAMESPACE
