/***************************************************************************
**
** Copyright (C) 2013 Klaralvdalens Datakonsult AB (KDAB)
** Contact: https://www.qt.io/licensing/
**
** This file is part of the utilities 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 "codegenerator.h"

#include <QDebug>
#include <QFile>
#include <QSettings>
#include <QTextStream>

static const QString extensionRegistryFileName = QStringLiteral("qopengl-extension-registry.ini");
static const QString extensionIdGroupName = QStringLiteral("ExtensionIds");

CodeGenerator::CodeGenerator()
    : m_parser(0)
{
}

void CodeGenerator::generateCoreClasses(const QString &baseFileName) const
{
    // Output header and implementation files for the backend and base class
    writeCoreHelperClasses(baseFileName + QStringLiteral(".h"), Declaration);
    writeCoreHelperClasses(baseFileName + QStringLiteral(".cpp"), Definition);

    // Output the per-version and profile public classes
    writeCoreClasses(baseFileName);

    // We also need to generate a factory class that can be used by
    // QOpenGLContext to actually create version function objects
    writeCoreFactoryHeader(baseFileName + QStringLiteral("factory_p.h"));
    writeCoreFactoryImplementation(baseFileName + QStringLiteral("factory.cpp"));
}

void CodeGenerator::generateExtensionClasses(const QString &baseFileName) const
{
    writeExtensionHeader(baseFileName + QStringLiteral(".h"));
    writeExtensionImplementation(baseFileName + QStringLiteral(".cpp"));
}

bool CodeGenerator::isLegacyVersion(Version v) const
{
    return (v.major < 3 || (v.major == 3 && v.minor == 0));
}

bool CodeGenerator::versionHasProfiles(Version v) const
{
    VersionProfile vp;
    vp.version = v;
    return vp.hasProfiles();
}

void CodeGenerator::writeCoreHelperClasses(const QString &fileName, ClassComponent component) const
{
    if (!m_parser)
        return;

    QFile file(fileName);
    if (!file.open(QIODevice::WriteOnly | QIODevice::Text))
        return;
    QTextStream stream(&file);

    // Write the preamble
    writePreamble(fileName, stream);

    // Iterate over each OpenGL version. For each version output a private class for
    // core functions and a private class for deprecated functions.
    const QString privateRootClass = QStringLiteral("QOpenGLVersionFunctionsBackend");
    Q_FOREACH (const VersionProfile &versionProfile, m_parser->versionProfiles()) {
        switch (component) {
        case Declaration:
            writeBackendClassDeclaration(stream, versionProfile, privateRootClass);
            break;

        case Definition:
            writeBackendClassImplementation(stream, versionProfile, privateRootClass);
            break;
        }
    }

    // Write the postamble
    writePostamble(fileName, stream);
}

void CodeGenerator::writeCoreClasses(const QString &baseFileName) const
{
    // Iterate over each OpenGL version. For each version output a public class (for legacy
    // versions or two public classes (for modern versions with profiles). Each public class
    // is given pointers to private classes containing the actual entry points. For example,
    // the class for OpenGL 1.1 will have pointers to the private classes for 1.0 core, 1.1
    // core, 1.0 deprecated and 1.1 deprecated. Whereas the class for OpenGL 3.2 Core profile
    // will have pointers to the private classes for 1.0 core, 1.1 core, ..., 3.2 core but
    // not to any of the deprecated private classes
    QList<ClassComponent> components = (QList<ClassComponent>() << Declaration << Definition);
    Q_FOREACH (const ClassComponent &component, components) {
        const QString rootClass = QStringLiteral("QAbstractOpenGLFunctions");
        Q_FOREACH (const Version &classVersion, m_parser->versions()) {
            VersionProfile v;
            v.version = classVersion;
            v.profile = VersionProfile::CompatibilityProfile;

            if (isLegacyVersion(classVersion)) {
                switch (component) {
                case Declaration:
                    writePublicClassDeclaration(baseFileName, v, rootClass);
                    break;

                case Definition:
                    writePublicClassImplementation(baseFileName, v, rootClass);
                    break;
                }
            } else {
                switch (component) {
                case Declaration:
                    writePublicClassDeclaration(baseFileName, v, rootClass);
                    v.profile = VersionProfile::CoreProfile;
                    writePublicClassDeclaration(baseFileName, v, rootClass);
                    break;

                case Definition:
                    writePublicClassImplementation(baseFileName, v, rootClass);
                    v.profile = VersionProfile::CoreProfile;
                    writePublicClassImplementation(baseFileName, v, rootClass);
                    break;
                }
            }
        }
    }
}

void CodeGenerator::writeCoreFactoryHeader(const QString &fileName) const
{
    if (!m_parser)
        return;

    QFile file(fileName);
    if (!file.open(QIODevice::WriteOnly | QIODevice::Text))
        return;
    QTextStream stream(&file);

    // Write the preamble
    writePreamble(fileName, stream);

    // Write the postamble
    writePostamble(fileName, stream);
}

void CodeGenerator::writeCoreFactoryImplementation(const QString &fileName) const
{
    if (!m_parser)
        return;

    QFile file(fileName);
    if (!file.open(QIODevice::WriteOnly | QIODevice::Text))
        return;
    QTextStream stream(&file);

    // Write the preamble
    writePreamble(fileName, stream);

    // Get the set of version functions classes we need to create
    QList<Version> versions = m_parser->versions();
    std::sort(versions.begin(), versions.end(), std::greater<Version>());

    // Outout the #include statements
    stream << QStringLiteral("#if !defined(QT_OPENGL_ES_2)") << endl;
    Q_FOREACH (const Version &classVersion, versions) {
        if (!versionHasProfiles(classVersion)) {
            stream << QString(QStringLiteral("#include \"qopenglfunctions_%1_%2.h\""))
                      .arg(classVersion.major)
                      .arg(classVersion.minor) << endl;
        } else {
            const QList<VersionProfile::OpenGLProfile> profiles = (QList<VersionProfile::OpenGLProfile>()
                << VersionProfile::CoreProfile << VersionProfile::CompatibilityProfile);

            Q_FOREACH (const VersionProfile::OpenGLProfile profile, profiles) {
                const QString profileSuffix = profile == VersionProfile::CoreProfile
                                            ? QStringLiteral("core")
                                            : QStringLiteral("compatibility");
                stream << QString(QStringLiteral("#include \"qopenglfunctions_%1_%2_%3.h\""))
                          .arg(classVersion.major)
                          .arg(classVersion.minor)
                          .arg(profileSuffix) << endl;
            }
        }
    }
    stream << QStringLiteral("#else") << endl;
    stream << QStringLiteral("#include \"qopenglfunctions_es2.h\"") << endl;
    stream << QStringLiteral("#endif") << endl;

    stream << endl;

    stream << QStringLiteral("QT_BEGIN_NAMESPACE") << endl << endl;
    stream << QStringLiteral("QAbstractOpenGLFunctions *QOpenGLVersionFunctionsFactory::create(const QOpenGLVersionProfile &versionProfile)") << endl;
    stream << QStringLiteral("{") << endl;
    stream << QStringLiteral("#if !defined(QT_OPENGL_ES_2)") << endl;
    stream << QStringLiteral("    const int major = versionProfile.version().first;") << endl;
    stream << QStringLiteral("    const int minor = versionProfile.version().second;") << endl << endl;

    // Iterate over classes with profiles
    stream << QStringLiteral("    if (versionProfile.hasProfiles()) {") << endl;
    stream << QStringLiteral("        switch (versionProfile.profile()) {") << endl;
    const QList<VersionProfile::OpenGLProfile> profiles = (QList<VersionProfile::OpenGLProfile>()
        << VersionProfile::CoreProfile << VersionProfile::CompatibilityProfile);
    Q_FOREACH (const VersionProfile::OpenGLProfile profile, profiles) {
        const QString caseLabel = profile == VersionProfile::CoreProfile
                                ? QStringLiteral("QSurfaceFormat::CoreProfile")
                                : QStringLiteral("QSurfaceFormat::CompatibilityProfile");
        stream << QString(QStringLiteral("        case %1:")).arg(caseLabel) << endl;

        int i = 0;
        Q_FOREACH (const Version &classVersion, versions) {
            if (!versionHasProfiles(classVersion))
                continue;

            const QString ifString = (i++ == 0) ? QStringLiteral("if") : QStringLiteral("else if");
            stream << QString(QStringLiteral("            %1 (major == %2 && minor == %3)"))
                      .arg(ifString)
                      .arg(classVersion.major)
                      .arg(classVersion.minor) << endl;

            VersionProfile v;
            v.version = classVersion;
            v.profile = profile;
            stream << QString(QStringLiteral("                return new %1;"))
                      .arg(generateClassName(v)) << endl;
        }

        stream << QStringLiteral("            break;") << endl << endl;
    }

    stream << QStringLiteral("        case QSurfaceFormat::NoProfile:") << endl;
    stream << QStringLiteral("        default:") << endl;
    stream << QStringLiteral("            break;") << endl;
    stream << QStringLiteral("        };") << endl;
    stream << QStringLiteral("    } else {") << endl;

    // Iterate over the legacy classes (no profiles)
    int i = 0;
    Q_FOREACH (const Version &classVersion, versions) {
        if (versionHasProfiles(classVersion))
            continue;

        const QString ifString = (i++ == 0) ? QStringLiteral("if") : QStringLiteral("else if");
        stream << QString(QStringLiteral("        %1 (major == %2 && minor == %3)"))
                  .arg(ifString)
                  .arg(classVersion.major)
                  .arg(classVersion.minor) << endl;

        VersionProfile v;
        v.version = classVersion;
        stream << QString(QStringLiteral("            return new %1;"))
                  .arg(generateClassName(v)) << endl;
    }

    stream << QStringLiteral("    }") << endl;
    stream << QStringLiteral("    return 0;") << endl;

    stream << QStringLiteral("#else") << endl;
    stream << QStringLiteral("    Q_UNUSED(versionProfile);") << endl;
    stream << QStringLiteral("    return new QOpenGLFunctions_ES2;") << endl;
    stream << QStringLiteral("#endif") << endl;
    stream << QStringLiteral("}") << endl;

    // Write the postamble
    writePostamble(fileName, stream);
}

/**
  \returns all functions to be included in the class defined by \a classVersionProfile
 */
