/****************************************************************************
**
** Copyright (C) 2016 Paul Lemire <paul.lemire350@gmail.com>
** Contact: http://www.qt-project.org/legal
**
** This file is part of the Qt3D module of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL3$
** 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 http://www.qt.io/terms-conditions. For further
** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free
** Software Foundation and appearing in the file LICENSE.GPL included in
** the packaging of this file. Please review the following information to
** ensure the GNU General Public License version 2.0 requirements will be
** met: http://www.gnu.org/licenses/gpl-2.0.html.
**
** $QT_END_LICENSE$
**
****************************************************************************/

#include "commandexecuter_p.h"

#include <Qt3DRender/private/renderer_p.h>
#include <Qt3DCore/private/qabstractaspect_p.h>
#include <Qt3DCore/qbackendnode.h>
#include <Qt3DRender/private/graphicscontext_p.h>
#include <Qt3DRender/private/renderview_p.h>
#include <Qt3DRender/private/rendercommand_p.h>
#include <Qt3DRender/private/nodemanagers_p.h>
#include <Qt3DRender/private/geometryrenderermanager_p.h>
#include <Qt3DRender/private/stringtoint_p.h>
#include <Qt3DRender/private/submissioncontext_p.h>
#include <QJsonObject>
#include <QJsonDocument>
#include <QJsonArray>

QT_BEGIN_NAMESPACE

