/****************************************************************************
**
** Copyright (C) 2017 Crimson AS <info@crimson.no>
** Copyright (C) 2016 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the test suite 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 "quicktestresult_p.h"
#include "quicktest.h"
#include <QtTest/qtestcase.h>
#include <QtTest/qtestsystem.h>
#include <QtTest/private/qtestblacklist_p.h>
#include <QtTest/private/qtestresult_p.h>
#include <QtTest/private/qtesttable_p.h>
#include <QtTest/private/qtestlog_p.h>
#include "qtestoptions_p.h"
#include <QtTest/qbenchmark.h>
// qbenchmark_p.h pulls windows.h via 3rd party; prevent it from defining
// the min/max macros which would clash with qnumeric_p.h's usage of min()/max().
#if defined(Q_OS_WIN32) && !defined(NOMINMAX)
#  define NOMINMAX
#endif
#include <QtTest/private/qbenchmark_p.h>
#include <QtCore/qset.h>
#include <QtCore/qmap.h>
#include <QtCore/qbytearray.h>
#include <QtCore/qcoreapplication.h>
#include <QtCore/qdatetime.h>
#include <QtCore/qdebug.h>
#include <QtCore/QUrl>
#include <QtCore/QDir>
#if QT_CONFIG(regularexpression)
#include <QtCore/qregularexpression.h>
#endif
#include <QtQuick/qquickwindow.h>
#include <QtGui/qvector3d.h>
#include <QtGui/qimagewriter.h>
#include <QtQml/private/qqmlglobal_p.h>
#include <QtQml/QQmlEngine>
#include <QtQml/QQmlContext>
#include <private/qv4qobjectwrapper_p.h>

#include <algorithm>

QT_BEGIN_NAMESPACE

static const char *globalProgramName = nullptr;
static bool loggingStarted = false;
static QBenchmarkGlobalData globalBenchmarkData;

extern bool qWaitForSignal(QObject *obj, const char* signal, int timeout = 5000);

class Q_QUICK_TEST_EXPORT QuickTestImageObject : public QObject
{
    Q_OBJECT

    Q_PROPERTY(int width READ width CONSTANT)
    Q_PROPERTY(int height READ height CONSTANT)
    Q_PROPERTY(QSize size READ size CONSTANT)

public:
    QuickTestImageObject(const QImage& img, QObject *parent = nullptr)
        : QObject(parent)
        , m_image(img)
    {
    }

    ~QuickTestImageObject() {}

public Q_SLOTS:
    int red(int x, int y) const
    {
        return pixel(x, y).value<QColor>().red();
    }

    int green(int x, int y) const
    {
        return pixel(x, y).value<QColor>().green();
    }

    int blue(int x, int y) const
    {
        return pixel(x, y).value<QColor>().blue();
    }

    int alpha(int x, int y) const
    {
        return pixel(x, y).value<QColor>().alpha();
    }

    QVariant pixel(int x, int y) const
    {
        if (m_image.isNull()
         || x >= m_image.width()
         || y >= m_image.height()
         || x < 0
         || y < 0
         || x * y >= m_image.width() * m_image.height())
            return QVariant();

        return QColor::fromRgba(m_image.pixel(QPoint(x, y)));
    }

    bool equals(QuickTestImageObject *other) const
    {
        if (!other)
            return m_image.isNull();

        return m_image == other->m_image;
    }

    void save(const QString &filePath)
    {
        QImageWriter writer(filePath);
        if (!writer.write(m_image)) {
            QQmlEngine *engine = qmlContext(this)->engine();
            QV4::ExecutionEngine *v4 = engine->handle();
            v4->throwError(QStringLiteral("Can't save to %1: %2").arg(filePath, writer.errorString()));
        }
    }

public:
    int width() const
    {
        return m_image.width();
    }

    int height() const
    {
        return m_image.height();
    }

    QSize size() const
    {
        return m_image.size();
    }

private:
    QImage m_image;
};

class QuickTestResultPrivate
{
public:
    QuickTestResultPrivate()
        : table(nullptr)
        , benchmarkIter(nullptr)
        , benchmarkData(nullptr)
        , iterCount(0)
    {
    }
    ~QuickTestResultPrivate()
    {
        delete table;
        delete benchmarkIter;
        delete benchmarkData;
    }

    QByteArray intern(const QString &str);

    QString testCaseName;
    QString functionName;
    QSet<QByteArray> internedStrings;
    QTestTable *table;
    QTest::QBenchmarkIterationController *benchmarkIter;
    QBenchmarkTestMethodData *benchmarkData;
    int iterCount;
    QList<QBenchmarkResult> results;
};

QByteArray QuickTestResultPrivate::intern(const QString &str)
{
    QByteArray bstr = str.toUtf8();
    return *(internedStrings.insert(bstr));
}

QuickTestResult::QuickTestResult(QObject *parent)
    : QObject(parent), d_ptr(new QuickTestResultPrivate)
{
    if (!QBenchmarkGlobalData::current)
        QBenchmarkGlobalData::current = &globalBenchmarkData;
}

QuickTestResult::~QuickTestResult()
{
}

/*!
    \qmlproperty string TestResult::testCaseName

    This property defines the name of current TestCase element
    that is running test cases.

    \sa functionName
*/
QString QuickTestResult::testCaseName() const
{
    Q_D(const QuickTestResult);
    return d->testCaseName;
}