FunctionCollection CodeGenerator::functionCollection( const VersionProfile& classVersionProfile ) const
{
    const Version classVersion = classVersionProfile.version;
    FunctionCollection functionSet;
    QList<Version> versions = m_parser->versions();

    // Populate these based upon the class version and profile
    Version minVersion;
    minVersion.major = 1;
    minVersion.minor = 0;
    Version maxVersion = classVersion;
    QList<VersionProfile::OpenGLProfile> profiles;
    profiles << VersionProfile::CoreProfile; // Always need core functions

    if (isLegacyVersion(classVersion)
        || (classVersionProfile.hasProfiles()
         && classVersionProfile.profile == VersionProfile::CompatibilityProfile)) {
        // For versions < 3.1 and Compatibility profile we include both core and deprecated functions
        profiles << VersionProfile::CompatibilityProfile;
    }

    Q_FOREACH (const Version &v, versions) {
        // Only include functions from versions in the range
        if (v < minVersion)
            continue;
        if (v > maxVersion)
            break;

        Q_FOREACH (VersionProfile::OpenGLProfile profile, profiles) {
            // Combine version and profile for this subset of functions
            VersionProfile version;
            version.version = v;
            version.profile = profile;

            // Fetch the functions and add to collection for this class
            QList<Function> functions = m_parser->functionsForVersion(version);
            functionSet.insert(version, functions);
        }
    }

    return functionSet;
}