namespace Qt3DRender {

namespace Debug {

namespace {

template<typename Type>
QJsonObject typeToJsonObj(const Type &)
{
    return QJsonObject();
}

template<typename Type>
QJsonValue typeToJsonValue(const Type &t)
{
    Q_UNUSED(t);
    return QJsonValue();
}

template<>
QJsonObject typeToJsonObj<QRectF>(const QRectF &rect)
{
    QJsonObject obj;

    obj.insert(QLatin1String("x"), rect.x());
    obj.insert(QLatin1String("y"), rect.y());
    obj.insert(QLatin1String("width"), rect.width());
    obj.insert(QLatin1String("height"), rect.height());

    return obj;
}

template<>
QJsonValue typeToJsonValue<QRectF>(const QRectF &rect)
{
    QJsonArray value;

    value.push_back(rect.x());
    value.push_back(rect.y());
    value.push_back(rect.width());
    value.push_back(rect.height());

    return value;
}

template<>
QJsonObject typeToJsonObj<QSize>(const QSize &s)
{
    QJsonObject obj;

    obj.insert(QLatin1String("width"), s.width());
    obj.insert(QLatin1String("height"), s.height());

    return obj;
}

template<>
QJsonValue typeToJsonValue<QSize>(const QSize &s)
{
    QJsonArray value;

    value.push_back(s.width());
    value.push_back(s.height());

    return value;
}

template<>
QJsonObject typeToJsonObj<QVector3D>(const QVector3D &v)
{
    QJsonObject obj;

    obj.insert(QLatin1String("x"), v.x());
    obj.insert(QLatin1String("y"), v.y());
    obj.insert(QLatin1String("z"), v.z());

    return obj;
}

template<>
QJsonValue typeToJsonValue<QVector3D>(const QVector3D &v)
{
    QJsonArray value;

    value.push_back(v.x());
    value.push_back(v.y());
    value.push_back(v.z());

    return value;
}

template<>
QJsonObject typeToJsonObj<Qt3DCore::QNodeId>(const Qt3DCore::QNodeId &v)
{
    QJsonObject obj;
    obj.insert(QLatin1String("id"), qint64(v.id()));
    return obj;
}

template<>
QJsonValue typeToJsonValue<Qt3DCore::QNodeId>(const Qt3DCore::QNodeId &v)
{
    QJsonValue value(qint64(v.id()));
    return value;
}

template<>
QJsonObject typeToJsonObj<QVector4D>(const QVector4D &v)
{
    QJsonObject obj;

    obj.insert(QLatin1String("x"), v.x());
    obj.insert(QLatin1String("y"), v.y());
    obj.insert(QLatin1String("z"), v.z());
    obj.insert(QLatin1String("w"), v.w());

    return obj;
}

template<>
QJsonValue typeToJsonValue<QVector4D>(const QVector4D &v)
{
    QJsonArray value;

    value.push_back(v.x());
    value.push_back(v.y());
    value.push_back(v.z());
    value.push_back(v.w());

    return value;
}

template<>
QJsonObject typeToJsonObj<QMatrix4x4>(const QMatrix4x4 &v)
{
    QJsonObject obj;

    obj.insert(QLatin1String("row 0"), typeToJsonObj(v.row(0)));
    obj.insert(QLatin1String("row 1"), typeToJsonObj(v.row(0)));
    obj.insert(QLatin1String("row 2"), typeToJsonObj(v.row(0)));
    obj.insert(QLatin1String("row 3"), typeToJsonObj(v.row(0)));

    return obj;
}

template<>
QJsonValue typeToJsonValue<QMatrix4x4>(const QMatrix4x4 &v)
{
    QJsonArray value;

    value.push_back(typeToJsonValue(v.row(0)));
    value.push_back(typeToJsonValue(v.row(1)));
    value.push_back(typeToJsonValue(v.row(2)));
    value.push_back(typeToJsonValue(v.row(3)));

    return value;
}

template<>
QJsonValue typeToJsonValue<QVariant>(const QVariant &v)
{
    const int nodeTypeId = qMetaTypeId<Qt3DCore::QNodeId>();

    if (v.userType() == nodeTypeId)
        return typeToJsonValue(v.value<Qt3DCore::QNodeId>());

    switch (v.userType()) {
    case QMetaType::QVector3D:
        return typeToJsonValue(v.value<QVector3D>());
    case QMetaType::QVector4D:
        return typeToJsonValue(v.value<QVector4D>());
    case QMetaType::QMatrix4x4:
        return typeToJsonValue(v.value<QMatrix4x4>());
    default:
        return QJsonValue::fromVariant(v);
    }
}

template<typename Handle, typename Manager>
QJsonObject backendNodeToJSon(Handle handle, Manager *manager)
{
    Qt3DCore::QBackendNode *node = manager->data(handle);
    QJsonObject obj;
    Qt3DCore::QNodeId id;
    if (node != nullptr)
        id = node->peerId();
    obj.insert(QLatin1String("id"), qint64(id.id()));
    return obj;
}

QJsonObject parameterPackToJson(const Render::ShaderParameterPack &pack)
{
    QJsonObject obj;

    const Render::PackUniformHash &uniforms = pack.uniforms();
    QJsonArray uniformsArray;
    for (int i = 0, m = uniforms.keys.size(); i < m; ++i) {
        QJsonObject uniformObj;
        uniformObj.insert(QLatin1String("name"), Render::StringToInt::lookupString(uniforms.keys.at(i)));
        const Render::UniformValue::ValueType type = uniforms.values.at(i).valueType();
        uniformObj.insert(QLatin1String("type"),
                          type == Render::UniformValue::ScalarValue
                          ? QLatin1String("value")
                          : QLatin1String("texture"));
        uniformsArray.push_back(uniformObj);
    }
    obj.insert(QLatin1String("uniforms"), uniformsArray);

    QJsonArray texturesArray;
    const QVector<Render::ShaderParameterPack::NamedResource> &textures = pack.textures();
    for (const auto & texture : textures) {
        QJsonObject textureObj;
        textureObj.insert(QLatin1String("name"), Render::StringToInt::lookupString(texture.glslNameId));
        textureObj.insert(QLatin1String("id"), qint64(texture.nodeId.id()));
        texturesArray.push_back(textureObj);
    }
    obj.insert(QLatin1String("textures"), texturesArray);

    const QVector<Render::BlockToUBO> &ubos = pack.uniformBuffers();
    QJsonArray ubosArray;
    for (const auto &ubo : ubos) {
        QJsonObject uboObj;
        uboObj.insert(QLatin1String("index"), ubo.m_blockIndex);
        uboObj.insert(QLatin1String("bufferId"), qint64(ubo.m_bufferID.id()));
        ubosArray.push_back(uboObj);

    }
    obj.insert(QLatin1String("ubos"), ubosArray);

    const QVector<Render::BlockToSSBO> &ssbos = pack.shaderStorageBuffers();
    QJsonArray ssbosArray;
    for (const auto &ssbo : ssbos) {
        QJsonObject ssboObj;
        ssboObj.insert(QLatin1String("index"), ssbo.m_blockIndex);
        ssboObj.insert(QLatin1String("bufferId"), qint64(ssbo.m_bufferID.id()));
        ssbosArray.push_back(ssboObj);
    }
    obj.insert(QLatin1String("ssbos"), ssbosArray);

    return obj;
}

} // anonymous

CommandExecuter::CommandExecuter(Render::Renderer *renderer)
    : m_renderer(renderer)
{
}

// Render thread
void CommandExecuter::performAsynchronousCommandExecution(const QVector<Render::RenderView *> &views)
{
    QMutexLocker lock(&m_pendingCommandsMutex);
    const QVector<Qt3DCore::Debug::AsynchronousCommandReply *> shellCommands = std::move(m_pendingCommands);
    lock.unlock();

    for (auto *reply : shellCommands) {
        if (reply->commandName() == QLatin1String("glinfo")) {
            QJsonObject replyObj;
            const GraphicsApiFilterData *contextInfo = m_renderer->submissionContext()->contextInfo();
            if (contextInfo != nullptr) {
                replyObj.insert(QLatin1String("api"),
                                contextInfo->m_api == QGraphicsApiFilter::OpenGL
                                ? QLatin1String("OpenGL")
                                : QLatin1String("OpenGLES"));
                const QString versionString =
                        QString::number(contextInfo->m_major)
                        + QStringLiteral(".")
                        + QString::number(contextInfo->m_minor);
                replyObj.insert(QLatin1String("version"), versionString);
                replyObj.insert(QLatin1String("profile"),
                                contextInfo->m_profile == QGraphicsApiFilter::CoreProfile
                                ? QLatin1String("Core")
                                : contextInfo->m_profile == QGraphicsApiFilter::CompatibilityProfile
                                  ? QLatin1String("Compatibility")
                                  : QLatin1String("None"));
            }
            reply->setData(QJsonDocument(replyObj).toJson());
        } else if (reply->commandName() == QLatin1String("rendercommands")) {
            QJsonObject replyObj;

            QJsonArray viewArray;
            for (Render::RenderView *v : views) {
                QJsonObject viewObj;
                viewObj.insert(QLatin1String("viewport"), typeToJsonValue(v->viewport()));
                viewObj.insert(QLatin1String("surfaceSize"), typeToJsonValue(v->surfaceSize()));
                viewObj.insert(QLatin1String("devicePixelRatio"), v->devicePixelRatio());
                viewObj.insert(QLatin1String("noDraw"), v->noDraw());
                viewObj.insert(QLatin1String("frustumCulling"), v->frustumCulling());
                viewObj.insert(QLatin1String("compute"), v->isCompute());
                viewObj.insert(QLatin1String("clearDepthValue"), v->clearDepthValue());
                viewObj.insert(QLatin1String("clearStencilValue"), v->clearStencilValue());

                QJsonArray renderCommandsArray;
                for (const Render::RenderCommand &c : v->commands()) {
                    QJsonObject commandObj;
                    Render::NodeManagers *nodeManagers = m_renderer->nodeManagers();
                    commandObj.insert(QLatin1String("shader"), backendNodeToJSon(c.m_shader, nodeManagers->shaderManager()));
                    commandObj.insert(QLatin1String("vao"),  double(c.m_vao.handle()));
                    commandObj.insert(QLatin1String("instanceCount"), c.m_instanceCount);
                    commandObj.insert(QLatin1String("geometry"),  backendNodeToJSon(c.m_geometry, nodeManagers->geometryManager()));
                    commandObj.insert(QLatin1String("geometryRenderer"),  backendNodeToJSon(c.m_geometryRenderer, nodeManagers->geometryRendererManager()));
                    commandObj.insert(QLatin1String("shaderParameterPack"), parameterPackToJson(c.m_parameterPack));

                    renderCommandsArray.push_back(commandObj);
                }
                viewObj.insert(QLatin1String("commands"), renderCommandsArray);
                viewArray.push_back(viewObj);
            }

            replyObj.insert(QLatin1String("renderViews"), viewArray);
            reply->setData(QJsonDocument(replyObj).toJson());
        }
        reply->setFinished(true);
    }
}

// Main thread
QVariant CommandExecuter::executeCommand(const QStringList &args)
{
    // Note: The replies will be deleted by the AspectCommandDebugger
    if (args.length() > 0 &&
            (args.first() == QLatin1String("glinfo") ||
             args.first() == QLatin1String("rendercommands"))) {
        auto reply = new Qt3DCore::Debug::AsynchronousCommandReply(args.first());
        QMutexLocker lock(&m_pendingCommandsMutex);
        m_pendingCommands.push_back(reply);
        return QVariant::fromValue(reply);
    }
    return QVariant();
}

} // Debug

} // Qt3DRenderer

QT_END_NAMESPACE
