/****************************************************************************
**
** Copyright (C) 2020 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the tools applications 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 <qbytearray.h>
#include <qstring.h>
#include <qvarlengtharray.h>
#include <qfile.h>
#include <qlist.h>
#include <qbuffer.h>
#include <qvector.h>
#include <qdebug.h>

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include <qdbusconnection.h>    // for the Export* flags
#include <private/qdbusconnection_p.h>    // for the qDBusCheckAsyncTag

// copied from dbus-protocol.h:
static const char docTypeHeader[] =
    "<!DOCTYPE node PUBLIC \"-//freedesktop//DTD D-BUS Object Introspection 1.0//EN\" "
    "\"http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd\">\n";

#define ANNOTATION_NO_WAIT      "org.freedesktop.DBus.Method.NoReply"
#define QCLASSINFO_DBUS_INTERFACE       "D-Bus Interface"
#define QCLASSINFO_DBUS_INTROSPECTION   "D-Bus Introspection"

#include <qdbusmetatype.h>
#include <private/qdbusmetatype_p.h>
#include <private/qdbusutil_p.h>

#include "moc.h"
#include "generator.h"
#include "preprocessor.h"

#define PROGRAMNAME     "qdbuscpp2xml"
#define PROGRAMVERSION  "0.2"
#define PROGRAMCOPYRIGHT "Copyright (C) 2020 The Qt Company Ltd."

static QString outputFile;
static int flags;

static const char help[] =
    "Usage: " PROGRAMNAME " [options...] [files...]\n"
    "Parses the C++ source or header file containing a QObject-derived class and\n"
    "produces the D-Bus Introspection XML."
    "\n"
    "Options:\n"
    "  -p|-s|-m       Only parse scriptable Properties, Signals and Methods (slots)\n"
    "  -P|-S|-M       Parse all Properties, Signals and Methods (slots)\n"
    "  -a             Output all scriptable contents (equivalent to -psm)\n"
    "  -A             Output all contents (equivalent to -PSM)\n"
    "  -o <filename>  Write the output to file <filename>\n"
    "  -h             Show this information\n"
    "  -V             Show the program version and quit.\n"
    "\n";


int qDBusParametersForMethod(const FunctionDef &mm, QVector<int>& metaTypes, QString &errorMsg)
{
    QList<QByteArray> parameterTypes;
    parameterTypes.reserve(mm.arguments.size());

    for (const ArgumentDef &arg : mm.arguments)
        parameterTypes.append(arg.normalizedType);

    return qDBusParametersForMethod(parameterTypes, metaTypes, errorMsg);
}


static inline QString typeNameToXml(const char *typeName)
{
    QString plain = QLatin1String(typeName);
    return plain.toHtmlEscaped();
}

static QString addFunction(const FunctionDef &mm, bool isSignal = false) {

    QString xml = QString::asprintf("    <%s name=\"%s\">\n",
                                    isSignal ? "signal" : "method", mm.name.constData());

    // check the return type first
    int typeId = QMetaType::type(mm.normalizedType.constData());
    if (typeId != QMetaType::Void) {
        if (typeId) {
            const char *typeName = QDBusMetaType::typeToSignature(typeId);
            if (typeName) {
                xml += QString::fromLatin1("      <arg type=\"%1\" direction=\"out\"/>\n")
                        .arg(typeNameToXml(typeName));

                    // do we need to describe this argument?
                    if (QDBusMetaType::signatureToType(typeName) == QMetaType::UnknownType)
                        xml += QString::fromLatin1("      <annotation name=\"org.qtproject.QtDBus.QtTypeName.Out0\" value=\"%1\"/>\n")
                            .arg(typeNameToXml(mm.normalizedType.constData()));
            } else {
                return QString();
            }
        } else if (!mm.normalizedType.isEmpty()) {
            return QString();           // wasn't a valid type
        }
    }
    QVector<ArgumentDef> names = mm.arguments;
    QVector<int> types;
    QString errorMsg;
    int inputCount = qDBusParametersForMethod(mm, types, errorMsg);
    if (inputCount == -1) {
        qWarning() << qPrintable(errorMsg);
        return QString();           // invalid form
    }
    if (isSignal && inputCount + 1 != types.count())
        return QString();           // signal with output arguments?
    if (isSignal && types.at(inputCount) == QDBusMetaTypeId::message())
        return QString();           // signal with QDBusMessage argument?

    bool isScriptable = mm.isScriptable;
    for (int j = 1; j < types.count(); ++j) {
        // input parameter for a slot or output for a signal
        if (types.at(j) == QDBusMetaTypeId::message()) {
            isScriptable = true;
            continue;
        }

        QString name;
        if (!names.at(j - 1).name.isEmpty())
            name = QString::fromLatin1("name=\"%1\" ").arg(QString::fromLatin1(names.at(j - 1).name));

        bool isOutput = isSignal || j > inputCount;

        const char *signature = QDBusMetaType::typeToSignature(types.at(j));
        xml += QString::fromLatin1("      <arg %1type=\"%2\" direction=\"%3\"/>\n")
                .arg(name,
                     QLatin1String(signature),
                     isOutput ? QLatin1String("out") : QLatin1String("in"));

        // do we need to describe this argument?
        if (QDBusMetaType::signatureToType(signature) == QMetaType::UnknownType) {
            const char *typeName = QMetaType::typeName(types.at(j));
            xml += QString::fromLatin1("      <annotation name=\"org.qtproject.QtDBus.QtTypeName.%1%2\" value=\"%3\"/>\n")
                    .arg(isOutput ? QLatin1String("Out") : QLatin1String("In"))
                    .arg(isOutput && !isSignal ? j - inputCount : j - 1)
                    .arg(typeNameToXml(typeName));
        }
    }

    int wantedMask;
    if (isScriptable)
        wantedMask = isSignal ? QDBusConnection::ExportScriptableSignals
                              : QDBusConnection::ExportScriptableSlots;
    else
        wantedMask = isSignal ? QDBusConnection::ExportNonScriptableSignals
                              : QDBusConnection::ExportNonScriptableSlots;
    if ((flags & wantedMask) != wantedMask)
        return QString();

    if (qDBusCheckAsyncTag(mm.tag.constData()))
        // add the no-reply annotation
        xml += QLatin1String("      <annotation name=\"" ANNOTATION_NO_WAIT "\""
                              " value=\"true\"/>\n");

    QString retval = xml;
    retval += QString::fromLatin1("    </%1>\n")
              .arg(isSignal ? QLatin1String("signal") : QLatin1String("method"));

    return retval;
}


static QString generateInterfaceXml(const ClassDef *mo)
{
    QString retval;

    // start with properties:
    if (flags & (QDBusConnection::ExportScriptableProperties |
                 QDBusConnection::ExportNonScriptableProperties)) {
        static const char *accessvalues[] = {0, "read", "write", "readwrite"};
        for (const PropertyDef &mp : mo->propertyList) {
            if (!((!mp.scriptable.isEmpty() && (flags & QDBusConnection::ExportScriptableProperties)) ||
                  (!mp.scriptable.isEmpty() && (flags & QDBusConnection::ExportNonScriptableProperties))))
                continue;

            int access = 0;
            if (!mp.read.isEmpty())
                access |= 1;
            if (!mp.write.isEmpty())
                access |= 2;

            int typeId = QMetaType::type(mp.type.constData());
            if (!typeId) {
                fprintf(stderr, PROGRAMNAME ": unregistered type: '%s', ignoring\n",
                        mp.type.constData());
                continue;
            }
            const char *signature = QDBusMetaType::typeToSignature(typeId);
            if (!signature)
                continue;

            retval += QString::fromLatin1("    <property name=\"%1\" type=\"%2\" access=\"%3\"")
                      .arg(QLatin1String(mp.name),
                           QLatin1String(signature),
                           QLatin1String(accessvalues[access]));

            if (QDBusMetaType::signatureToType(signature) == QMetaType::UnknownType) {
                retval += QString::fromLatin1(">\n      <annotation name=\"org.qtproject.QtDBus.QtTypeName\" value=\"%3\"/>\n    </property>\n")
                          .arg(typeNameToXml(mp.type.constData()));
            } else {
                retval += QLatin1String("/>\n");
            }
        }
    }

    // now add methods:

    if (flags & (QDBusConnection::ExportScriptableSignals | QDBusConnection::ExportNonScriptableSignals)) {
        for (const FunctionDef &mm : mo->signalList) {
            if (mm.wasCloned)
                continue;
            if (!mm.isScriptable && !(flags & QDBusConnection::ExportNonScriptableSignals))
                continue;

            retval += addFunction(mm, true);
        }
    }

    if (flags & (QDBusConnection::ExportScriptableSlots | QDBusConnection::ExportNonScriptableSlots)) {
        for (const FunctionDef &slot : mo->slotList) {
            if (!slot.isScriptable && !(flags & QDBusConnection::ExportNonScriptableSlots))
                continue;
            if (slot.access == FunctionDef::Public)
              retval += addFunction(slot);
        }
        for (const FunctionDef &method : mo->methodList) {
            if (!method.isScriptable && !(flags & QDBusConnection::ExportNonScriptableSlots))
                continue;
            if (method.access == FunctionDef::Public)
              retval += addFunction(method);
        }
    }
    return retval;
}

QString qDBusInterfaceFromClassDef(const ClassDef *mo)
{
    QString interface;

    for (const ClassInfoDef &cid : mo->classInfoList) {
        if (cid.name == QCLASSINFO_DBUS_INTERFACE)
            return QString::fromUtf8(cid.value);
    }
    interface = QLatin1String(mo->classname);
    interface.replace(QLatin1String("::"), QLatin1String("."));

    if (interface.startsWith(QLatin1String("QDBus"))) {
        interface.prepend(QLatin1String("org.qtproject.QtDBus."));
    } else if (interface.startsWith(QLatin1Char('Q')) &&
                interface.length() >= 2 && interface.at(1).isUpper()) {
        // assume it's Qt
        interface.prepend(QLatin1String("local.org.qtproject.Qt."));
    } else {
        interface.prepend(QLatin1String("local."));
    }

    return interface;
}


QString qDBusGenerateClassDefXml(const ClassDef *cdef)
{
    for (const ClassInfoDef &cid : cdef->classInfoList) {
        if (cid.name == QCLASSINFO_DBUS_INTROSPECTION)
            return QString::fromUtf8(cid.value);
    }

    // generate the interface name from the meta object
    QString interface = qDBusInterfaceFromClassDef(cdef);

    QString xml = generateInterfaceXml(cdef);

    if (xml.isEmpty())
        return QString();       // don't add an empty interface
    return QString::fromLatin1("  <interface name=\"%1\">\n%2  </interface>\n")
        .arg(interface, xml);
}

static void showHelp()
{
    printf("%s", help);
    exit(0);
}

static void showVersion()
{
    printf("%s version %s\n", PROGRAMNAME, PROGRAMVERSION);
    printf("D-Bus QObject-to-XML converter\n");
    exit(0);
}

static void parseCmdLine(QStringList &arguments)
{
    flags = 0;
    for (int i = 0; i < arguments.count(); ++i) {
        const QString arg = arguments.at(i);

        if (arg == QLatin1String("--help"))
            showHelp();

        if (!arg.startsWith(QLatin1Char('-')))
            continue;

        char c = arg.count() == 2 ? arg.at(1).toLatin1() : char(0);
        switch (c) {
        case 'P':
            flags |= QDBusConnection::ExportNonScriptableProperties;
            Q_FALLTHROUGH();
        case 'p':
            flags |= QDBusConnection::ExportScriptableProperties;
            break;

        case 'S':
            flags |= QDBusConnection::ExportNonScriptableSignals;
            Q_FALLTHROUGH();
        case 's':
            flags |= QDBusConnection::ExportScriptableSignals;
            break;

        case 'M':
            flags |= QDBusConnection::ExportNonScriptableSlots;
            Q_FALLTHROUGH();
        case 'm':
            flags |= QDBusConnection::ExportScriptableSlots;
            break;

        case 'A':
            flags |= QDBusConnection::ExportNonScriptableContents;
            Q_FALLTHROUGH();
        case 'a':
            flags |= QDBusConnection::ExportScriptableContents;
            break;

        case 'o':
            if (arguments.count() < i + 2 || arguments.at(i + 1).startsWith(QLatin1Char('-'))) {
                printf("-o expects a filename\n");
                exit(1);
            }
            outputFile = arguments.takeAt(i + 1);
            break;

        case 'h':
        case '?':
            showHelp();
            break;

        case 'V':
            showVersion();
            break;

        default:
            printf("unknown option: \"%s\"\n", qPrintable(arg));
            exit(1);
        }
    }

    if (flags == 0)
        flags = QDBusConnection::ExportScriptableContents
                | QDBusConnection::ExportNonScriptableContents;
}

int main(int argc, char **argv)
{
    QStringList args;
    args.reserve(argc - 1);
    for (int n = 1; n < argc; ++n)
        args.append(QString::fromLocal8Bit(argv[n]));
    parseCmdLine(args);

    QVector<ClassDef> classes;

    for (int i = 0; i < args.count(); ++i) {
        const QString arg = args.at(i);

        if (arg.startsWith(QLatin1Char('-')))
            continue;

        QFile f(arg);
        if (!f.open(QIODevice::ReadOnly|QIODevice::Text)) {
            fprintf(stderr, PROGRAMNAME ": could not open '%s': %s\n",
                    qPrintable(arg), qPrintable(f.errorString()));
            return 1;
        }

        Preprocessor pp;
        Moc moc;
        pp.macros["Q_MOC_RUN"];
        pp.macros["__cplusplus"];

        const QByteArray filename = arg.toLocal8Bit();

        moc.filename = filename;
        moc.currentFilenames.push(filename);

        moc.symbols = pp.preprocessed(moc.filename, &f);
        moc.parse();

        if (moc.classList.isEmpty())
            return 0;
        classes = moc.classList;

        f.close();
    }

    QFile output;
    if (outputFile.isEmpty()) {
        output.open(stdout, QIODevice::WriteOnly);
    } else {
        output.setFileName(outputFile);
        if (!output.open(QIODevice::WriteOnly)) {
            fprintf(stderr, PROGRAMNAME ": could not open output file '%s': %s",
                    qPrintable(outputFile), qPrintable(output.errorString()));
            return 1;
        }
    }

    output.write(docTypeHeader);
    output.write("<node>\n");
    for (const ClassDef &cdef : qAsConst(classes)) {
        QString xml = qDBusGenerateClassDefXml(&cdef);
        output.write(std::move(xml).toLocal8Bit());
    }
    output.write("</node>\n");

    return 0;
}