void CodeGenerator::writePreamble(const QString &baseFileName, QTextStream &stream, const QString replacement) const
{
    const QString fileName = baseFileName + QStringLiteral(".header");
    if (!QFile::exists(fileName))
        return;

    QFile file(fileName);
    if (file.open(QIODevice::ReadOnly | QIODevice::Text)) {
        QTextStream preambleStream(&file);
        QString preamble = preambleStream.readAll();
        if (!replacement.isEmpty())
            preamble.replace(QStringLiteral("__VERSION__"), replacement, Qt::CaseSensitive);
        stream << preamble;
    }
}

void CodeGenerator::writePostamble(const QString &baseFileName, QTextStream &stream) const
{
    const QString fileName = baseFileName + QStringLiteral(".footer");
    if (!QFile::exists(fileName))
        return;

    QFile file(fileName);
    if (file.open(QIODevice::ReadOnly | QIODevice::Text)) {
        QTextStream postambleStream(&file);
        QString postamble = postambleStream.readAll();
        stream << postamble;
    }
}

QString CodeGenerator::passByType(const Argument &arg) const
{
    QString passBy;
    switch (arg.mode) {
    case Argument::Reference:
    case Argument::Array:
        passBy = QStringLiteral("*");
        break;

    default:
    case Argument::Value:
        passBy = QString();
    }
    return passBy;
}

QString CodeGenerator::safeArgumentName(const QString& arg) const
{
    if (arg == QLatin1String("near")) // MS Windows defines near and far
        return QStringLiteral("nearVal");
    else if (arg == QLatin1String("far"))
        return QStringLiteral("farVal");
    else if (arg == QLatin1String("d"))
        return QStringLiteral("dd"); // Don't shadow d pointer
    else
        return arg;
}

QString CodeGenerator::generateClassName(const VersionProfile &classVersion, ClassVisibility visibility) const
{
    QString className;
    switch ( visibility ) {
    case Public: {
        // Class name and base class
        QString profileSuffix;
        if (classVersion.hasProfiles())
            profileSuffix = (classVersion.profile == VersionProfile::CoreProfile ? QStringLiteral("_Core") : QStringLiteral("_Compatibility"));

        className = QString(QStringLiteral("QOpenGLFunctions_%1_%2%3"))
                    .arg(classVersion.version.major)
                    .arg(classVersion.version.minor)
                    .arg(profileSuffix);
        break;
    }
    case Private: {
        QString statusSuffix = (classVersion.profile == VersionProfile::CoreProfile ? QStringLiteral("_Core") : QStringLiteral("_Deprecated"));

        className = QString(QStringLiteral("QOpenGLFunctions_%1_%2%3Private"))
                    .arg(classVersion.version.major)
                    .arg(classVersion.version.minor)
                    .arg(statusSuffix);
        break;
        }
    }

    return className;
}

void CodeGenerator::writeBackendClassDeclaration(QTextStream &stream,
                                                 const VersionProfile &versionProfile,
                                                 const QString &baseClass) const
{
    const QString className = backendClassName(versionProfile);
    stream << QString(QStringLiteral("class %1 : public %2"))
              .arg(className)
              .arg(baseClass)
           << endl;
    stream << QStringLiteral("{") << endl;
    stream << QStringLiteral("public:") << endl;
    stream << QString( QStringLiteral("    %1(QOpenGLContext *context);") ).arg(className) << endl << endl;

    // Output function used for generating key used in QOpenGLContextPrivate
    stream << QStringLiteral("    static QOpenGLVersionStatus versionStatus();") << endl << endl;

    // Get the functions needed for this class
    FunctionList functions = m_parser->functionsForVersion(versionProfile);
    FunctionCollection functionSet;
    functionSet.insert(versionProfile, functions);

    // Declare the functions
    writeClassFunctionDeclarations(stream, functionSet, Private);

    stream << QStringLiteral("};") << endl;
    stream << endl;
}

void CodeGenerator::writeBackendClassImplementation(QTextStream &stream,
                                                    const VersionProfile &versionProfile,
                                                    const QString &baseClass) const
{
    const QString className = backendClassName(versionProfile);
    stream << QString(QStringLiteral("%1::%1(QOpenGLContext *context)")).arg(className) << endl;
    stream << QString(QStringLiteral("    : %1(context)")).arg(baseClass) << endl
           << QStringLiteral("{") << endl;

    // Resolve the entry points for this set of functions
    // Get the functions needed for this class
    FunctionList functions = m_parser->functionsForVersion(versionProfile);
    FunctionCollection functionSet;
    functionSet.insert(versionProfile, functions);
    writeEntryPointResolutionCode(stream, functionSet);

    stream << QStringLiteral("}") << endl << endl;

    stream << QString(QStringLiteral("QOpenGLVersionStatus %1::versionStatus()")).arg(className) << endl;
    stream << QStringLiteral("{") << endl;
    const QString status = versionProfile.profile == VersionProfile::CoreProfile
                         ? QStringLiteral("QOpenGLVersionStatus::CoreStatus")
                         : QStringLiteral("QOpenGLVersionStatus::DeprecatedStatus");
    stream << QString(QStringLiteral("    return QOpenGLVersionStatus(%1, %2, %3);"))
              .arg(versionProfile.version.major)
              .arg(versionProfile.version.minor)
              .arg(status) << endl;
    stream << QStringLiteral("}") << endl << endl;
}

