/****************************************************************************
**
** Copyright (C) 2017 The Qt Company Ltd.
** Contact: http://www.qt.io/licensing/
**
** This file is part of the test suite 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 <QtTest>
#include <QtQml>
#include <QtCore/private/qhooks_p.h>
#include <QtQml/private/qqmljsengine_p.h>
#include <QtQml/private/qqmljslexer_p.h>
#include <QtQml/private/qqmljsparser_p.h>
#include <QtQml/private/qqmljsast_p.h>
#include <QtQml/private/qqmljsastvisitor_p.h>
#include <QtQml/private/qqmlmetatype_p.h>
#include "../../auto/shared/visualtestutil.h"

using namespace QQuickVisualTestUtil;

Q_GLOBAL_STATIC(QObjectList, qt_qobjects)

extern "C" Q_DECL_EXPORT void qt_addQObject(QObject *object)
{
    qt_qobjects->append(object);
}

extern "C" Q_DECL_EXPORT void qt_removeQObject(QObject *object)
{
    qt_qobjects->removeAll(object);
}

class tst_Sanity : public QObject
{
    Q_OBJECT

private slots:
    void init();
    void cleanup();
    void initTestCase();

    void jsFiles();
    void functions();
    void functions_data();
    void signalHandlers();
    void signalHandlers_data();
    void anchors();
    void anchors_data();
    void attachedObjects();
    void attachedObjects_data();
    void ids();
    void ids_data();

private:
    QQmlEngine engine;
    QMap<QString, QString> files;
};

void tst_Sanity::init()
{
    qtHookData[QHooks::AddQObject] = reinterpret_cast<quintptr>(&qt_addQObject);
    qtHookData[QHooks::RemoveQObject] = reinterpret_cast<quintptr>(&qt_removeQObject);
}

void tst_Sanity::cleanup()
{
    qt_qobjects->clear();
    qtHookData[QHooks::AddQObject] = 0;
    qtHookData[QHooks::RemoveQObject] = 0;
}

class BaseValidator : public QQmlJS::AST::Visitor
{
public:
    QString errors() const { return m_errors.join(", "); }

    bool validate(const QString& filePath)
    {
        m_errors.clear();
        m_fileName = QFileInfo(filePath).fileName();

        QFile file(filePath);
        if (!file.open(QFile::ReadOnly)) {
            m_errors += QString("%1: failed to open (%2)").arg(m_fileName, file.errorString());
            return false;
        }

        QQmlJS::Engine engine;
        QQmlJS::Lexer lexer(&engine);
        lexer.setCode(QString::fromUtf8(file.readAll()), /*line = */ 1);

        QQmlJS::Parser parser(&engine);
        if (!parser.parse()) {
            const auto diagnosticMessages = parser.diagnosticMessages();
            for (const QQmlJS::DiagnosticMessage &msg : diagnosticMessages)
#if Q_QML_PRIVATE_API_VERSION < 5
                m_errors += QString("%s:%d : %s").arg(m_fileName).arg(msg.loc.startLine).arg(msg.message);
#else
                m_errors += QString("%s:%d : %s").arg(m_fileName).arg(msg.line).arg(msg.message);
#endif
            return false;
        }

        QQmlJS::AST::UiProgram* ast = parser.ast();
        ast->accept(this);
        return m_errors.isEmpty();
    }

protected:
    void addError(const QString& error, QQmlJS::AST::Node *node)
    {
        m_errors += QString("%1:%2 : %3").arg(m_fileName).arg(node->firstSourceLocation().startLine).arg(error);
    }

    void throwRecursionDepthError() final
    {
        m_errors += QString::fromLatin1("%1: Maximum statement or expression depth exceeded")
                            .arg(m_fileName);
    }

private:
    QString m_fileName;
    QStringList m_errors;
};

void tst_Sanity::initTestCase()
{
    QQmlEngine engine;
    QQmlComponent component(&engine);
    component.setData(QString("import QtQuick.Templates 2.%1; Control { }").arg(QT_VERSION_MINOR - 7).toUtf8(), QUrl());

    const QStringList qmlTypeNames = QQmlMetaType::qmlTypeNames();

    QDirIterator it(QQC2_IMPORT_PATH, QStringList() << "*.qml" << "*.js", QDir::Files, QDirIterator::Subdirectories);
    while (it.hasNext()) {
        it.next();
        QFileInfo info = it.fileInfo();
        if (qmlTypeNames.contains(QStringLiteral("QtQuick.Templates/") + info.baseName()))
            files.insert(info.dir().dirName() + "/" + info.fileName(), info.filePath());
    }
}

void tst_Sanity::jsFiles()
{
    QMap<QString, QString>::const_iterator it;
    for (it = files.constBegin(); it != files.constEnd(); ++it) {
        if (QFileInfo(it.value()).suffix() == QStringLiteral("js"))
            QFAIL(qPrintable(it.value() +  ": JS files are not allowed"));
    }
}

class FunctionValidator : public BaseValidator
{
protected:
    virtual bool visit(QQmlJS::AST::FunctionDeclaration *node)
    {
        addError("function declarations are not allowed", node);
        return true;
    }
};

void tst_Sanity::functions()
{
    QFETCH(QString, control);
    QFETCH(QString, filePath);

    FunctionValidator validator;
    if (!validator.validate(filePath))
        QFAIL(qPrintable(validator.errors()));
}

void tst_Sanity::functions_data()
{
    QTest::addColumn<QString>("control");
    QTest::addColumn<QString>("filePath");

    QMap<QString, QString>::const_iterator it;
    for (it = files.constBegin(); it != files.constEnd(); ++it)
        QTest::newRow(qPrintable(it.key())) << it.key() << it.value();
}

