/****************************************************************************
**
** Copyright (C) 2017 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:GPL-EXCEPT$
** 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 General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 3 as published by the Free Software
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
** 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-3.0.html.
**
** $QT_END_LICENSE$
**
****************************************************************************/


#include <QtTest/QTest>
#include <Qt3DRender/qshaderprogram.h>
#include <Qt3DRender/qshaderprogrambuilder.h>
#include <Qt3DRender/private/qshaderprogrambuilder_p.h>
#include <QObject>
#include <QSignalSpy>
#include <Qt3DCore/qpropertyupdatedchange.h>
#include <Qt3DCore/private/qnodecreatedchangegenerator_p.h>
#include <Qt3DCore/qnodecreatedchange.h>
#include "testpostmanarbiter.h"

class tst_QShaderProgramBuilder : public Qt3DRender::QShaderProgramBuilder
{
    Q_OBJECT
public:
    tst_QShaderProgramBuilder()
        : Qt3DRender::QShaderProgramBuilder()
    {
        qRegisterMetaType<Qt3DRender::QShaderProgram*>("Qt3DRender::QShaderProgram*");
    }

private Q_SLOTS:
    void checkDefaultConstruction()
    {
        // GIVEN
        Qt3DRender::QShaderProgramBuilder builder;

        // THEN
        QVERIFY(!builder.shaderProgram());
        QVERIFY(builder.enabledLayers().isEmpty());
        QCOMPARE(builder.vertexShaderGraph(), QUrl());
        QCOMPARE(builder.tessellationControlShaderGraph(), QUrl());
        QCOMPARE(builder.tessellationEvaluationShaderGraph(), QUrl());
        QCOMPARE(builder.geometryShaderGraph(), QUrl());
        QCOMPARE(builder.fragmentShaderGraph(), QUrl());
        QCOMPARE(builder.computeShaderGraph(), QUrl());
        QCOMPARE(builder.vertexShaderCode(), QByteArray());
        QCOMPARE(builder.fragmentShaderCode(), QByteArray());
        QCOMPARE(builder.computeShaderCode(), QByteArray());
        QCOMPARE(builder.geometryShaderCode(), QByteArray());
        QCOMPARE(builder.tessellationEvaluationShaderCode(), QByteArray());
        QCOMPARE(builder.tessellationControlShaderCode(), QByteArray());
    }