QString CodeGenerator::coreClassFileName(const VersionProfile &versionProfile,
                                         const QString& fileExtension) const
{
    QString profileSuffix;
    if (versionProfile.hasProfiles())
        profileSuffix = (versionProfile.profile == VersionProfile::CoreProfile ? QStringLiteral("_core") : QStringLiteral("_compatibility"));

    const QString fileName = QString(QStringLiteral("qopenglfunctions_%1_%2%3.%4"))
                             .arg(versionProfile.version.major)
                             .arg(versionProfile.version.minor)
                             .arg(profileSuffix)
                             .arg(fileExtension);
    return fileName;
}

void CodeGenerator::writePublicClassDeclaration(const QString &baseFileName,
                                                const VersionProfile &versionProfile,
                                                const QString &baseClass) const
{
    const QString fileName = coreClassFileName(versionProfile, QStringLiteral("h"));
    QFile file(fileName);
    if (!file.open(QIODevice::WriteOnly | QIODevice::Text))
        return;
    QTextStream stream(&file);

    // Write the preamble
    const QString templateFileName = QString(QStringLiteral("%1__VERSION__.h"))
                                     .arg(baseFileName);
    QString profileSuffix;
    if (versionProfile.hasProfiles())
        profileSuffix = (versionProfile.profile == VersionProfile::CoreProfile ? QStringLiteral("_CORE") : QStringLiteral("_COMPATIBILITY"));

    const QString versionProfileString = QString(QStringLiteral("_%1_%2%3"))
                                         .arg(versionProfile.version.major)
                                         .arg(versionProfile.version.minor)
                                         .arg(profileSuffix);
    writePreamble(templateFileName, stream, versionProfileString);

    // Ctor, dtor, and initialize function;
    const QString className = generateClassName(versionProfile, Public);
    stream << QString(QStringLiteral("class Q_GUI_EXPORT %1 : public %2"))
              .arg(className)
              .arg(baseClass)
           << endl;
    stream << QStringLiteral("{") << endl;
    stream << QStringLiteral("public:") << endl;
    stream << QString(QStringLiteral("    %1();")).arg(className) << endl;
    stream << QString(QStringLiteral("    ~%1();")).arg(className) << endl << endl;
    stream << QStringLiteral("    bool initializeOpenGLFunctions() override;") << endl << endl;

    // Get the functions needed for this class and declare them
    FunctionCollection functionSet = functionCollection(versionProfile);
    writeClassFunctionDeclarations(stream, functionSet, Public);

    // isCompatible function and backend variables
    stream << QStringLiteral("private:") << endl;
    stream << QStringLiteral("    friend class QOpenGLContext;") << endl << endl;
    stream << QStringLiteral("    static bool isContextCompatible(QOpenGLContext *context);") << endl;
    stream << QStringLiteral("    static QOpenGLVersionProfile versionProfile();") << endl << endl;
    writeBackendVariableDeclarations(stream, backendsForFunctionCollection(functionSet));

    stream << QStringLiteral("};") << endl << endl;

    // Output the inline functions that forward OpenGL calls to the backends' entry points
    writeClassInlineFunctions(stream, className, functionSet);

    // Write the postamble
    writePostamble(templateFileName, stream);
}

