/****************************************************************************
**
** 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: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 <QtGui/QOpenGLFunctions>
#include <QtGui/QScreen>
#include <QtGui/QWindow>
#include <private/qguiapplication_p.h>
#include <qpa/qplatformintegration.h>
#include <qpa/qplatformnativeinterface.h>
#include <private/qopengl_p.h>

#include <QtTest/QtTest>

#include <QtCore/QSysInfo>
#include <QtCore/QLibraryInfo>
#include <QtCore/QScopedPointer>
#include <QtCore/QVariant>
#include <QtCore/QDebug>
#include <QtCore/QTextStream>
#include <QtCore/QJsonDocument>

#include <algorithm>

#define DUMP_CAPABILITY(str, integration, capability) \
    if (platformIntegration->hasCapability(QPlatformIntegration::capability)) \
        str << ' ' << #capability;

QTextStream &operator<<(QTextStream &str, const QSize &s)
{
    str << s.width() << 'x' << s.height();
    return str;
}

QTextStream &operator<<(QTextStream &str, const QRect &r)
{
    str << r.size() << '+' << r.x() << '+' << r.y();
    return str;
}

QTextStream &operator<<(QTextStream &str, const QSizeF &s)
{
    str << s.width() << 'x' << s.height();
    return str;
}

QTextStream &operator<<(QTextStream &str, const QSurfaceFormat &format)
{
    str << "Version: " << format.majorVersion() << '.'
        << format.minorVersion() << " Profile: " << format.profile()
        << " Swap behavior: " << format.swapBehavior()
        << " Buffer size (RGB";
    if (format.hasAlpha())
        str << 'A';
    str << "): " << format.redBufferSize() << ',' << format.greenBufferSize()
        << ',' << format.blueBufferSize();
    if (format.hasAlpha())
        str << ',' << format.alphaBufferSize();
    if (const int dbs = format.depthBufferSize())
        str << " Depth buffer: " << dbs;
    if (const int sbs = format.stencilBufferSize())
        str << " Stencil buffer: " << sbs;
    const int samples = format.samples();
    if (samples > 0)
        str << " Samples: " << samples;
    return str;
}

/* This test contains code from the qtdiag tool. Its purpose is to output the
 * graphics configuration to the CI log and to verify that Open GL can be
 * initialized for platforms on which the qopengl test is marked as
 * insignificant. */

class tst_QOpenGlConfig : public QObject
{
    Q_OBJECT

private slots:
    void initTestCase();
    void testConfiguration();
    void testGlConfiguration();
    void testBugList();
    void testDefaultWindowsBlacklist();
};

