/****************************************************************************
**
** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
** All rights reserved.
** Contact: Nokia Corporation (qt-info@nokia.com)
**
** This file is part of the tools applications of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** GNU Lesser General Public License Usage
** This file may be used under the terms of the GNU Lesser General Public
** License version 2.1 as published by the Free Software Foundation and
** appearing in the file LICENSE.LGPL included in the packaging of this
** file. Please review the following information to ensure the GNU Lesser
** General Public License version 2.1 requirements will be met:
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, Nokia gives you certain additional
** rights. These rights are described in the Nokia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU General
** Public License version 3.0 as published by the Free Software Foundation
** and appearing in the file LICENSE.GPL included in the packaging of this
** file. Please review the following information to ensure the GNU General
** Public License version 3.0 requirements will be met:
** http://www.gnu.org/copyleft/gpl.html.
**
** Other Usage
** Alternatively, this file may be used in accordance with the terms and
** conditions contained in a signed written agreement between you and Nokia.
**
**
**
**
**
** $QT_END_LICENSE$
**
****************************************************************************/

/*
  main.cpp
*/

#include <qglobal.h>
#include <stdlib.h>
#include "codemarker.h"
#include "codeparser.h"
#include "config.h"
#include "cppcodemarker.h"
#include "cppcodeparser.h"
#include "ditaxmlgenerator.h"
#include "doc.h"
#include "htmlgenerator.h"
#include "jscodemarker.h"
#include "plaincodemarker.h"
#include "puredocparser.h"
#include "qmlcodemarker.h"
#include "qmlcodeparser.h"
#include "tokenizer.h"
#include "tree.h"
#include <qdebug.h>

#include "qtranslator.h"
#ifndef QT_BOOTSTRAPPED
#  include "qcoreapplication.h"
#endif

QT_BEGIN_NAMESPACE

/*
  The default indent for code is 4.
  The default value for false is 0.
  The default language is c++.
  The default output format is html.
  The default tab size is 8.
  And those are all the default values for configuration variables.
 */
static const struct {
    const char *key;
    const char *value;
} defaults[] = {
    { CONFIG_CODEINDENT, "4" },
    { CONFIG_FALSEHOODS, "0" },
    { CONFIG_LANGUAGE, "Cpp" },
    { CONFIG_OUTPUTFORMATS, "HTML" },
    { CONFIG_TABSIZE, "8" },
    { 0, 0 }
};

static bool slow = false;
static bool showInternal = false;
static bool obsoleteLinks = false;
static QStringList defines;
static QHash<QString, Tree *> trees;

/*!
  Print the help message to \c stdout.
 */
static void printHelp()
{
    Location::information(tr("Usage: qdoc [options] file1.qdocconf ...\n"
                              "Options:\n"
                              "    -help         "
                              "Display this information and exit\n"
                              "    -version      "
                              "Display version of qdoc and exit\n"
                              "    -D<name>      "
                              "Define <name> as a macro while parsing sources\n"
                              "    -slow         "
                              "Turn on features that slow down qdoc\n"
                              "    -showinternal "
                              "Include stuff marked internal\n"
                              "    -obsoletelinks "
                              "Report links from obsolete items to non-obsolete items") );
}

/*!
  Prints the qdoc version number to stdout.
 */
static void printVersion()
{
    QString s = tr("qdoc version %1").arg(QT_VERSION_STR);
    Location::information(s);
}

/*!
  Processes the qdoc config file \a fileName. This is the
  controller for all of qdoc.
 */