void CodeGenerator::writePublicClassImplementation(const QString &baseFileName,
                                                   const VersionProfile &versionProfile,
                                                   const QString& baseClass) const
{
    const QString fileName = coreClassFileName(versionProfile, QStringLiteral("cpp"));
    QFile file(fileName);
    if (!file.open(QIODevice::WriteOnly | QIODevice::Text))
        return;
    QTextStream stream(&file);

    // Write the preamble
    const QString templateFileName = QString(QStringLiteral("%1__VERSION__.cpp"))
                                     .arg(baseFileName);
    QString profileSuffix;
    if (versionProfile.hasProfiles())
        profileSuffix = (versionProfile.profile == VersionProfile::CoreProfile ? QStringLiteral("_core") : QStringLiteral("_compatibility"));

    const QString versionProfileString = QString(QStringLiteral("_%1_%2%3"))
                                         .arg(versionProfile.version.major)
                                         .arg(versionProfile.version.minor)
                                         .arg(profileSuffix);
    writePreamble(templateFileName, stream, versionProfileString);

    const QString className = generateClassName(versionProfile, Public);
    stream << QStringLiteral("/*!") << endl
           << QStringLiteral("    \\class ") << className << endl
           << QStringLiteral("    \\inmodule QtGui") << endl
           << QStringLiteral("    \\since 5.1") << endl
           << QStringLiteral("    \\wrapper") << endl
           << QStringLiteral("    \\brief The ") << className
           << QString(QStringLiteral(" class provides all functions for OpenGL %1.%2 "))
                .arg(versionProfile.version.major)
                .arg(versionProfile.version.minor);

    if (!profileSuffix.isEmpty()) {
        profileSuffix.remove(0, 1);
        profileSuffix.append(QStringLiteral(" profile"));
    } else {
        profileSuffix = "specification";
    }

    stream << profileSuffix << QStringLiteral(".") << endl << endl
           << QStringLiteral("    This class is a wrapper for functions from ")
           << QString(QStringLiteral("OpenGL %1.%2 "))
                .arg(versionProfile.version.major)
                .arg(versionProfile.version.minor)
           << profileSuffix << QStringLiteral(".") << endl
           << QStringLiteral("    See reference pages on \\l {http://www.opengl.org/sdk/docs/}{opengl.org}") << endl
           << QStringLiteral("    for function documentation.") << endl << endl
           << QStringLiteral("    \\sa QAbstractOpenGLFunctions") << endl
           << QStringLiteral("*/") << endl << endl;

    // Get the data we'll need for this class implementation
    FunctionCollection functionSet = functionCollection(versionProfile);
    QList<VersionProfile> backends = backendsForFunctionCollection(functionSet);

    // Output default constructor
    stream << className << QStringLiteral("::") << className << QStringLiteral("()") << endl;
    stream << QStringLiteral(" : ") << baseClass << QStringLiteral("()");
    Q_FOREACH (const VersionProfile &v, backends)
        stream << endl << QString(QStringLiteral(" , %1(0)")).arg(backendVariableName(v));
    stream << endl << QStringLiteral("{") << endl << QStringLiteral("}") << endl << endl;

    // Output the destructor
    stream << className << QStringLiteral("::~") << className << QStringLiteral("()") << endl;
    stream << QStringLiteral("{") << endl;
    Q_FOREACH (const VersionProfile &v, backends) {
        const QString backendVar = backendVariableName(v);
        const QString backendClass = backendClassName(v);
        stream << QString(QStringLiteral("    if (%1 && !%1->refs.deref()) {")).arg(backendVar) << endl;
        stream << QString(QStringLiteral("        QAbstractOpenGLFunctionsPrivate::removeFunctionsBackend(%1->context, %2::versionStatus());"))
                  .arg(backendVar)
                  .arg(backendClass) << endl;
        stream << QString(QStringLiteral("        delete %1;")).arg(backendVar) << endl;
        stream << QStringLiteral("    }") << endl;
    }
    stream << QStringLiteral("}") << endl << endl;

    // Output the initialize function that creates the backend objects
    stream << QString(QStringLiteral("bool %1::initializeOpenGLFunctions()")).arg(className) << endl;
    stream << QStringLiteral("{") << endl;

    stream << QStringLiteral("    if ( isInitialized() )") << endl;
    stream << QStringLiteral("        return true;") << endl << endl;
    stream << QStringLiteral("    QOpenGLContext* context = QOpenGLContext::currentContext();") << endl << endl;
    stream << QStringLiteral("    // If owned by a context object make sure it is current.") << endl;
    stream << QStringLiteral("    // Also check that current context is capable of resolving all needed functions") << endl;
    stream << QStringLiteral("    if (((owningContext() && owningContext() == context) || !owningContext())") << endl;
    stream << QString(QStringLiteral("        && %1::isContextCompatible(context))")).arg(className) << endl;
    stream << QStringLiteral("    {") << endl;
    stream << QStringLiteral("        // Associate with private implementation, creating if necessary") << endl;
    stream << QStringLiteral("        // Function pointers in the backends are resolved at creation time") << endl;
    stream << QStringLiteral("        QOpenGLVersionFunctionsBackend* d = 0;") << endl;

    Q_FOREACH (const VersionProfile &v, backends) {
        const QString backendClass = backendClassName(v);
        const QString backendVar = backendVariableName(v);
        stream << QString(QStringLiteral("        d = QAbstractOpenGLFunctionsPrivate::functionsBackend(context, %1::versionStatus());"))
                  .arg(backendClass) << endl;
        stream << QStringLiteral("        if (!d) {") << endl;
        stream << QString(QStringLiteral("            d = new %1(context);")).arg(backendClass) << endl;
        stream << QString(QStringLiteral("            QAbstractOpenGLFunctionsPrivate::insertFunctionsBackend(context, %1::versionStatus(), d);"))
                  .arg(backendClass) << endl;
        stream << QStringLiteral("        }") << endl;
        stream << QString(QStringLiteral("        %1 = static_cast<%2*>(d);")).arg(backendVar).arg(backendClass) << endl;
        stream << QStringLiteral("        d->refs.ref();") << endl << endl;
    }

    stream << QStringLiteral("        QAbstractOpenGLFunctions::initializeOpenGLFunctions();") << endl;
    stream << QStringLiteral("    }") << endl;

    stream << QStringLiteral("    return isInitialized();") << endl;
    stream << QStringLiteral("}") << endl << endl;

    // Output the context compatibility check function
    stream << QString(QStringLiteral("bool %1::isContextCompatible(QOpenGLContext *context)")).arg(className) << endl;
    stream << QStringLiteral("{") << endl;
    stream << QStringLiteral("    Q_ASSERT(context);") << endl;
    stream << QStringLiteral("    QSurfaceFormat f = context->format();") << endl;
    stream << QStringLiteral("    const QPair<int, int> v = qMakePair(f.majorVersion(), f.minorVersion());") << endl;
    stream << QString(QStringLiteral("    if (v < qMakePair(%1, %2))"))
              .arg(versionProfile.version.major)
              .arg(versionProfile.version.minor) << endl;
    stream << QStringLiteral("        return false;") << endl << endl;

    // If generating a legacy or compatibility profile class we need to ensure that
    // the context does not expose only core functions
    if (versionProfile.profile != VersionProfile::CoreProfile) {
        stream << QStringLiteral("    if (f.profile() == QSurfaceFormat::CoreProfile)") << endl;
        stream << QStringLiteral("        return false;") << endl << endl;
    }

    stream << QStringLiteral("    return true;") << endl;
    stream << QStringLiteral("}") << endl << endl;

    // Output static function used as helper in template versionFunctions() function
    // in QOpenGLContext
    stream << QString(QStringLiteral("QOpenGLVersionProfile %1::versionProfile()")).arg(className) << endl;
    stream << QStringLiteral("{") << endl;
    stream << QStringLiteral("    QOpenGLVersionProfile v;") << endl;
    stream << QString(QStringLiteral("    v.setVersion(%1, %2);"))
              .arg(versionProfile.version.major)
              .arg(versionProfile.version.minor) << endl;
    if (versionProfile.hasProfiles()) {
        const QString profileName = versionProfile.profile == VersionProfile::CoreProfile
                                    ? QStringLiteral("QSurfaceFormat::CoreProfile")
                                    : QStringLiteral("QSurfaceFormat::CompatibilityProfile");
        stream << QString(QStringLiteral("    v.setProfile(%1);")).arg(profileName) << endl;
    }
    stream << QStringLiteral("    return v;") << endl;
    stream << QStringLiteral("}") << endl;

    // Write the postamble
    writePostamble(templateFileName, stream);
}