static void dumpConfiguration(QTextStream &str)
{
    const QPlatformIntegration *platformIntegration = QGuiApplicationPrivate::platformIntegration();
    str << "\nBuild        : " << QLibraryInfo::build()
        << "\nPlatform     : " << QGuiApplication::platformName()
        << "\nOS           : " << QSysInfo::prettyProductName() << " ["
        << QSysInfo::kernelType() << " version " << QSysInfo::kernelVersion() << ']'
        << "\nArchitecture : " << QSysInfo::currentCpuArchitecture()
        << "\nCapabilities :";
    DUMP_CAPABILITY(str, platformIntegration, ThreadedPixmaps)
    DUMP_CAPABILITY(str, platformIntegration, OpenGL)
    DUMP_CAPABILITY(str, platformIntegration, ThreadedOpenGL)
    DUMP_CAPABILITY(str, platformIntegration, SharedGraphicsCache)
    DUMP_CAPABILITY(str, platformIntegration, BufferQueueingOpenGL)
    DUMP_CAPABILITY(str, platformIntegration, WindowMasks)
    DUMP_CAPABILITY(str, platformIntegration, RasterGLSurface)
    DUMP_CAPABILITY(str, platformIntegration, AllGLFunctionsQueryable)
    str << '\n';

    const QList<QScreen*> screens = QGuiApplication::screens();
    const int screenCount = screens.size();
    str << "\nScreens: " << screenCount << '\n';
    for (int s = 0; s < screenCount; ++s) {
        const QScreen *screen = screens.at(s);
        str << '#' << ' ' << s << " \"" << screen->name() << '"'
                  << " Depth: " << screen->depth()
                  << " Primary: " <<  (screen == QGuiApplication::primaryScreen() ? "yes" : "no")
            << "\n  Geometry: " << screen->geometry() << " Available: " << screen->availableGeometry();
        if (screen->geometry() != screen->virtualGeometry())
            str << "\n  Virtual geometry: " << screen->virtualGeometry() << " Available: " << screen->availableVirtualGeometry();
        if (screen->virtualSiblings().size() > 1)
            str << "\n  " << screen->virtualSiblings().size() << " virtual siblings";
        str << "\n  Physical size: " << screen->physicalSize() << " mm"
                  << "  Refresh: " << screen->refreshRate() << " Hz"
            << "\n  Physical DPI: " << screen->physicalDotsPerInchX()
            << ',' << screen->physicalDotsPerInchY()
            << " Logical DPI: " << screen->logicalDotsPerInchX()
            << ',' << screen->logicalDotsPerInchY()
            << "\n  DevicePixelRatio: " << screen->devicePixelRatio()
            << " Primary orientation: " << screen->primaryOrientation()
            << "\n  Orientation: " << screen->orientation()
            << " Native orientation: " << screen->nativeOrientation()
            << " OrientationUpdateMask: " << screen->orientationUpdateMask() << '\n';
    }

    // On Windows, this will provide addition GPU info similar to the output of dxdiag.
    if (QGuiApplication::platformNativeInterface()) {
        const QVariant gpuInfoV = QGuiApplication::platformNativeInterface()->property("gpu");
        if (gpuInfoV.type() == QVariant::Map) {
            const QString description = gpuInfoV.toMap().value(QStringLiteral("printable")).toString();
            if (!description.isEmpty())
                str << "\nGPU:\n" << description << "\n\n";
        }
    }
}

void tst_QOpenGlConfig::initTestCase()
{
    if (!QGuiApplicationPrivate::platformIntegration()->hasCapability(QPlatformIntegration::OpenGL))
        QSKIP("OpenGL is not supported on this platform.");
}

void tst_QOpenGlConfig::testConfiguration()
{
    QString result;
    QTextStream str(&result);
    dumpConfiguration(str);

    qDebug().noquote() << '\n' << result;
}

static void dumpGlConfiguration(QOpenGLContext &context, QTextStream &str)
{
    str << "Type             : ";
#ifdef QT_OPENGL_DYNAMIC
    str << "Dynamic GL ";
#endif
    switch (context.openGLModuleType()) {
    case QOpenGLContext::LibGL:
        str << "LibGL";
        break;
    case QOpenGLContext::LibGLES:
        str << "LibGLES";
        break;
    }
    QOpenGLFunctions functions(&context);

    str << "\nVendor           : " << reinterpret_cast<const char *>(functions.glGetString(GL_VENDOR))
        << "\nRenderer         : " << reinterpret_cast<const char *>(functions.glGetString(GL_RENDERER))
        << "\nVersion          : " << reinterpret_cast<const char *>(functions.glGetString(GL_VERSION))
        << "\nShading language : " << reinterpret_cast<const char *>(functions.glGetString(GL_SHADING_LANGUAGE_VERSION))
        << "\nFormat           : " << context.format();

    QList<QByteArray> extensionList = context.extensions().values();
    std::sort(extensionList.begin(), extensionList.end());
    const int extensionCount = extensionList.size();
    str << "\n\nFound " << extensionCount << " extensions:\n";
    for (int e = 0; e < extensionCount; ++e)
        str << ((e % 4) ? ' ' : '\n') << extensionList.at(e);
}

void tst_QOpenGlConfig::testGlConfiguration()
{
    QString result;
    QTextStream str(&result);

    QWindow window;
    window.setSurfaceType(QSurface::OpenGLSurface);
    window.create();
    QOpenGLContext context;
    QVERIFY(context.create());
    QVERIFY(context.makeCurrent(&window));
    dumpGlConfiguration(context, str);
    context.doneCurrent();

    qDebug().noquote() << '\n' << result;

    // fromContext either uses the current context or creates a temporary dummy one.
    QOpenGLConfig::Gpu gpu = QOpenGLConfig::Gpu::fromContext();
    qDebug().noquote() << '\n' << "GL_VENDOR queried by QOpenGLConfig::Gpu:" << gpu.glVendor;
    QVERIFY(!gpu.glVendor.isEmpty());
}