void QuickTestResult::setTestCaseName(const QString &name)
{
    Q_D(QuickTestResult);
    d->testCaseName = name;
    emit testCaseNameChanged();
}

/*!
    \qmlproperty string TestResult::functionName

    This property defines the name of current test function
    within a TestCase element that is running.  If this string is
    empty, then no function is currently running.

    \sa testCaseName
*/
QString QuickTestResult::functionName() const
{
    Q_D(const QuickTestResult);
    return d->functionName;
}

void QuickTestResult::setFunctionName(const QString &name)
{
    Q_D(QuickTestResult);
    if (!name.isEmpty()) {
        if (d->testCaseName.isEmpty()) {
            QTestResult::setCurrentTestFunction
                (d->intern(name).constData());
        } else {
            QString fullName = d->testCaseName + QLatin1String("::") + name;
            QTestResult::setCurrentTestFunction
                (d->intern(fullName).constData());
            QTestPrivate::checkBlackLists(fullName.toUtf8().constData(), nullptr);
        }
    } else {
        QTestResult::setCurrentTestFunction(nullptr);
    }
    d->functionName = name;
    emit functionNameChanged();
}

/*!
    \qmlproperty string TestResult::dataTag

    This property defines the tag for the current row in a
    data-driven test, or an empty string if not a data-driven test.
*/
QString QuickTestResult::dataTag() const
{
    const char *tag = QTestResult::currentDataTag();
    if (tag)
        return QString::fromUtf8(tag);
    else
        return QString();
}

void QuickTestResult::setDataTag(const QString &tag)
{
    if (!tag.isEmpty()) {
        QTestData *data = &(QTest::newRow(tag.toUtf8().constData()));
        QTestResult::setCurrentTestData(data);
        QTestPrivate::checkBlackLists((testCaseName() + QLatin1String("::") + functionName()).toUtf8().constData(), tag.toUtf8().constData());
        emit dataTagChanged();
    } else {
        QTestResult::setCurrentTestData(nullptr);
    }
}

/*!
    \qmlproperty bool TestResult::failed

    This property returns true if the current test function (or
    current test data row for a data-driven test) has failed;
    false otherwise.  The fail state is reset when functionName
    is changed or finishTestDataCleanup() is called.

    \sa skipped
*/
bool QuickTestResult::isFailed() const
{
    return QTestResult::currentTestFailed();
}

/*!
    \qmlproperty bool TestResult::skipped

    This property returns true if the current test function was
    marked as skipped; false otherwise.

    \sa failed
*/
bool QuickTestResult::isSkipped() const
{
    return QTestResult::skipCurrentTest();
}

void QuickTestResult::setSkipped(bool skip)
{
    QTestResult::setSkipCurrentTest(skip);
    if (!skip)
        QTestResult::setBlacklistCurrentTest(false);
    emit skippedChanged();
}

/*!
    \qmlproperty int TestResult::passCount

    This property returns the number of tests that have passed.

    \sa failCount, skipCount
*/
int QuickTestResult::passCount() const
{
    return QTestLog::passCount();
}

/*!
    \qmlproperty int TestResult::failCount

    This property returns the number of tests that have failed.

    \sa passCount, skipCount
*/
int QuickTestResult::failCount() const
{
    return QTestLog::failCount();
}

/*!
    \qmlproperty int TestResult::skipCount

    This property returns the number of tests that have been skipped.

    \sa passCount, failCount
*/
int QuickTestResult::skipCount() const
{
    return QTestLog::skipCount();
}

/*!
    \qmlproperty list<string> TestResult::functionsToRun

    This property returns the list of function names to be run.
*/
QStringList QuickTestResult::functionsToRun() const
{
    return QTest::testFunctions;
}