    void checkPropertyChanges()
    {
        // GIVEN
        Qt3DRender::QShaderProgramBuilder builder;

        {
            // WHEN
            QSignalSpy spy(&builder, SIGNAL(shaderProgramChanged(Qt3DRender::QShaderProgram*)));
            auto newValue = new Qt3DRender::QShaderProgram(&builder);
            builder.setShaderProgram(newValue);

            // THEN
            QVERIFY(spy.isValid());
            QCOMPARE(builder.shaderProgram(), newValue);
            QCOMPARE(spy.count(), 1);

            // WHEN
            spy.clear();
            builder.setShaderProgram(newValue);

            // THEN
            QCOMPARE(builder.shaderProgram(), newValue);
            QCOMPARE(spy.count(), 0);
        }
        {
            // WHEN
            QSignalSpy spy(&builder, SIGNAL(enabledLayersChanged(QStringList)));
            const auto newValue = QStringList() << "foo" << "bar";
            builder.setEnabledLayers(newValue);

            // THEN
            QVERIFY(spy.isValid());
            QCOMPARE(builder.enabledLayers(), newValue);
            QCOMPARE(spy.count(), 1);

            // WHEN
            spy.clear();
            builder.setEnabledLayers(newValue);

            // THEN
            QCOMPARE(builder.enabledLayers(), newValue);
            QCOMPARE(spy.count(), 0);
        }
        {
            // WHEN
            QSignalSpy spy(&builder, SIGNAL(vertexShaderGraphChanged(QUrl)));
            const auto newValue = QUrl::fromEncoded("qrc:/vertex.json");
            builder.setVertexShaderGraph(newValue);

            // THEN
            QVERIFY(spy.isValid());
            QCOMPARE(builder.vertexShaderGraph(), newValue);
            QCOMPARE(spy.count(), 1);

            // WHEN
            spy.clear();
            builder.setVertexShaderGraph(newValue);

            // THEN
            QCOMPARE(builder.vertexShaderGraph(), newValue);
            QCOMPARE(spy.count(), 0);
        }
        {
            // WHEN
            QSignalSpy spy(&builder, SIGNAL(tessellationControlShaderGraphChanged(QUrl)));
            const auto newValue = QUrl::fromEncoded("qrc:/tesscontrol.json");
            builder.setTessellationControlShaderGraph(newValue);

            // THEN
            QVERIFY(spy.isValid());
            QCOMPARE(builder.tessellationControlShaderGraph(), newValue);
            QCOMPARE(spy.count(), 1);

            // WHEN
            spy.clear();
            builder.setTessellationControlShaderGraph(newValue);

            // THEN
            QCOMPARE(builder.tessellationControlShaderGraph(), newValue);
            QCOMPARE(spy.count(), 0);
        }
        {
            // WHEN
            QSignalSpy spy(&builder, SIGNAL(tessellationEvaluationShaderGraphChanged(QUrl)));
            const auto newValue = QUrl::fromEncoded("qrc:/tesseval.json");
            builder.setTessellationEvaluationShaderGraph(newValue);

            // THEN
            QVERIFY(spy.isValid());
            QCOMPARE(builder.tessellationEvaluationShaderGraph(), newValue);
            QCOMPARE(spy.count(), 1);

            // WHEN
            spy.clear();
            builder.setTessellationEvaluationShaderGraph(newValue);

            // THEN
            QCOMPARE(builder.tessellationEvaluationShaderGraph(), newValue);
            QCOMPARE(spy.count(), 0);
        }
        {
            // WHEN
            QSignalSpy spy(&builder, SIGNAL(geometryShaderGraphChanged(QUrl)));
            const auto newValue = QUrl::fromEncoded("qrc:/geometry.json");
            builder.setGeometryShaderGraph(newValue);

            // THEN
            QVERIFY(spy.isValid());
            QCOMPARE(builder.geometryShaderGraph(), newValue);
            QCOMPARE(spy.count(), 1);

            // WHEN
            spy.clear();
            builder.setGeometryShaderGraph(newValue);

            // THEN
            QCOMPARE(builder.geometryShaderGraph(), newValue);
            QCOMPARE(spy.count(), 0);
        }
        {
            // WHEN
            QSignalSpy spy(&builder, SIGNAL(fragmentShaderGraphChanged(QUrl)));
            const auto newValue = QUrl::fromEncoded("qrc:/fragment.json");
            builder.setFragmentShaderGraph(newValue);

            // THEN
            QVERIFY(spy.isValid());
            QCOMPARE(builder.fragmentShaderGraph(), newValue);
            QCOMPARE(spy.count(), 1);

            // WHEN
            spy.clear();
            builder.setFragmentShaderGraph(newValue);

            // THEN
            QCOMPARE(builder.fragmentShaderGraph(), newValue);
            QCOMPARE(spy.count(), 0);
        }
        {
            // WHEN
            QSignalSpy spy(&builder, SIGNAL(computeShaderGraphChanged(QUrl)));
            const auto newValue = QUrl::fromEncoded("qrc:/compute.json");
            builder.setComputeShaderGraph(newValue);

            // THEN
            QVERIFY(spy.isValid());
            QCOMPARE(builder.computeShaderGraph(), newValue);
            QCOMPARE(spy.count(), 1);

            // WHEN
            spy.clear();
            builder.setComputeShaderGraph(newValue);

            // THEN
            QCOMPARE(builder.computeShaderGraph(), newValue);
            QCOMPARE(spy.count(), 0);
        }
    }