static void processQdocconfFile(const QString &fileName)
{
#ifndef QT_NO_TRANSLATION
    QList<QTranslator *> translators;
#endif

    /*
      The Config instance represents the configuration data for qdoc.
      All the other classes are initialized with the config. Here we
      initialize the configuration with some default values.
     */
    Config config(tr("qdoc"));
    int i = 0;
    while (defaults[i].key) {
	config.setStringList(defaults[i].key,
                             QStringList() << defaults[i].value);
	++i;
    }
    config.setStringList(CONFIG_SYNTAXHIGHLIGHTING, QStringList(slow ? "true" : "false"));
    config.setStringList(CONFIG_SHOWINTERNAL,
                         QStringList(showInternal ? "true" : "false"));
    config.setStringList(CONFIG_OBSOLETELINKS,
                         QStringList(obsoleteLinks ? "true" : "false"));

    /*
      With the default configuration values in place, load
      the qdoc configuration file. Note that the configuration
      file may include other configuration files.

      The Location class keeps track of the current location
      in the file being processed, mainly for error reporting
      purposes.
     */
    Location::initialize(config);
    config.load(fileName);

    /*
      Add the defines to the configuration variables.
     */
    QStringList defs = defines + config.getStringList(CONFIG_DEFINES);
    config.setStringList(CONFIG_DEFINES,defs);
    Location::terminate();

    QString prevCurrentDir = QDir::currentPath();
    QString dir = QFileInfo(fileName).path();
    if (!dir.isEmpty())
	QDir::setCurrent(dir);

    /*
      Initialize all the classes and data structures with the
      qdoc configuration.
     */
    Location::initialize(config);
    Tokenizer::initialize(config);
    Doc::initialize(config);
    CodeMarker::initialize(config);
    CodeParser::initialize(config);
    Generator::initialize(config);

#ifndef QT_NO_TRANSLATION
    /*
      Load the language translators, if the configuration specifies any.
     */
    QStringList fileNames = config.getStringList(CONFIG_TRANSLATORS);
    QStringList::Iterator fn = fileNames.begin();
    while (fn != fileNames.end()) {
	QTranslator *translator = new QTranslator(0);
	if (!translator->load(*fn))
	    config.lastLocation().error(tr("Cannot load translator '%1'")
					 .arg(*fn));
	QCoreApplication::instance()->installTranslator(translator);
	translators.append(translator);
	++fn;
    }
#endif

    //QSet<QString> outputLanguages = config.getStringSet(CONFIG_OUTPUTLANGUAGES);

    /*
      Get the source language (Cpp) from the configuration
      and the location in the configuration file where the
      source language was set.
     */
    QString lang = config.getString(CONFIG_LANGUAGE);
    Location langLocation = config.lastLocation();

    /*
      Initialize the tree where all the parsed sources will be stored.
      The tree gets built as the source files are parsed, and then the
      documentation output is generated by traversing the tree.
     */
    Tree *tree = new Tree;
    tree->setVersion(config.getString(CONFIG_VERSION));

    /*
      By default, the only output format is HTML.
     */
    QSet<QString> outputFormats = config.getStringSet(CONFIG_OUTPUTFORMATS);
    Location outputFormatsLocation = config.lastLocation();

    /*
      Read some XML indexes containing definitions from other documentation sets.
     */
    QStringList indexFiles = config.getStringList(CONFIG_INDEXES);
    tree->readIndexes(indexFiles);

#if 0
    /*
      I think we won't beusing this...

      Read the list of DITA excluded directories.
     */
    QSet<QString> ditaExcludedDirs;
    QStringList ditaExcludedDirsList = config.getStringList("dita.metadata.excludedirs");
    foreach (const QString &t, ditaExcludedDirsList)
        ditaExcludedDirs.insert(QDir::fromNativeSeparators(t));

    if (!ditaExcludedDirs.isEmpty()) {
        QSet<QString>::iterator i = ditaExcludedDirs.begin();
        while (i != ditaExcludedDirs.end()) {
            qDebug() << "DITA EXCLUDED DIR:" << (*i);
            ++i;
        }
    }
#endif

    /*
      Read the list of excluded directories.
     */
    QSet<QString> excludedDirs;
    QStringList excludedDirsList = config.getStringList(CONFIG_EXCLUDEDIRS);
    foreach (const QString &excludeDir, excludedDirsList)
        excludedDirs.insert(QDir::fromNativeSeparators(excludeDir));

    /*
      Get all the header files: "*.ch *.h *.h++ *.hh *.hpp *.hxx"
      Put them in a set.
     */
    QSet<QString> headers = QSet<QString>::fromList(
        config.getAllFiles(CONFIG_HEADERS, CONFIG_HEADERDIRS, excludedDirs));

    /*
      Get all the source text files: "*.cpp *.qdoc *.mm"
      Put them in a set.
     */
    QSet<QString> sources = QSet<QString>::fromList(
        config.getAllFiles(CONFIG_SOURCES, CONFIG_SOURCEDIRS, excludedDirs));

    /*
      Parse each header file in the set using the appropriate parser and add it
      to the big tree.
     */
    QSet<CodeParser *> usedParsers;

    QSet<QString>::ConstIterator h = headers.begin();
    while (h != headers.end()) {
        CodeParser *codeParser = CodeParser::parserForHeaderFile(*h);
        if (codeParser) {
	    codeParser->parseHeaderFile(config.location(), *h, tree);
            usedParsers.insert(codeParser);
        }
	++h;
    }

    foreach (CodeParser *codeParser, usedParsers)
        codeParser->doneParsingHeaderFiles(tree);

    usedParsers.clear();
    /*
      Parse each source text file in the set using the appropriate parser and
      add it to the big tree.
     */
    QSet<QString>::ConstIterator s = sources.begin();
    while (s != sources.end()) {
        CodeParser *codeParser = CodeParser::parserForSourceFile(*s);
        if (codeParser) {
	    codeParser->parseSourceFile(config.location(), *s, tree);
            usedParsers.insert(codeParser);
        }
	++s;
    }

    foreach (CodeParser *codeParser, usedParsers)
        codeParser->doneParsingSourceFiles(tree);

    /*
      Now the big tree has been built from all the header and
      source files. Resolve all the class names, function names,
      targets, URLs, links, and other stuff that needs resolving.
     */
    tree->resolveGroups();
    tree->resolveTargets();

    /*
      Now the tree has been built, and all the stuff that needed
      resolving has been resolved. Now it is time to traverse
      the big tree and generate the documentation output.
     */
    QSet<QString>::ConstIterator of = outputFormats.begin();
    while (of != outputFormats.end()) {
        Generator *generator = Generator::generatorForFormat(*of);
        if (generator == 0)
            outputFormatsLocation.fatal(tr("Unknown output format '%1'")
                                        .arg(*of));
        generator->generateTree(tree);
        ++of;
    }

    /*
      Generate the XML tag file, if it was requested.
     */
    QString tagFile = config.getString(CONFIG_TAGFILE);
    if (!tagFile.isEmpty()) {
        tree->generateTagFile(tagFile);
    }

    tree->setVersion("");
    Generator::terminate();
    CodeParser::terminate();
    CodeMarker::terminate();
    Doc::terminate();
    Tokenizer::terminate();
    Location::terminate();
    QDir::setCurrent(prevCurrentDir);

#ifndef QT_NO_TRANSLATION
    qDeleteAll(translators);
#endif
#ifdef DEBUG_SHUTDOWN_CRASH    
    qDebug() << "main(): Delete tree";
#endif    
    delete tree;
#ifdef DEBUG_SHUTDOWN_CRASH    
    qDebug() << "main(): Tree deleted";
#endif
}