void CodeGenerator::writeClassFunctionDeclarations(QTextStream &stream,
                                                   const FunctionCollection &functionSet,
                                                   ClassVisibility visibility) const
{
    Q_FOREACH (const VersionProfile &version, functionSet.keys()) {
        // Add a comment to the header
        stream << QString(QStringLiteral("    // OpenGL %1.%2 %3 functions"))
                  .arg(version.version.major)
                  .arg(version.version.minor)
                  .arg((version.profile == VersionProfile::CoreProfile) ? QStringLiteral("core") : QStringLiteral("deprecated"))
               << endl;

        // Output function declarations
        FunctionList functions = functionSet.value(version);
        Q_FOREACH (const Function &f, functions)
            writeFunctionDeclaration(stream, f, visibility);
        stream << endl;
    } // version and profile
}

void CodeGenerator::writeFunctionDeclaration(QTextStream &stream, const Function &f, ClassVisibility visibility) const
{
    QStringList argList;
    Q_FOREACH (const Argument &arg, f.arguments) {
        QString a = QString(QStringLiteral("%1%2 %3%4"))
                    .arg((arg.direction == Argument::In && arg.mode != Argument::Value) ? QStringLiteral("const ") : QString())
                    .arg(arg.type)
                    .arg(passByType(arg))
                    .arg(safeArgumentName(arg.name));
        argList.append(a);
    }
    QString args = argList.join(QStringLiteral(", "));

    QString signature;
    switch (visibility) {
    case Public:
        signature = QString(QStringLiteral("    %1 gl%2(%3);")).arg(f.returnType).arg(f.name).arg(args);
        break;

    case Private:
    default:
        signature = QString(QStringLiteral("    %1 (QOPENGLF_APIENTRYP %2)(%3);")).arg(f.returnType).arg(f.name).arg(args);
    }
    stream << signature << endl;
}

void CodeGenerator::writeClassInlineFunctions(QTextStream &stream,
                                              const QString &className,
                                              const FunctionCollection &functionSet) const
{
    Q_FOREACH (const VersionProfile &version, functionSet.keys()) {

        // Add a comment to the header
        stream << QString(QStringLiteral("// OpenGL %1.%2 %3 functions"))
                  .arg(version.version.major)
                  .arg(version.version.minor)
                  .arg((version.profile == VersionProfile::CoreProfile) ? QStringLiteral("core") : QStringLiteral("deprecated"))
               << endl;

        // Output function declarations
        const QString backendVar = backendVariableName(version);
        FunctionList functions = functionSet.value(version);
        Q_FOREACH (const Function &f, functions)
            writeInlineFunction(stream, className, backendVar, f);

        stream << endl;

    } // version and profile
}

void CodeGenerator::writeInlineFunction(QTextStream &stream, const QString &className,
                                        const QString &backendVar, const Function &f) const
{
    QStringList argList;
    Q_FOREACH (const Argument &arg, f.arguments) {
        QString a = QString(QStringLiteral("%1%2 %3%4"))
                    .arg((arg.direction == Argument::In && arg.mode != Argument::Value) ? QStringLiteral("const ") : QString())
                    .arg(arg.type)
                    .arg(passByType(arg))
                    .arg(safeArgumentName(arg.name));
        argList.append(a);
    }
    QString args = argList.join(", ");


    QString signature = QString(QStringLiteral("inline %1 %2::gl%3(%4)"))
                        .arg(f.returnType)
                        .arg(className)
                        .arg(f.name)
                        .arg(args);
    stream << signature << endl << QStringLiteral("{") << endl;

    QStringList argumentNames;
    Q_FOREACH (const Argument &arg, f.arguments)
        argumentNames.append(safeArgumentName(arg.name));
    QString argNames = argumentNames.join(", ");

    if (f.returnType == QLatin1String("void"))
        stream << QString(QStringLiteral("    %1->%2(%3);")).arg(backendVar).arg(f.name).arg(argNames) << endl;
    else
        stream << QString(QStringLiteral("    return %1->%2(%3);")).arg(backendVar).arg(f.name).arg(argNames) << endl;
    stream << QStringLiteral("}") << endl << endl;
}

