/****************************************************************************
**
** Copyright (C) 2016 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the Qt Assistant 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 "../shared/collectionconfiguration.h"
#include "helpgenerator.h"
#include "collectionconfigreader.h"
#include "qhelpprojectdata_p.h"

#include <QtCore/QBuffer>
#include <QtCore/QDataStream>
#include <QtCore/QDir>
#include <QtCore/QFileInfo>
#include <QtCore/QLibraryInfo>
#include <QtCore/QRegExp>
#include <QtCore/QTranslator>

#include <QtGui/QGuiApplication>

#include <QtHelp/QHelpEngineCore>


QT_USE_NAMESPACE

class QHG {
    Q_DECLARE_TR_FUNCTIONS(QHelpGenerator)
};

static const char QHP[]  = "qhp";
static const char QCH[]  = "qch";

static const char QHCP[] = "qhcp";
static const char QHC[]  = "qhc";

namespace {
    QString absoluteFilePath(const QString &basePath, const QString &fileName)
    {
        return QDir(basePath).absoluteFilePath(fileName);
    }
}

int generateCollectionFile(const QByteArray &data, const QString &basePath, const QString outputFile)
{
    fputs(qPrintable(QHG::tr("Reading collection config file...\n")), stdout);
    CollectionConfigReader config;
    config.readData(data);
    if (config.hasError()) {
        fputs(qPrintable(QHG::tr("Collection config file error: %1\n")
                         .arg(config.errorString())), stderr);
        return 1;
    }

    const QMap<QString, QString> &filesToGenerate = config.filesToGenerate();
    for (auto it = filesToGenerate.cbegin(), end = filesToGenerate.cend(); it != end; ++it) {
        fputs(qPrintable(QHG::tr("Generating help for %1...\n").arg(it.key())), stdout);
        QHelpProjectData helpData;
        if (!helpData.readData(absoluteFilePath(basePath, it.key()))) {
            fprintf(stderr, "%s\n", qPrintable(helpData.errorMessage()));
            return 1;
        }

        HelpGenerator helpGenerator;
        if (!helpGenerator.generate(&helpData, absoluteFilePath(basePath, it.value()))) {
            fprintf(stderr, "%s\n", qPrintable(helpGenerator.error()));
            return 1;
        }
    }

    fputs(qPrintable(QHG::tr("Creating collection file...\n")), stdout);

    QFileInfo colFi(outputFile);
    if (colFi.exists()) {
        if (!colFi.dir().remove(colFi.fileName())) {
            fputs(qPrintable(QHG::tr("The file %1 cannot be overwritten.\n")
                             .arg(outputFile)), stderr);
            return 1;
        }
    }

    QHelpEngineCore helpEngine(outputFile);
    if (!helpEngine.setupData()) {
        fprintf(stderr, "%s\n", qPrintable(helpEngine.error()));
        return 1;
    }

    for (const QString &file : config.filesToRegister()) {
        if (!helpEngine.registerDocumentation(absoluteFilePath(basePath, file))) {
            fprintf(stderr, "%s\n", qPrintable(helpEngine.error()));
            return 1;
        }
    }
    if (!config.filesToRegister().isEmpty()) {
        if (Q_UNLIKELY(qEnvironmentVariableIsSet("SOURCE_DATE_EPOCH"))) {
            QDateTime dt;
            dt.setSecsSinceEpoch(qEnvironmentVariableIntValue("SOURCE_DATE_EPOCH"));
            CollectionConfiguration::updateLastRegisterTime(helpEngine, dt);
        } else {
            CollectionConfiguration::updateLastRegisterTime(helpEngine);
        }
    }

    if (!config.title().isEmpty())
        CollectionConfiguration::setWindowTitle(helpEngine, config.title());

    if (!config.homePage().isEmpty()) {
        CollectionConfiguration::setDefaultHomePage(helpEngine,
            config.homePage());
    }

    if (!config.startPage().isEmpty()) {
        CollectionConfiguration::setLastShownPages(helpEngine,
            QStringList(config.startPage()));
    }

    if (!config.currentFilter().isEmpty()) {
        helpEngine.setCurrentFilter(config.currentFilter());
    }

    if (!config.cacheDirectory().isEmpty()) {
        CollectionConfiguration::setCacheDir(helpEngine, config.cacheDirectory(),
            config.cacheDirRelativeToCollection());
    }

    CollectionConfiguration::setFilterFunctionalityEnabled(helpEngine,
        config.enableFilterFunctionality());
    CollectionConfiguration::setFilterToolbarVisible(helpEngine,
        !config.hideFilterFunctionality());
    CollectionConfiguration::setDocumentationManagerEnabled(helpEngine,
        config.enableDocumentationManager());
    CollectionConfiguration::setAddressBarEnabled(helpEngine,
        config.enableAddressBar());
    CollectionConfiguration::setAddressBarVisible(helpEngine,
         !config.hideAddressBar());
    uint time = QDateTime::currentMSecsSinceEpoch() / 1000;
    if (Q_UNLIKELY(qEnvironmentVariableIsSet("SOURCE_DATE_EPOCH")))
        time = qEnvironmentVariableIntValue("SOURCE_DATE_EPOCH");
    CollectionConfiguration::setCreationTime(helpEngine, time);
    CollectionConfiguration::setFullTextSearchFallbackEnabled(helpEngine,
        config.fullTextSearchFallbackEnabled());

    if (!config.applicationIcon().isEmpty()) {
        QFile icon(absoluteFilePath(basePath, config.applicationIcon()));
        if (!icon.open(QIODevice::ReadOnly)) {
            fputs(qPrintable(QHG::tr("Cannot open %1.\n").arg(icon.fileName())), stderr);
            return 1;
        }
        CollectionConfiguration::setApplicationIcon(helpEngine, icon.readAll());
    }

    if (config.aboutMenuTexts().count()) {
        QByteArray ba;
        QDataStream s(&ba, QIODevice::WriteOnly);
        const QMap<QString, QString> &aboutMenuTexts = config.aboutMenuTexts();
        for (auto it = aboutMenuTexts.cbegin(), end = aboutMenuTexts.cend(); it != end; ++it)
            s << it.key() << it.value();
        CollectionConfiguration::setAboutMenuTexts(helpEngine, ba);
    }

    if (!config.aboutIcon().isEmpty()) {
        QFile icon(absoluteFilePath(basePath, config.aboutIcon()));
        if (!icon.open(QIODevice::ReadOnly)) {
            fputs(qPrintable(QHG::tr("Cannot open %1.\n").arg(icon.fileName())), stderr);
            return 1;
        }
        CollectionConfiguration::setAboutIcon(helpEngine, icon.readAll());
    }

    if (config.aboutTextFiles().count()) {
        QByteArray ba;
        QDataStream s(&ba, QIODevice::WriteOnly);
        QMap<QString, QByteArray> imgData;

        QRegExp srcRegExp(QLatin1String("src=(\"(.+)\"|([^\"\\s]+)).*>"));
        srcRegExp.setMinimal(true);
        QRegExp imgRegExp(QLatin1String("(<img[^>]+>)"));
        imgRegExp.setMinimal(true);

        const QMap<QString, QString> &aboutMenuTexts = config.aboutTextFiles();
        for (auto it = aboutMenuTexts.cbegin(), end = aboutMenuTexts.cend(); it != end; ++it) {
            s << it.key();
            QFileInfo fi(absoluteFilePath(basePath, it.value()));
            QFile f(fi.absoluteFilePath());
            if (!f.open(QIODevice::ReadOnly)) {
                fputs(qPrintable(QHG::tr("Cannot open %1.\n").arg(f.fileName())), stderr);
                return 1;
            }
            QByteArray data = f.readAll();
            s << data;

            QString contents = QString::fromUtf8(data);
            int pos = 0;
            while ((pos = imgRegExp.indexIn(contents, pos)) != -1) {
                QString imgTag = imgRegExp.cap(1);
                pos += imgRegExp.matchedLength();

                if (srcRegExp.indexIn(imgTag, 0) != -1) {
                    QString src = srcRegExp.cap(2);
                    if (src.isEmpty())
                        src = srcRegExp.cap(3);

                    QFile img(fi.absolutePath() + QDir::separator() + src);
                    if (img.open(QIODevice::ReadOnly)) {
                        if (!imgData.contains(src))
                            imgData.insert(src, img.readAll());
                    } else {
                        fputs(qPrintable(QHG::tr("Cannot open referenced image file %1.\n")
                                         .arg(img.fileName())), stderr);
                    }
                }
            }
        }
        CollectionConfiguration::setAboutTexts(helpEngine, ba);
        if (imgData.count()) {
            QByteArray imageData;
            QBuffer buffer(&imageData);
            buffer.open(QIODevice::WriteOnly);
            QDataStream out(&buffer);
            out << imgData;
            CollectionConfiguration::setAboutImages(helpEngine, imageData);
        }
    }
    return 0;
}

int main(int argc, char *argv[])
{
    QString error;
    QString outputFile;
    QString inputFile;
    QString basePath;
    bool showHelp = false;
    bool showVersion = false;
    bool checkLinks = false;
    bool silent = false;

    // don't require a window manager even though we're a QGuiApplication
    qputenv("QT_QPA_PLATFORM", QByteArrayLiteral("minimal"));

    QGuiApplication app(argc, argv);
#ifndef Q_OS_WIN32
    QTranslator translator;
    QTranslator qtTranslator;
    QTranslator qt_helpTranslator;
    QString sysLocale = QLocale::system().name();
    QString resourceDir = QLibraryInfo::location(QLibraryInfo::TranslationsPath);
    if (translator.load(QLatin1String("assistant_") + sysLocale, resourceDir)
        && qtTranslator.load(QLatin1String("qt_") + sysLocale, resourceDir)
        && qt_helpTranslator.load(QLatin1String("qt_help_") + sysLocale, resourceDir)) {
        app.installTranslator(&translator);
        app.installTranslator(&qtTranslator);
        app.installTranslator(&qt_helpTranslator);
    }
#endif // Q_OS_WIN32

    for (int i = 1; i < argc; ++i) {
        const QString arg = QString::fromLocal8Bit(argv[i]);
        if (arg == QLatin1String("-o")) {
            if (++i < argc) {
                QFileInfo fi(QString::fromLocal8Bit(argv[i]));
                outputFile = fi.absoluteFilePath();
            } else {
                error = QHG::tr("Missing output file name.");
            }
        } else if (arg == QLatin1String("-v")) {
            showVersion = true;
        } else if (arg == QLatin1String("-h")) {
            showHelp = true;
        } else if (arg == QLatin1String("-c")) {
            checkLinks = true;
        } else if (arg == QLatin1String("-s")) {
            silent = true;
        } else {
            const QFileInfo fi(arg);
            inputFile = fi.absoluteFilePath();
            basePath = fi.absolutePath();
        }
    }

    if (showVersion) {
        fputs(qPrintable(QHG::tr("Qt Help Generator version 1.0 (Qt %1)\n")
                         .arg(QT_VERSION_STR)), stdout);
        return 0;
    }

    enum InputType {
        InputQhp,
        InputQhcp,
        InputUnknown
    };

    InputType inputType = InputUnknown;

    if (!showHelp) {
        if (inputFile.isEmpty()) {
            error = QHG::tr("Missing input file name.");
        } else {
            const QFileInfo fi(inputFile);
            if (fi.suffix() == QHP)
                inputType = InputQhp;
            else if (fi.suffix() == QHCP)
                inputType = InputQhcp;

            if (inputType == InputUnknown)
                error = QHG::tr("Unknown input file type.");
        }
    }

    const QString help = QHG::tr("\nUsage:\n\n"
        "qhelpgenerator <file> [options]\n\n"
        "  -o <output-file>       Generates a Qt compressed help\n"
        "                         called <output-file> (*.qch) for the\n"
        "                         Qt help project <file> (*.qhp).\n"
        "                         Generates a Qt help collection\n"
        "                         called <output-file> (*.qhc) for the\n"
        "                         Qt help collection project <file> (*.qhcp).\n"
        "                         If this option is not specified\n"
        "                         a default name will be used\n"
        "                         (*.qch for *.qhp and *.qhc for *.qhcp).\n"
        "  -c                     Checks whether all links in HTML files\n"
        "                         point to files in this help project.\n"
        "  -s                     Suppresses status messages.\n"
        "  -v                     Displays the version of \n"
        "                         qhelpgenerator.\n\n");

    if (showHelp) {
        fputs(qPrintable(help), stdout);
        return 0;
    } else if (!error.isEmpty()) {
        fprintf(stderr, "%s\n\n%s", qPrintable(error), qPrintable(help));
        return 1;
    }

    // detect input file type (qhp or qhcp)

    QFile file(inputFile);
    if (!file.open(QIODevice::ReadOnly)) {
        fputs(qPrintable(QHG::tr("Could not open %1.\n").arg(inputFile)), stderr);
        return 1;
    }

    const QString outputExtension = inputType == InputQhp ? QCH : QHC;

    if (outputFile.isEmpty()) {
        if (inputType == InputQhcp || !checkLinks) {
            QFileInfo fi(inputFile);
            outputFile = basePath + QDir::separator()
                             + fi.baseName() + QLatin1Char('.') + outputExtension;
        }
    } else {
        // check if the output dir exists -- create if it doesn't
        QFileInfo fi(outputFile);
        QDir parentDir = fi.dir();
        if (!parentDir.exists()) {
            if (!parentDir.mkpath(QLatin1String("."))) {
                fputs(qPrintable(QHG::tr("Could not create output directory: %1\n")
                                 .arg(parentDir.path())), stderr);
            }
        }
    }

    if (inputType == InputQhp) {
        QHelpProjectData *helpData = new QHelpProjectData();
        if (!helpData->readData(inputFile)) {
            fprintf(stderr, "%s\n", qPrintable(helpData->errorMessage()));
            return 1;
        }

        HelpGenerator generator(silent);
        bool success = true;
        if (checkLinks)
            success = generator.checkLinks(*helpData);
        if (success && !outputFile.isEmpty())
            success = generator.generate(helpData, outputFile);
        delete helpData;
        if (!success) {
            fprintf(stderr, "%s\n", qPrintable(generator.error()));
            return 1;
        }
    } else {
        const QByteArray data = file.readAll();
        return generateCollectionFile(data, basePath, outputFile);

    }

    return 0;
}