/*!
    \qmlproperty list<string> TestResult::tagsToRun

    This property returns the list of test function's data tags to be run
*/
QStringList QuickTestResult::tagsToRun() const
{
    return QTest::testTags;
}

/*!
    \qmlmethod TestResult::reset()

    Resets all pass/fail/skip counters and prepare for testing.
*/
void QuickTestResult::reset()
{
    if (!globalProgramName)     // Only if run via qmlviewer.
        QTestResult::reset();
}

/*!
    \qmlmethod TestResult::startLogging()

    Starts logging to the test output stream and writes the
    test header.

    \sa stopLogging()
*/
void QuickTestResult::startLogging()
{
    // The program name is used for logging headers and footers if it
    // is set.  Otherwise the test case name is used.
    if (loggingStarted)
        return;
    QTestLog::startLogging();
    loggingStarted = true;
}

/*!
    \qmlmethod TestResult::stopLogging()

    Writes the test footer to the test output stream and then stops logging.

    \sa startLogging()
*/
void QuickTestResult::stopLogging()
{
    Q_D(QuickTestResult);
    if (globalProgramName)
        return;     // Logging will be stopped by setProgramName(0).
    QTestResult::setCurrentTestObject(d->intern(d->testCaseName).constData());
    QTestLog::stopLogging();
}

void QuickTestResult::initTestTable()
{
    Q_D(QuickTestResult);
    delete d->table;
    d->table = new QTestTable;
    //qmltest does not really need the column for data driven test
    //add this to avoid warnings.
    d->table->addColumn(qMetaTypeId<QString>(), "qmltest_dummy_data_column");
}

void QuickTestResult::clearTestTable()
{
    Q_D(QuickTestResult);
    delete d->table;
    d->table = nullptr;
}

void QuickTestResult::finishTestData()
{
    QTestResult::finishedCurrentTestData();
}

void QuickTestResult::finishTestDataCleanup()
{
    QTestResult::finishedCurrentTestDataCleanup();
}

void QuickTestResult::finishTestFunction()
{
    QTestResult::finishedCurrentTestFunction();
}

static QString qtestFixUrl(const QUrl &location)
{
    if (location.isLocalFile()) // Use QUrl's logic for Windows drive letters.
        return QDir::toNativeSeparators(location.toLocalFile());
    return location.toString();
}

void QuickTestResult::fail
    (const QString &message, const QUrl &location, int line)
{
    QTestResult::addFailure(message.toUtf8().constData(),
                            qtestFixUrl(location).toLatin1().constData(), line);
}

bool QuickTestResult::verify
    (bool success, const QString &message, const QUrl &location, int line)
{
    if (!success && message.isEmpty()) {
        return QTestResult::verify
            (success, "verify()", "",
             qtestFixUrl(location).toLatin1().constData(), line);
    } else {
        return QTestResult::verify
            (success, message.toUtf8().constData(), "",
             qtestFixUrl(location).toLatin1().constData(), line);
    }
}

bool QuickTestResult::fuzzyCompare(const QVariant &actual, const QVariant &expected, qreal delta)
{
    if (actual.userType() == QMetaType::QColor || expected.userType() == QMetaType::QColor) {
        if (!actual.canConvert(QMetaType::QColor) || !expected.canConvert(QMetaType::QColor))
            return false;

        //fuzzy color comparison
        QColor act;
        QColor exp;
        bool ok(false);

        QVariant var = QQml_colorProvider()->colorFromString(actual.toString(), &ok);
        if (!ok)
            return false;
        act = var.value<QColor>();

        QQml_colorProvider()->colorFromString(expected.toString(), &ok);
        if (!ok)
            return false;
        exp = var.value<QColor>();

        return ( qAbs(act.red() - exp.red()) <= delta
              && qAbs(act.green() - exp.green()) <= delta
              && qAbs(act.blue() - exp.blue()) <= delta
              && qAbs(act.alpha() - exp.alpha()) <= delta);
    } else {
        //number comparison
        bool ok = true;
        qreal act = actual.toFloat(&ok);
        if (!ok)
            return false;

        qreal exp = expected.toFloat(&ok);
        if (!ok)
            return false;

        return (qAbs(act - exp) <= delta);
    }

    return false;
}