class SignalHandlerValidator : public BaseValidator
{
protected:
    static bool isSignalHandler(const QStringRef &name)
    {
        return name.length() > 2 && name.startsWith("on") && name.at(2).isUpper();
    }

    virtual bool visit(QQmlJS::AST::UiScriptBinding *node)
    {
        QQmlJS::AST::UiQualifiedId* id = node->qualifiedId;
        if ((id && isSignalHandler(id->name)) || (id && id->next && isSignalHandler(id->next->name)))
            addError("signal handlers are not allowed", node);
        return true;
    }
};

void tst_Sanity::signalHandlers()
{
    QFETCH(QString, control);
    QFETCH(QString, filePath);

    SignalHandlerValidator validator;
    if (!validator.validate(filePath))
        QFAIL(qPrintable(validator.errors()));
}

void tst_Sanity::signalHandlers_data()
{
    QTest::addColumn<QString>("control");
    QTest::addColumn<QString>("filePath");

    QMap<QString, QString>::const_iterator it;
    for (it = files.constBegin(); it != files.constEnd(); ++it)
        QTest::newRow(qPrintable(it.key())) << it.key() << it.value();
}

class AnchorValidator : public BaseValidator
{
protected:
    virtual bool visit(QQmlJS::AST::UiScriptBinding *node)
    {
        QQmlJS::AST::UiQualifiedId* id = node->qualifiedId;
        if (id && id->name ==  QStringLiteral("anchors"))
            addError("anchors are not allowed", node);
        return true;
    }
};

void tst_Sanity::anchors()
{
    QFETCH(QString, control);
    QFETCH(QString, filePath);

    AnchorValidator validator;
    if (!validator.validate(filePath))
        QFAIL(qPrintable(validator.errors()));
}

void tst_Sanity::anchors_data()
{
    QTest::addColumn<QString>("control");
    QTest::addColumn<QString>("filePath");

    QMap<QString, QString>::const_iterator it;
    for (it = files.constBegin(); it != files.constEnd(); ++it)
        QTest::newRow(qPrintable(it.key())) << it.key() << it.value();
}

class IdValidator : public BaseValidator
{
public:
    IdValidator() : m_depth(0) { }

protected:
    bool visit(QQmlJS::AST::UiObjectBinding *) override
    {
        ++m_depth;
        return true;
    }

    void endVisit(QQmlJS::AST::UiObjectBinding *) override
    {
        --m_depth;
    }

    bool visit(QQmlJS::AST::UiScriptBinding *node) override
    {
        if (m_depth == 0)
            return true;

        QQmlJS::AST::UiQualifiedId *id = node->qualifiedId;
        if (id && id->name ==  QStringLiteral("id"))
            addError(QString("Internal IDs are not allowed (%1)").arg(extractName(node->statement)), node);
        return true;
    }

private:
    QString extractName(QQmlJS::AST::Statement *statement)
    {
        QQmlJS::AST::ExpressionStatement *expressionStatement = static_cast<QQmlJS::AST::ExpressionStatement *>(statement);
        if (!expressionStatement)
            return QString();

        QQmlJS::AST::IdentifierExpression *expression = static_cast<QQmlJS::AST::IdentifierExpression *>(expressionStatement->expression);
        if (!expression)
            return QString();

        return expression->name.toString();
    }

    int m_depth;
};

void tst_Sanity::ids()
{
    QFETCH(QString, control);
    QFETCH(QString, filePath);

    IdValidator validator;
    if (!validator.validate(filePath))
        QFAIL(qPrintable(validator.errors()));
}

void tst_Sanity::ids_data()
{
    QTest::addColumn<QString>("control");
    QTest::addColumn<QString>("filePath");

    QMap<QString, QString>::const_iterator it;
    for (it = files.constBegin(); it != files.constEnd(); ++it)
        QTest::newRow(qPrintable(it.key())) << it.key() << it.value();
}

void tst_Sanity::attachedObjects()
{
    QFETCH(QUrl, url);

    QQmlComponent component(&engine);
    component.loadUrl(url);

    QSet<QString> classNames;
    QScopedPointer<QObject> object(component.create());
    QVERIFY2(object.data(), qPrintable(component.errorString()));
    for (QObject *object : qAsConst(*qt_qobjects)) {
        if (object->parent() == &engine)
            continue; // allow "global" instances
        QString className = object->metaObject()->className();
        if (className.endsWith("Attached") || className.endsWith("Style"))
            QVERIFY2(!classNames.contains(className), qPrintable(QString("Multiple %1 instances").arg(className)));
        classNames.insert(className);
    }
}

void tst_Sanity::attachedObjects_data()
{
    QTest::addColumn<QUrl>("url");
    addTestRowForEachControl(&engine, "calendar", "Qt/labs/calendar");
    addTestRowForEachControl(&engine, "controls", "QtQuick/Controls.2");
    addTestRowForEachControl(&engine, "controls/fusion", "QtQuick/Controls.2", QStringList() << "CheckIndicator" << "RadioIndicator" << "SliderGroove" << "SliderHandle" << "SwitchIndicator");
    addTestRowForEachControl(&engine, "controls/material", "QtQuick/Controls.2/Material", QStringList() << "Ripple" << "SliderHandle" << "CheckIndicator" << "RadioIndicator" << "SwitchIndicator" << "BoxShadow" << "ElevationEffect" << "CursorDelegate");
    addTestRowForEachControl(&engine, "controls/universal", "QtQuick/Controls.2/Universal", QStringList() << "CheckIndicator" << "RadioIndicator" << "SwitchIndicator");
}

QTEST_MAIN(tst_Sanity)

#include "tst_sanity.moc"