    void checkShaderProgramBookkeeping()
    {
        // GIVEN
        QScopedPointer<Qt3DRender::QShaderProgramBuilder> builder(new Qt3DRender::QShaderProgramBuilder);
        {
            // WHEN
            Qt3DRender::QShaderProgram program;
            builder->setShaderProgram(&program);

            // THEN
            QCOMPARE(program.parent(), builder.data());
            QCOMPARE(builder->shaderProgram(), &program);
        }
        // THEN (Should not crash and effect be unset)
        QVERIFY(!builder->shaderProgram());

        {
            // WHEN
            Qt3DRender::QShaderProgramBuilder someOtherBuilder;
            QScopedPointer<Qt3DRender::QShaderProgram> program(new Qt3DRender::QShaderProgram(&someOtherBuilder));
            builder->setShaderProgram(program.data());

            // THEN
            QCOMPARE(program->parent(), &someOtherBuilder);
            QCOMPARE(builder->shaderProgram(), program.data());

            // WHEN
            builder.reset();
            program.reset();

            // THEN Should not crash when the effect is destroyed (tests for failed removal of destruction helper)
        }
    }

    void checkCreationData()
    {
        // GIVEN
        Qt3DRender::QShaderProgramBuilder builder;

        builder.setShaderProgram(new Qt3DRender::QShaderProgram(&builder));
        builder.setEnabledLayers({"foo", "bar"});
        builder.setVertexShaderGraph(QUrl::fromEncoded("qrc:/vertex.json"));
        builder.setTessellationControlShaderGraph(QUrl::fromEncoded("qrc:/tesscontrol.json"));
        builder.setTessellationEvaluationShaderGraph(QUrl::fromEncoded("qrc:/tesseval.json"));
        builder.setGeometryShaderGraph(QUrl::fromEncoded("qrc:/geometry.json"));
        builder.setFragmentShaderGraph(QUrl::fromEncoded("qrc:/fragment.json"));
        builder.setComputeShaderGraph(QUrl::fromEncoded("qrc:/compute.json"));

        // WHEN
        QVector<Qt3DCore::QNodeCreatedChangeBasePtr> creationChanges;

        {
            Qt3DCore::QNodeCreatedChangeGenerator creationChangeGenerator(&builder);
            creationChanges = creationChangeGenerator.creationChanges();
        }

        // THEN
        {
            QCOMPARE(creationChanges.size(), 2); // second one is for the shader program child

            const auto creationChangeData = qSharedPointerCast<Qt3DCore::QNodeCreatedChange<Qt3DRender::QShaderProgramBuilderData>>(creationChanges.first());
            const Qt3DRender::QShaderProgramBuilderData cloneData = creationChangeData->data;

            QCOMPARE(builder.shaderProgram()->id(), cloneData.shaderProgramId);
            QCOMPARE(builder.enabledLayers(), cloneData.enabledLayers);
            QCOMPARE(builder.vertexShaderGraph(), cloneData.vertexShaderGraph);
            QCOMPARE(builder.tessellationControlShaderGraph(), cloneData.tessellationControlShaderGraph);
            QCOMPARE(builder.tessellationEvaluationShaderGraph(), cloneData.tessellationEvaluationShaderGraph);
            QCOMPARE(builder.geometryShaderGraph(), cloneData.geometryShaderGraph);
            QCOMPARE(builder.fragmentShaderGraph(), cloneData.fragmentShaderGraph);
            QCOMPARE(builder.computeShaderGraph(), cloneData.computeShaderGraph);
            QCOMPARE(builder.id(), creationChangeData->subjectId());
            QCOMPARE(builder.isEnabled(), true);
            QCOMPARE(builder.isEnabled(), creationChangeData->isNodeEnabled());
            QCOMPARE(builder.metaObject(), creationChangeData->metaObject());
        }

        // WHEN
        builder.setEnabled(false);

        {
            Qt3DCore::QNodeCreatedChangeGenerator creationChangeGenerator(&builder);
            creationChanges = creationChangeGenerator.creationChanges();
        }

        // THEN
        {
            QCOMPARE(creationChanges.size(), 2); // second one is for the shader program child

            const auto creationChangeData = qSharedPointerCast<Qt3DCore::QNodeCreatedChange<Qt3DRender::QShaderProgramBuilderData>>(creationChanges.first());
            const Qt3DRender::QShaderProgramBuilderData cloneData = creationChangeData->data;

            QCOMPARE(builder.shaderProgram()->id(), cloneData.shaderProgramId);
            QCOMPARE(builder.enabledLayers(), cloneData.enabledLayers);
            QCOMPARE(builder.vertexShaderGraph(), cloneData.vertexShaderGraph);
            QCOMPARE(builder.tessellationControlShaderGraph(), cloneData.tessellationControlShaderGraph);
            QCOMPARE(builder.tessellationEvaluationShaderGraph(), cloneData.tessellationEvaluationShaderGraph);
            QCOMPARE(builder.geometryShaderGraph(), cloneData.geometryShaderGraph);
            QCOMPARE(builder.fragmentShaderGraph(), cloneData.fragmentShaderGraph);
            QCOMPARE(builder.computeShaderGraph(), cloneData.computeShaderGraph);
            QCOMPARE(builder.id(), creationChangeData->subjectId());
            QCOMPARE(builder.isEnabled(), false);
            QCOMPARE(builder.isEnabled(), creationChangeData->isNodeEnabled());
            QCOMPARE(builder.metaObject(), creationChangeData->metaObject());
        }
    }