static inline QByteArray msgSetMismatch(const QSet<QString> &expected,
                                        const QSet<QString> &actual)
{
    const QString result = QStringList(expected.values()).join(QLatin1Char(','))
        + QLatin1String(" != ")
        + QStringList(actual.values()).join(QLatin1Char(','));
    return result.toLatin1();
}

void tst_QOpenGlConfig::testBugList()
{
    // Check bug list parsing for some arbitrary NVidia card
    // faking Windows OS.
    const QString fileName = QFINDTESTDATA("buglist.json");
    QVERIFY(!fileName.isEmpty());

    QSet<QString> expectedFeatures;
    expectedFeatures << "feature1";

    // adapter info
    QVersionNumber driverVersion(QVector<int>() << 9 << 18 << 13 << 4460);
    QOpenGLConfig::Gpu gpu = QOpenGLConfig::Gpu::fromDevice(0x10DE, 0x0DE9, driverVersion, QByteArrayLiteral("Unknown"));

    QSet<QString> actualFeatures = QOpenGLConfig::gpuFeatures(gpu, QStringLiteral("win"),
                                                              QVersionNumber(6, 3), QStringLiteral("7"), fileName);
    QVERIFY2(expectedFeatures == actualFeatures,
             msgSetMismatch(expectedFeatures, actualFeatures));

    // driver_description
    gpu = QOpenGLConfig::Gpu::fromDevice(0xDEAD, 0xBEEF, driverVersion, QByteArrayLiteral("Very Long And Special Driver Description"));
    actualFeatures = QOpenGLConfig::gpuFeatures(gpu, QStringLiteral("win"),
                                                QVersionNumber(6, 3), QStringLiteral("8"), fileName);
    expectedFeatures = QSet<QString>() << "feature2";
    QVERIFY2(expectedFeatures == actualFeatures,
             msgSetMismatch(expectedFeatures, actualFeatures));

    // os.release
    gpu = QOpenGLConfig::Gpu::fromDevice(0xDEAD, 0xBEEF, driverVersion, QByteArrayLiteral("WinVerTest"));
    actualFeatures = QOpenGLConfig::gpuFeatures(gpu, QStringLiteral("win"),
                                                QVersionNumber(12, 34), QStringLiteral("10"), fileName);
    expectedFeatures = QSet<QString>() << "win10_feature";
    QVERIFY2(expectedFeatures == actualFeatures,
             msgSetMismatch(expectedFeatures, actualFeatures));

    // gl_vendor
    gpu = QOpenGLConfig::Gpu::fromGLVendor(QByteArrayLiteral("Somebody Else"));
    expectedFeatures.clear();
    actualFeatures = QOpenGLConfig::gpuFeatures(gpu, QStringLiteral("linux"),
                                                QVersionNumber(1, 0), QString(), fileName);
    QVERIFY2(expectedFeatures == actualFeatures,
             msgSetMismatch(expectedFeatures, actualFeatures));

    gpu = QOpenGLConfig::Gpu::fromGLVendor(QByteArrayLiteral("The Qt Company"));
    expectedFeatures = QSet<QString>() << "cool_feature";
    actualFeatures = QOpenGLConfig::gpuFeatures(gpu, QStringLiteral("linux"),
                                                QVersionNumber(1, 0), QString(), fileName);
    QVERIFY2(expectedFeatures == actualFeatures,
             msgSetMismatch(expectedFeatures, actualFeatures));
}

void tst_QOpenGlConfig::testDefaultWindowsBlacklist()
{
    if (QGuiApplication::platformName().compare(QLatin1String("windows"), Qt::CaseInsensitive))
        QSKIP("Only applicable to Windows");

    QFile f(QStringLiteral(":/qt-project.org/windows/openglblacklists/default.json"));
    QVERIFY(f.open(QIODevice::ReadOnly | QIODevice::Text));
    QJsonParseError err;
    QJsonDocument doc = QJsonDocument::fromJson(f.readAll(), &err);
    QVERIFY2(err.error == 0,
             QStringLiteral("Failed to parse built-in Windows GPU blacklist. %1 : %2")
             .arg(err.offset).arg(err.errorString()).toLatin1());
}

QTEST_MAIN(tst_QOpenGlConfig)

#include "tst_qopenglconfig.moc"