void CodeGenerator::writeEntryPointResolutionCode(QTextStream &stream,
                                                  const FunctionCollection &functionSet) const
{
    bool hasModuleHandle = false;
    Q_FOREACH (const VersionProfile &version, functionSet.keys()) {

        // Add a comment to the header
        stream << QString(QStringLiteral("    // OpenGL %1.%2 %3 functions"))
                  .arg(version.version.major)
                  .arg(version.version.minor)
                  .arg((version.profile == VersionProfile::CoreProfile) ? QStringLiteral("core") : QStringLiteral("deprecated"))
               << endl;

        // Output function declarations
        FunctionList functions = functionSet.value(version);

        bool useGetProcAddress = (version.version.major == 1 && (version.version.minor == 0 || version.version.minor == 1));
        if (useGetProcAddress) {
            stream << "#if defined(Q_OS_WIN)" << endl;
            if (!hasModuleHandle) {
                stream << "    HMODULE handle = GetModuleHandleA(\"opengl32.dll\");" << endl;
                hasModuleHandle = true;
            }

            Q_FOREACH (const Function &f, functions)
                writeEntryPointResolutionStatement(stream, f, QString(), useGetProcAddress);

            stream << "#else" << endl;
        }

        Q_FOREACH (const Function &f, functions)
            writeEntryPointResolutionStatement(stream, f);

        if (useGetProcAddress)
            stream << "#endif" << endl;

        stream << endl;

    } // version and profile
}

void CodeGenerator::writeEntryPointResolutionStatement(QTextStream &stream, const Function &f,
                                                       const QString &prefix, bool useGetProcAddress) const
{
    QStringList argList;
    Q_FOREACH (const Argument &arg, f.arguments) {
        QString a = QString("%1%2 %3")
                    .arg((arg.direction == Argument::In && arg.mode != Argument::Value) ? QStringLiteral("const ") : QString())
                    .arg(arg.type)
                    .arg(passByType(arg));
        argList.append(a);
    }
    QString args = argList.join(QStringLiteral(", "));

    QString signature;
    if (!useGetProcAddress) {
        signature = QString(QStringLiteral("    %4%3 = reinterpret_cast<%1 (QOPENGLF_APIENTRYP)(%2)>(context->getProcAddress(\"gl%3\"));"))
                    .arg(f.returnType)
                    .arg(args)
                    .arg(f.name)
                    .arg(prefix);
    } else {
        signature = QString(QStringLiteral("    %4%3 = reinterpret_cast<%1 (QOPENGLF_APIENTRYP)(%2)>(GetProcAddress(handle, \"gl%3\"));"))
                    .arg(f.returnType)
                    .arg(args)
                    .arg(f.name)
                    .arg(prefix);
    }
    stream << signature << endl;
}

QList<VersionProfile> CodeGenerator::backendsForFunctionCollection(const FunctionCollection &functionSet) const
{
    QList<VersionProfile> backends;
    Q_FOREACH (const VersionProfile &versionProfile, functionSet.keys()) {
        if (m_parser->versionProfiles().contains(versionProfile))
            backends.append(versionProfile);
    }
    return backends;
}

QString CodeGenerator::backendClassName(const VersionProfile &v) const
{
    QString statusSuffix = v.profile == VersionProfile::CoreProfile
                         ? QStringLiteral("_Core")
                         : QStringLiteral("_Deprecated");
    const QString className = QString(QStringLiteral("QOpenGLFunctions_%1_%2%3Backend"))
                              .arg(v.version.major)
                              .arg(v.version.minor)
                              .arg(statusSuffix);
    return className;
}

QString CodeGenerator::backendVariableName(const VersionProfile &v) const
{
    const QString status = (v.profile == VersionProfile::CoreProfile)
                         ? QStringLiteral("Core")
                         : QStringLiteral("Deprecated");
    const QString varName = QString(QStringLiteral("d_%1_%2_%3"))
                            .arg(v.version.major)
                            .arg(v.version.minor)
                            .arg(status);
    return varName;
}

void CodeGenerator::writeBackendVariableDeclarations(QTextStream &stream, const QList<VersionProfile> &backends) const
{
    // We need a private class for each version and profile (status: core or deprecated)
    Q_FOREACH (const VersionProfile &v, backends) {
        const QString className = backendClassName(v);
        const QString varName = backendVariableName(v);
        stream << QString(QStringLiteral("    %1* %2;")).arg(className).arg(varName) << endl;
    }
}

void CodeGenerator::writeExtensionHeader(const QString &fileName) const
{
    if (!m_parser)
        return;

    QFile file(fileName);
    if (!file.open(QIODevice::WriteOnly | QIODevice::Text))
        return;
    QTextStream stream(&file);

    // Write the preamble
    writePreamble(fileName, stream);

    // Iterate through the list of extensions and create one class per extension
    QStringList extensions = m_parser->extensions();
    Q_FOREACH (const QString &extension, extensions) {
        writeExtensionClassDeclaration(stream, extension, Private);
        writeExtensionClassDeclaration(stream, extension, Public);
    }

    // Write the postamble
    writePostamble(fileName, stream);
}

void CodeGenerator::writeExtensionImplementation(const QString &fileName) const
{
    if (!m_parser)
        return;

    QFile file(fileName);
    if (!file.open(QIODevice::WriteOnly | QIODevice::Text))
        return;
    QTextStream stream(&file);

    // Write the preamble
    writePreamble(fileName, stream);

    // Iterate through the list of extensions and create one class per extension
    QStringList extensions = m_parser->extensions();
    Q_FOREACH (const QString &extension, extensions)
        writeExtensionClassImplementation(stream, extension);

    // Write the postamble
    writePostamble(fileName, stream);
}