    void checkShaderProgramUpdate()
    {
        // GIVEN
        TestArbiter arbiter;
        Qt3DRender::QShaderProgramBuilder builder;
        arbiter.setArbiterOnNode(&builder);
        auto program = new Qt3DRender::QShaderProgram(&builder);

        {
            // WHEN
            builder.setShaderProgram(program);
            QCoreApplication::processEvents();

            // THEN
            QCOMPARE(arbiter.events.size(), 0);
            QCOMPARE(arbiter.dirtyNodes.size(), 1);
            QCOMPARE(arbiter.dirtyNodes.front(), &builder);

            arbiter.dirtyNodes.clear();
        }

        {
            // WHEN
            builder.setShaderProgram(program);
            QCoreApplication::processEvents();

            // THEN
            QCOMPARE(arbiter.events.size(), 0);
            QCOMPARE(arbiter.dirtyNodes.size(), 0);
        }
    }

    void checkEnabledLayersUpdate()
    {
        // GIVEN
        TestArbiter arbiter;
        Qt3DRender::QShaderProgramBuilder builder;
        arbiter.setArbiterOnNode(&builder);
        const auto layers = QStringList() << "foo" << "bar";

        {
            // WHEN
            builder.setEnabledLayers(layers);
            QCoreApplication::processEvents();

            // THEN
            QCOMPARE(arbiter.events.size(), 0);
            QCOMPARE(arbiter.dirtyNodes.size(), 1);
            QCOMPARE(arbiter.dirtyNodes.front(), &builder);

            arbiter.dirtyNodes.clear();
        }

        {
            // WHEN
            builder.setEnabledLayers(layers);
            QCoreApplication::processEvents();

            // THEN
            QCOMPARE(arbiter.events.size(), 0);
            QCOMPARE(arbiter.dirtyNodes.size(), 0);
        }
    }

    void checkVertexShaderGraphUpdate()
    {
        // GIVEN
        TestArbiter arbiter;
        Qt3DRender::QShaderProgramBuilder builder;
        arbiter.setArbiterOnNode(&builder);

        {
            // WHEN
            builder.setVertexShaderGraph(QUrl::fromEncoded("qrc:/vertex.json"));
            QCoreApplication::processEvents();

            // THEN
            QCOMPARE(arbiter.events.size(), 0);
            QCOMPARE(arbiter.dirtyNodes.size(), 1);
            QCOMPARE(arbiter.dirtyNodes.front(), &builder);

            arbiter.dirtyNodes.clear();
        }

        {
            // WHEN
            builder.setVertexShaderGraph(QUrl::fromEncoded("qrc:/vertex.json"));
            QCoreApplication::processEvents();

            // THEN
            QCOMPARE(arbiter.events.size(), 0);
            QCOMPARE(arbiter.dirtyNodes.size(), 0);
        }

    }