void QuickTestResult::stringify(QQmlV4Function *args)
{
    if (args->length() < 1)
        args->setReturnValue(QV4::Encode::null());

    QV4::Scope scope(args->v4engine());
    QV4::ScopedValue value(scope, (*args)[0]);

    QString result;

    //Check for Object Type
    if (value->isObject()
        && !value->as<QV4::FunctionObject>()
        && !value->as<QV4::ArrayObject>()) {
        QVariant v = scope.engine->toVariant(value, QMetaType::UnknownType);
        if (v.isValid()) {
            switch (v.userType()) {
            case QMetaType::QVector3D:
            {
                QVector3D v3d = v.value<QVector3D>();
                result = QString::fromLatin1("Qt.vector3d(%1, %2, %3)").arg(v3d.x()).arg(v3d.y()).arg(v3d.z());
                break;
            }
            case QMetaType::QUrl:
            {
                QUrl url = v.value<QUrl>();
                result = QString::fromLatin1("Qt.url(%1)").arg(url.toString());
                break;
            }
            case QMetaType::QDateTime:
            {
                QDateTime dt = v.value<QDateTime>();
                result = dt.toString(Qt::ISODateWithMs);
                break;
            }
            default:
                result = v.toString();
            }

        } else {
            result = QLatin1String("Object");
        }
    }

    if (result.isEmpty()) {
        QString tmp = value->toQStringNoThrow();
        if (value->as<QV4::ArrayObject>())
            result += QLatin1Char('[') + tmp + QLatin1Char(']');
        else
            result.append(tmp);
    }

    args->setReturnValue(QV4::Encode(args->v4engine()->newString(result)));
}

bool QuickTestResult::compare
    (bool success, const QString &message,
     const QVariant &val1, const QVariant &val2,
     const QUrl &location, int line)
{
    return QTestResult::compare
        (success, message.toUtf8().constData(),
         QTest::toString(val1.toString().toLatin1().constData()),
         QTest::toString(val2.toString().toLatin1().constData()),
         "", "",
         qtestFixUrl(location).toLatin1().constData(), line);
}

void QuickTestResult::skip
    (const QString &message, const QUrl &location, int line)
{
    QTestResult::addSkip(message.toUtf8().constData(),
                         qtestFixUrl(location).toLatin1().constData(), line);
    QTestResult::setSkipCurrentTest(true);
}

bool QuickTestResult::expectFail
    (const QString &tag, const QString &comment, const QUrl &location, int line)
{
    return QTestResult::expectFail
        (tag.toLatin1().constData(),
         QTest::toString(comment.toLatin1().constData()),
         QTest::Abort, qtestFixUrl(location).toLatin1().constData(), line);
}

bool QuickTestResult::expectFailContinue
    (const QString &tag, const QString &comment, const QUrl &location, int line)
{
    return QTestResult::expectFail
        (tag.toLatin1().constData(),
         QTest::toString(comment.toUtf8().constData()),
         QTest::Continue, qtestFixUrl(location).toLatin1().constData(), line);
}

void QuickTestResult::warn(const QString &message, const QUrl &location, int line)
{
    QTestLog::warn(message.toUtf8().constData(), qtestFixUrl(location).toLatin1().constData(), line);
}

void QuickTestResult::ignoreWarning(const QJSValue &message)
{
    if (message.isRegExp()) {
#if QT_CONFIG(regularexpression)
        QTestLog::ignoreMessage(QtWarningMsg, message.toVariant().toRegularExpression());
#endif
    } else {
        QTestLog::ignoreMessage(QtWarningMsg, message.toString().toUtf8());
    }
}

void QuickTestResult::wait(int ms)
{
    QTest::qWait(ms);
}

void QuickTestResult::sleep(int ms)
{
    QTest::qSleep(ms);
}

bool QuickTestResult::waitForRendering(QQuickItem *item, int timeout)
{
    Q_ASSERT(item);

    return qWaitForSignal(item->window(), SIGNAL(frameSwapped()), timeout);
}

void QuickTestResult::startMeasurement()
{
    Q_D(QuickTestResult);
    delete d->benchmarkData;
    d->benchmarkData = new QBenchmarkTestMethodData();
    QBenchmarkTestMethodData::current = d->benchmarkData;
    d->iterCount = (QBenchmarkGlobalData::current->measurer->needsWarmupIteration()) ? -1 : 0;
    d->results.clear();
}

void QuickTestResult::beginDataRun()
{
    QBenchmarkTestMethodData::current->beginDataRun();
}

void QuickTestResult::endDataRun()
{
    Q_D(QuickTestResult);
    QBenchmarkTestMethodData::current->endDataRun();
    if (d->iterCount > -1)  // iteration -1 is the warmup iteration.
        d->results.append(QBenchmarkTestMethodData::current->result);

    if (QBenchmarkGlobalData::current->verboseOutput) {
        if (d->iterCount == -1) {
            qDebug() << "warmup stage result      :" << QBenchmarkTestMethodData::current->result.value;
        } else {
            qDebug() << "accumulation stage result:" << QBenchmarkTestMethodData::current->result.value;
        }
    }
}