void CodeGenerator::writeExtensionClassDeclaration(QTextStream &stream, const QString &extension, ClassVisibility visibility) const
{
    const QString className = generateExtensionClassName(extension, visibility);

    QString baseClass = (visibility == Public) ? QStringLiteral("QAbstractOpenGLExtension") : QStringLiteral("QAbstractOpenGLExtensionPrivate");

    stream << QString(QStringLiteral("class %2 : public %3"))
              .arg(className)
              .arg(baseClass)
           << endl << "{" << endl << "public:" << endl;

    if (visibility == Public) {
        // Default constructor
        stream << QStringLiteral("    ") << className << QStringLiteral("();") << endl << endl;

        // Base class virtual function(s)
        QString resolveFunction = QStringLiteral("    bool initializeOpenGLFunctions() final;");
        stream << resolveFunction << endl << endl;
    }

    // Output the functions provided by this extension
    QList<Function> functions = m_parser->functionsForExtension(extension);
    Q_FOREACH (const Function &f, functions)
        writeFunctionDeclaration(stream, f, visibility);

    if (visibility == Public) {
        // Write out the protected ctor
        stream << endl << QStringLiteral("protected:") << endl;
        stream << QStringLiteral("    Q_DECLARE_PRIVATE(") << className << QStringLiteral(")") << endl;
    }

    // End the class declaration
    stream << QStringLiteral("};") << endl << endl;

    // Output the inline functions for public class
    if (visibility == Public) {
        Q_FOREACH (const Function &f, functions)
            writeExtensionInlineFunction(stream, className, f);
    }
}

void CodeGenerator::writeExtensionInlineFunction(QTextStream &stream, const QString &className, const Function &f) const
{
    QStringList argList;
    Q_FOREACH (const Argument &arg, f.arguments) {
        QString a = QString(QStringLiteral("%1%2 %3%4"))
                    .arg((arg.direction == Argument::In && arg.mode != Argument::Value) ? QStringLiteral("const ") : QString())
                    .arg(arg.type)
                    .arg(passByType(arg))
                    .arg(safeArgumentName(arg.name));
        argList.append(a);
    }
    QString args = argList.join(", ");


    QString signature = QString(QStringLiteral("inline %1 %2::gl%3(%4)"))
                        .arg(f.returnType)
                        .arg(className)
                        .arg(f.name)
                        .arg(args);
    stream << signature << endl << QStringLiteral("{") << endl;

    stream << QString(QStringLiteral("    Q_D(%1);")).arg(className) << endl;

    QStringList argumentNames;
    Q_FOREACH (const Argument &arg, f.arguments)
        argumentNames.append(safeArgumentName(arg.name));
    QString argNames = argumentNames.join(", ");

    if (f.returnType == QStringLiteral("void"))
        stream << QString(QStringLiteral("    d->%1(%2);")).arg(f.name).arg(argNames) << endl;
    else
        stream << QString(QStringLiteral("    return d->%1(%2);")).arg(f.name).arg(argNames) << endl;
    stream << QStringLiteral("}") << endl << endl;
}

void CodeGenerator::writeExtensionClassImplementation(QTextStream &stream, const QString &extension) const
{
    const QString className = generateExtensionClassName(extension);
    const QString privateClassName = generateExtensionClassName(extension, Private);

    // Output default constructor
    stream << className << QStringLiteral("::") << className << QStringLiteral("()") << endl;
    stream << QStringLiteral(" : QAbstractOpenGLExtension(*(new ") << privateClassName << QStringLiteral("))") << endl;
    stream << QStringLiteral("{") << endl << QStringLiteral("}") << endl << endl;


    // Output function to initialize this class
    stream << QStringLiteral("bool ") << className
           << QStringLiteral("::initializeOpenGLFunctions()") << endl
           << QStringLiteral("{") << endl;

    stream << QStringLiteral("    if (isInitialized())") << endl;
    stream << QStringLiteral("        return true;") << endl << endl;

    stream << QStringLiteral("    QOpenGLContext *context = QOpenGLContext::currentContext();") << endl;
    stream << QStringLiteral("    if (!context) {") << endl;
    stream << QStringLiteral("        qWarning(\"A current OpenGL context is required to resolve OpenGL extension functions\");")
           << endl;
    stream << QStringLiteral("        return false;") << endl;
    stream << QStringLiteral("    }") << endl << endl;

    // Output code to resolve entry points for this class
    stream << QStringLiteral("    // Resolve the functions") << endl;
    stream << QStringLiteral("    Q_D(") << className << QStringLiteral(");") << endl;
    stream << endl;

    // Output function declarations
    QList<Function> functions = m_parser->functionsForExtension(extension);
    Q_FOREACH (const Function &f, functions)
        writeEntryPointResolutionStatement(stream, f, QStringLiteral("d->"));

    // Call the base class implementation
    stream << QStringLiteral("    QAbstractOpenGLExtension::initializeOpenGLFunctions();") << endl;

    // Finish off
    stream << QStringLiteral("    return true;") << endl;
    stream << QStringLiteral("}") << endl << endl;
}

QString CodeGenerator::generateExtensionClassName(const QString &extension, ClassVisibility visibility) const
{
    QString visibilitySuffix;
    if (visibility == Private)
        visibilitySuffix = QStringLiteral("Private");

    return QString(QStringLiteral("QOpenGLExtension_%1%2"))
            .arg(extension)
            .arg(visibilitySuffix);
}