    void checkTessellationControlShaderGraphUpdate()
    {
        // GIVEN
        TestArbiter arbiter;
        Qt3DRender::QShaderProgramBuilder builder;
        arbiter.setArbiterOnNode(&builder);

        {
            // WHEN
            builder.setTessellationControlShaderGraph(QUrl::fromEncoded("qrc:/tesscontrol.json"));
            QCoreApplication::processEvents();

            // THEN
            QCOMPARE(arbiter.events.size(), 0);
            QCOMPARE(arbiter.dirtyNodes.size(), 1);
            QCOMPARE(arbiter.dirtyNodes.front(), &builder);

            arbiter.dirtyNodes.clear();
        }

        {
            // WHEN
            builder.setTessellationControlShaderGraph(QUrl::fromEncoded("qrc:/tesscontrol.json"));
            QCoreApplication::processEvents();

            // THEN
            QCOMPARE(arbiter.events.size(), 0);
            QCOMPARE(arbiter.dirtyNodes.size(), 0);
        }

    }

    void checkTessellationEvaluationShaderGraphUpdate()
    {
        // GIVEN
        TestArbiter arbiter;
        Qt3DRender::QShaderProgramBuilder builder;
        arbiter.setArbiterOnNode(&builder);

        {
            // WHEN
            builder.setTessellationEvaluationShaderGraph(QUrl::fromEncoded("qrc:/tesseval.json"));
            QCoreApplication::processEvents();

            // THEN
            QCOMPARE(arbiter.events.size(), 0);
            QCOMPARE(arbiter.dirtyNodes.size(), 1);
            QCOMPARE(arbiter.dirtyNodes.front(), &builder);

            arbiter.dirtyNodes.clear();
        }

        {
            // WHEN
            builder.setTessellationEvaluationShaderGraph(QUrl::fromEncoded("qrc:/tesseval.json"));
            QCoreApplication::processEvents();

            // THEN
            QCOMPARE(arbiter.events.size(), 0);
            QCOMPARE(arbiter.dirtyNodes.size(), 0);
        }

    }

    void checkGeometryShaderGraphUpdate()
    {
        // GIVEN
        TestArbiter arbiter;
        Qt3DRender::QShaderProgramBuilder builder;
        arbiter.setArbiterOnNode(&builder);

        {
            // WHEN
            builder.setGeometryShaderGraph(QUrl::fromEncoded("qrc:/geometry.json"));
            QCoreApplication::processEvents();

            // THEN
            QCOMPARE(arbiter.events.size(), 0);
            QCOMPARE(arbiter.dirtyNodes.size(), 1);
            QCOMPARE(arbiter.dirtyNodes.front(), &builder);

            arbiter.dirtyNodes.clear();
        }

        {
            // WHEN
            builder.setGeometryShaderGraph(QUrl::fromEncoded("qrc:/geometry.json"));
            QCoreApplication::processEvents();

            // THEN
            QCOMPARE(arbiter.events.size(), 0);
            QCOMPARE(arbiter.dirtyNodes.size(), 0);
        }

    }

    void checkFragmentShaderGraphUpdate()
    {
        // GIVEN
        TestArbiter arbiter;
        Qt3DRender::QShaderProgramBuilder builder;
        arbiter.setArbiterOnNode(&builder);

        {
            // WHEN
            builder.setFragmentShaderGraph(QUrl::fromEncoded("qrc:/fragment.json"));
            QCoreApplication::processEvents();

            // THEN
            QCOMPARE(arbiter.events.size(), 0);
            QCOMPARE(arbiter.dirtyNodes.size(), 1);
            QCOMPARE(arbiter.dirtyNodes.front(), &builder);

            arbiter.dirtyNodes.clear();
        }

        {
            // WHEN
            builder.setFragmentShaderGraph(QUrl::fromEncoded("qrc:/fragment.json"));
            QCoreApplication::processEvents();

            // THEN
            QCOMPARE(arbiter.events.size(), 0);
            QCOMPARE(arbiter.dirtyNodes.size(), 0);
        }

    }