QT_END_NAMESPACE

int main(int argc, char **argv)
{
    QT_USE_NAMESPACE

#ifndef QT_BOOTSTRAPPED
    QCoreApplication app(argc, argv);
#endif

    /*
      Create code parsers for the languages to be parsed,
      and create a tree for C++.
     */
    CppCodeParser cppParser;
    QmlCodeParser qmlParser;
    PureDocParser docParser;

    /*
      Create code markers for plain text and C++.
     */
    PlainCodeMarker plainMarker;
    CppCodeMarker cppMarker;
    JsCodeMarker jsMarker;
    QmlCodeMarker qmlMarker;

    HtmlGenerator htmlGenerator;
    DitaXmlGenerator ditaxmlGenerator;

    QStringList qdocFiles;
    QString opt;
    int i = 1;

    while (i < argc) {
        opt = argv[i++];

	if (opt == "-help") {
	    printHelp();
	    return EXIT_SUCCESS;
	}
        else if (opt == "-version") {
	    printVersion();
	    return EXIT_SUCCESS;
	}
        else if (opt == "--") {
	    while (i < argc)
		qdocFiles.append(argv[i++]);
        }
        else if (opt.startsWith("-D")) {
            QString define = opt.mid(2);
            defines += define;
        }
        else if (opt == "-slow") {
            slow = true;
	}
        else if (opt == "-showinternal") {
            showInternal = true;
        }
        else if (opt == "-obsoletelinks") {
            obsoleteLinks = true;
        }
        else {
	    qdocFiles.append(opt);
	}
    }

	if (qdocFiles.isEmpty()) {
        printHelp();
        return EXIT_FAILURE;
    }

    /*
      Main loop.
     */
    foreach (QString qf, qdocFiles) {
        //qDebug() << "PROCESSING:" << qf;
	processQdocconfFile(qf);
    }

    qDeleteAll(trees);
    return EXIT_SUCCESS;
}

