/****************************************************************************
**
** Copyright (C) 2017 Ford Motor Company
** Contact: https://www.qt.io/licensing/
**
** This file is part of the QtRemoteObjects module 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 <qcommandlineoption.h>
#include <qcommandlineparser.h>
#include <qcoreapplication.h>
#include <qfileinfo.h>

#include "cppcodegenerator.h"
#include "moc.h"
#include "preprocessor.h"
#include "repcodegenerator.h"
#include "repparser.h"
#include "utils.h"

#include <cstdio>

#define PROGRAM_NAME  "repc"
#define REPC_VERSION  "0.1"

enum Mode {
    InRep = 1,
    InSrc = 2,
    OutRep = 4,
    OutSource = 8,
    OutReplica = 16,
    OutMerged = OutSource | OutReplica
};

static const QLatin1String REP("rep");
static const QLatin1String SRC("src");
static const QLatin1String REPLICA("replica");
static const QLatin1String SOURCE("source");
static const QLatin1String MERGED("merged");

QT_USE_NAMESPACE

int main(int argc, char **argv)
{
    QCoreApplication app(argc, argv);
    QCoreApplication::setApplicationVersion(QString::fromLatin1(REPC_VERSION));

    QString outputFile;
    QString inputFile;
    int mode = 0;
    QCommandLineParser parser;
    parser.setApplicationDescription(QStringLiteral("repc tool v%1 (Qt %2).\n")
                                     .arg(QStringLiteral(REPC_VERSION), QString::fromLatin1(QT_VERSION_STR)));
    parser.addHelpOption();
    parser.addVersionOption();
    QCommandLineOption inputTypeOption(QStringLiteral("i"));
    inputTypeOption.setDescription(QLatin1String("Input file type:\n"
                                                  "rep: replicant template files.\n"
                                                  "src: C++ QObject derived classes."));
    inputTypeOption.setValueName(QStringLiteral("rep|src"));
    parser.addOption(inputTypeOption);

    QCommandLineOption outputTypeOption(QStringLiteral("o"));
    outputTypeOption.setDescription(QLatin1String("Output file type:\n"
                                                   "source: generates source header. Is incompatible with \"-i src\" option.\n"
                                                   "replica: generates replica header.\n"
                                                   "merged: generates combined replica/source header.\n"
                                                   "rep: generates replicant template file from C++ QOject classes. Is not compatible with \"-i rep\" option."));
    outputTypeOption.setValueName(QStringLiteral("source|replica|merged|rep"));
    parser.addOption(outputTypeOption);

    QCommandLineOption includePathOption(QStringLiteral("I"));
    includePathOption.setDescription(QStringLiteral("Add dir to the include path for header files. This parameter is needed only if the input file type is src (.h file)."));
    includePathOption.setValueName(QStringLiteral("dir"));
    parser.addOption(includePathOption);

    QCommandLineOption alwaysClassOption(QStringLiteral("c"));
    alwaysClassOption.setDescription(QStringLiteral("Always output `class` type for .rep files and never `POD`."));
    parser.addOption(alwaysClassOption);

    QCommandLineOption debugOption(QStringLiteral("d"));
    debugOption.setDescription(QStringLiteral("Print out parsing debug information (for troubleshooting)."));
    parser.addOption(debugOption);

    parser.addPositionalArgument(QStringLiteral("[header-file/rep-file]"),
            QStringLiteral("Input header/rep file to read from, otherwise stdin."));

    parser.addPositionalArgument(QStringLiteral("[rep-file/header-file]"),
            QStringLiteral("Output header/rep file to write to, otherwise stdout."));

    parser.process(app.arguments());

    const QStringList files = parser.positionalArguments();

    if (files.count() > 2) {
        fprintf(stderr, "%s", qPrintable(QLatin1String(PROGRAM_NAME ": Too many input, output files specified: '") + files.join(QStringLiteral("' '")) + QStringLiteral("\'.\n")));
        parser.showHelp(1);
    }

    if (parser.isSet(inputTypeOption)) {
        const QString &inputType = parser.value(inputTypeOption);
        if (inputType == REP)
            mode = InRep;
        else if (inputType == SRC)
            mode = InSrc;
        else {
            fprintf(stderr, PROGRAM_NAME ": Unknown input type\"%s\".\n", qPrintable(inputType));
            parser.showHelp(1);
        }
    }

    if (parser.isSet(outputTypeOption)) {
        const QString &outputType = parser.value(outputTypeOption);
        if (outputType == REP)
            mode |= OutRep;
        else if (outputType == REPLICA)
            mode |= OutReplica;
        else if (outputType == SOURCE)
            mode |= OutSource;
        else if (outputType == MERGED)
            mode |= OutMerged;
        else {
            fprintf(stderr, PROGRAM_NAME ": Unknown output type\"%s\".\n", qPrintable(outputType));
            parser.showHelp(1);
        }
    }

    switch (files.count()) {
    case 2:
        outputFile = files.last();
        if (!(mode & (OutRep | OutSource | OutReplica))) {
            // try to figure out the Out mode from file extension
            if (outputFile.endsWith(QLatin1String(".rep")))
                mode |= OutRep;
        }
        Q_FALLTHROUGH();
    case 1:
        inputFile = files.first();
        if (!(mode & (InRep | InSrc))) {
            // try to figure out the In mode from file extension
            if (inputFile.endsWith(QLatin1String(".rep")))
                mode |= InRep;
            else
                mode |= InSrc;
        }
        break;
    }
    // check mode sanity
    if (!(mode & (InRep | InSrc))) {
        fprintf(stderr, PROGRAM_NAME ": Unknown input type, please use -i option to specify one.\n");
        parser.showHelp(1);
    }
    if (!(mode & (OutRep | OutSource | OutReplica))) {
        fprintf(stderr, PROGRAM_NAME ": Unknown output type, please use -o option to specify one.\n");
        parser.showHelp(1);
    }
    if (mode & InRep && mode & OutRep) {
        fprintf(stderr, PROGRAM_NAME ": Invalid input/output type combination, both are rep files.\n");
        parser.showHelp(1);
    }
    if (mode & InSrc && mode & OutSource) {
        fprintf(stderr, PROGRAM_NAME ": Invalid input/output type combination, both are source header files.\n");
        parser.showHelp(1);
    }

    QFile input;
    if (inputFile.isEmpty()) {
        inputFile = QStringLiteral("<stdin>");
        input.open(stdin, QIODevice::ReadOnly);
    } else {
        input.setFileName(inputFile);
        if (!input.open(QIODevice::ReadOnly)) {
            fprintf(stderr, PROGRAM_NAME ": %s: No such file.\n", qPrintable(inputFile));
            return 1;
        }
    }

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

    if (mode & InSrc) {
        Preprocessor pp;
        const QFileInfo includePath(QLatin1String(RO_INSTALL_HEADERS));
        pp.includes += Preprocessor::IncludePath(QFile::encodeName(includePath.canonicalFilePath()));
        pp.includes += Preprocessor::IncludePath(QFile::encodeName(includePath.canonicalPath()));
        const auto paths = parser.values(includePathOption);
        for (const QString &path : paths)
            pp.includes += Preprocessor::IncludePath(QFile::encodeName(path));

        pp.macros["Q_MOC_RUN"];
        pp.macros["__cplusplus"];

        Moc moc;
        if (!inputFile.isEmpty())
            moc.filename = inputFile.toLocal8Bit();
        moc.currentFilenames.push(inputFile.toLocal8Bit());
        moc.includes = pp.includes;
        moc.symbols = pp.preprocessed(moc.filename, &input);
        moc.parse();

        if (moc.classList.isEmpty()) {
            fprintf(stderr, PROGRAM_NAME ": No QObject classes found.\n");
            return 0;
        }

        input.close();

        if (mode & OutRep) {
            CppCodeGenerator generator(&output);
            generator.generate(moc.classList, parser.isSet(alwaysClassOption));
        } else {
            Q_ASSERT(mode & OutReplica);
            RepCodeGenerator generator(&output);
            generator.generate(classList2AST(moc.classList), RepCodeGenerator::REPLICA, outputFile);
        }
    } else {
        Q_ASSERT(!(mode & OutRep));
        RepParser repparser(input);
        if (parser.isSet(debugOption))
            repparser.setDebug();
        if (!repparser.parse()) {
            fprintf(stderr, PROGRAM_NAME ": %s:%d: error: %s\n", qPrintable(inputFile), repparser.lineNumber(), qPrintable(repparser.errorString()));
            // if everything is okay and only the input was malformed => remove the output file
            // let's not create an empty file -- make sure the build system tries to run repc again
            // this is the same behavior other code generators exhibit (e.g. flex)
            output.remove();
            return 1;
        }

        input.close();

        RepCodeGenerator generator(&output);
        if ((mode & OutMerged) == OutMerged)
            generator.generate(repparser.ast(), RepCodeGenerator::MERGED, outputFile);
        else if (mode & OutReplica)
            generator.generate(repparser.ast(), RepCodeGenerator::REPLICA, outputFile);
        else if (mode & OutSource)
            generator.generate(repparser.ast(), RepCodeGenerator::SOURCE, outputFile);
        else {
            fprintf(stderr, PROGRAM_NAME ": Unknown mode.\n");
            return 1;
        }
    }

    output.close();
    return 0;
}