    void checkComputeShaderGraphUpdate()
    {
        // GIVEN
        TestArbiter arbiter;
        Qt3DRender::QShaderProgramBuilder builder;
        arbiter.setArbiterOnNode(&builder);

        {
            // WHEN
            builder.setComputeShaderGraph(QUrl::fromEncoded("qrc:/compute.json"));
            QCoreApplication::processEvents();

            // THEN
            QCOMPARE(arbiter.events.size(), 0);
            QCOMPARE(arbiter.dirtyNodes.size(), 1);
            QCOMPARE(arbiter.dirtyNodes.front(), &builder);

            arbiter.dirtyNodes.clear();
        }

        {
            // WHEN
            builder.setComputeShaderGraph(QUrl::fromEncoded("qrc:/compute.json"));
            QCoreApplication::processEvents();

            // THEN
            QCOMPARE(arbiter.events.size(), 0);
            QCOMPARE(arbiter.dirtyNodes.size(), 0);
        }
    }

    void checkGeneratedCodePropertyUpdates()
    {
        Qt3DRender::QShaderProgramBuilderPrivate *dBuilder = static_cast<decltype(dBuilder)>(Qt3DCore::QNodePrivate::get(this));
        {
            // WHEN
            QSignalSpy spy(this, SIGNAL(vertexShaderCodeChanged(QByteArray)));
            dBuilder->setShaderCode(QByteArrayLiteral("vertex"), Qt3DRender::QShaderProgram::Vertex);

            // THEN
            QVERIFY(spy.isValid());
            QCOMPARE(spy.count(), 1);
            QCOMPARE(vertexShaderCode(), QByteArrayLiteral("vertex"));
        }
        {
            // WHEN
            QSignalSpy spy(this, SIGNAL(fragmentShaderCodeChanged(QByteArray)));
            dBuilder->setShaderCode(QByteArrayLiteral("fragment"), Qt3DRender::QShaderProgram::Fragment);

            // THEN
            QVERIFY(spy.isValid());
            QCOMPARE(spy.count(), 1);
            QCOMPARE(fragmentShaderCode(), QByteArrayLiteral("fragment"));
        }
        {
            // WHEN
            QSignalSpy spy(this, SIGNAL(geometryShaderCodeChanged(QByteArray)));
            dBuilder->setShaderCode(QByteArrayLiteral("geometry"), Qt3DRender::QShaderProgram::Geometry);

            // THEN
            QVERIFY(spy.isValid());
            QCOMPARE(spy.count(), 1);
            QCOMPARE(geometryShaderCode(), QByteArrayLiteral("geometry"));
        }
        {
            // WHEN
            QSignalSpy spy(this, SIGNAL(computeShaderCodeChanged(QByteArray)));
            dBuilder->setShaderCode(QByteArrayLiteral("compute"), Qt3DRender::QShaderProgram::Compute);


            // THEN
            QVERIFY(spy.isValid());
            QCOMPARE(spy.count(), 1);
            QCOMPARE(computeShaderCode(), QByteArrayLiteral("compute"));
        }
        {
            // WHEN
            QSignalSpy spy(this, SIGNAL(tessellationControlShaderCodeChanged(QByteArray)));
            dBuilder->setShaderCode(QByteArrayLiteral("control"), Qt3DRender::QShaderProgram::TessellationControl);

            // THEN
            QVERIFY(spy.isValid());
            QCOMPARE(spy.count(), 1);
            QCOMPARE(tessellationControlShaderCode(), QByteArrayLiteral("control"));
        }
        {
            // WHEN
            QSignalSpy spy(this, SIGNAL(tessellationEvaluationShaderCodeChanged(QByteArray)));
            dBuilder->setShaderCode(QByteArrayLiteral("eval"), Qt3DRender::QShaderProgram::TessellationEvaluation);

            // THEN
            QVERIFY(spy.isValid());
            QCOMPARE(spy.count(), 1);
            QCOMPARE(tessellationEvaluationShaderCode(), QByteArrayLiteral("eval"));
        }
    }

};

QTEST_MAIN(tst_QShaderProgramBuilder)

#include "tst_qshaderprogrambuilder.moc"