bool QuickTestResult::measurementAccepted()
{
    return QBenchmarkTestMethodData::current->resultsAccepted();
}

static QBenchmarkResult qMedian(const QList<QBenchmarkResult> &container)
{
    const int count = container.count();
    if (count == 0)
        return QBenchmarkResult();

    if (count == 1)
        return container.at(0);

    QList<QBenchmarkResult> containerCopy = container;
    std::sort(containerCopy.begin(), containerCopy.end());

    const int middle = count / 2;

    // ### handle even-sized containers here by doing an aritmetic mean of the two middle items.
    return containerCopy.at(middle);
}

bool QuickTestResult::needsMoreMeasurements()
{
    Q_D(QuickTestResult);
    ++(d->iterCount);
    if (d->iterCount < QBenchmarkGlobalData::current->adjustMedianIterationCount())
        return true;
    if (QBenchmarkTestMethodData::current->resultsAccepted())
        QTestLog::addBenchmarkResult(qMedian(d->results));
    return false;
}

void QuickTestResult::startBenchmark(RunMode runMode, const QString &tag)
{
    QBenchmarkTestMethodData::current->result = QBenchmarkResult();
    QBenchmarkTestMethodData::current->resultAccepted = false;
    QBenchmarkGlobalData::current->context.tag = tag;
    QBenchmarkGlobalData::current->context.slotName = functionName();

    Q_D(QuickTestResult);
    delete d->benchmarkIter;
    d->benchmarkIter = new QTest::QBenchmarkIterationController
        (QTest::QBenchmarkIterationController::RunMode(runMode));
}

bool QuickTestResult::isBenchmarkDone() const
{
    Q_D(const QuickTestResult);
    if (d->benchmarkIter)
        return d->benchmarkIter->isDone();
    else
        return true;
}

void QuickTestResult::nextBenchmark()
{
    Q_D(QuickTestResult);
    if (d->benchmarkIter)
        d->benchmarkIter->next();
}

void QuickTestResult::stopBenchmark()
{
    Q_D(QuickTestResult);
    delete d->benchmarkIter;
    d->benchmarkIter = nullptr;
}

QObject *QuickTestResult::grabImage(QQuickItem *item)
{
    if (item && item->window()) {
        QQuickWindow *window = item->window();
        QImage grabbed = window->grabWindow();
        QRectF rf(item->x(), item->y(), item->width(), item->height());
        rf = rf.intersected(QRectF(0, 0, grabbed.width(), grabbed.height()));
        QObject *o = new QuickTestImageObject(grabbed.copy(rf.toAlignedRect()));
        QQmlEngine::setContextForObject(o, qmlContext(this));
        return o;
    }
    return nullptr;
}

QObject *QuickTestResult::findChild(QObject *parent, const QString &objectName)
{
    return parent ? parent->findChild<QObject*>(objectName) : 0;
}

bool QuickTestResult::isPolishScheduled(QQuickItem *item) const
{
    return QQuickTest::qIsPolishScheduled(item);
}

bool QuickTestResult::waitForItemPolished(QQuickItem *item, int timeout)
{
    return QQuickTest::qWaitForItemPolished(item, timeout);
}

namespace QTest {
    void qtest_qParseArgs(int argc, char *argv[], bool qml);
};

void QuickTestResult::parseArgs(int argc, char *argv[])
{
    if (!QBenchmarkGlobalData::current)
        QBenchmarkGlobalData::current = &globalBenchmarkData;
    QTest::qtest_qParseArgs(argc, argv, true);
}

void QuickTestResult::setProgramName(const char *name)
{
    if (name) {
        QTestPrivate::parseBlackList();
        QTestResult::reset();
    } else if (!name && loggingStarted) {
        QTestResult::setCurrentTestObject(globalProgramName);
        QTestLog::stopLogging();
        QTestResult::setCurrentTestObject(nullptr);
    }
    globalProgramName = name;
    QTestResult::setCurrentTestObject(globalProgramName);
}

void QuickTestResult::setCurrentAppname(const char *appname)
{
    QTestResult::setCurrentAppName(appname);
}

int QuickTestResult::exitCode()
{
#if defined(QTEST_NOEXITCODE)
    return 0;
#else
    // make sure our exit code is never going above 127
    // since that could wrap and indicate 0 test fails
    return qMin(QTestLog::failCount(), 127);
#endif
}

QT_END_NAMESPACE

#include "quicktestresult.moc"
#include "moc_quicktestresult_p.cpp"
