/****************************************************************************
**
** 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 Qt Linguist 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$
**
****************************************************************************/

#include "lupdate.h"

#include <translator.h>

#include <QtCore/QDebug>
#include <QtCore/QFile>
#include <QtCore/QString>

#include "parser/qdeclarativejsengine_p.h"
#include "parser/qdeclarativejsparser_p.h"
#include "parser/qdeclarativejslexer_p.h"
#include "parser/qdeclarativejsnodepool_p.h"
#include "parser/qdeclarativejsastvisitor_p.h"
#include "parser/qdeclarativejsast_p.h"

#include <QCoreApplication>
#include <QFile>
#include <QFileInfo>
#include <QtDebug>
#include <QStringList>

#include <iostream>
#include <cstdlib>

QT_BEGIN_NAMESPACE

class LU {
    Q_DECLARE_TR_FUNCTIONS(LUpdate)
};

using namespace QDeclarativeJS;

class Comment
{
public:
    Comment() : lastLine(-1) {}
    QString extracomment;
    QString msgid;
    TranslatorMessage::ExtraData extra;
    QString sourcetext;
    int lastLine;

    bool isValid() const
    { return !extracomment.isEmpty() || !msgid.isEmpty() || !sourcetext.isEmpty() || !extra.isEmpty(); }
};

class FindTrCalls: protected AST::Visitor
{
public:
    void operator()(Translator *translator, const QString &fileName, AST::Node *node)
    {
        m_translator = translator;
        m_fileName = fileName;
        m_component = QFileInfo(fileName).baseName();   //matches qsTr usage in QScriptEngine
        accept(node);
    }

    QList<Comment> comments;

protected:
    using AST::Visitor::visit;
    using AST::Visitor::endVisit;

    void accept(AST::Node *node)
    { AST::Node::acceptChild(node, this); }

    virtual void endVisit(AST::CallExpression *node)
    {
        m_bSource.clear();
        if (AST::IdentifierExpression *idExpr = AST::cast<AST::IdentifierExpression *>(node->base)) {
            if (idExpr->name->asString() == QLatin1String("qsTr") ||
                idExpr->name->asString() == QLatin1String("QT_TR_NOOP")) {
                if (!node->arguments)
                    return;
                AST::BinaryExpression *binary = AST::cast<AST::BinaryExpression *>(node->arguments->expression);
                if (binary) {
                    if (!createString(binary))
                        m_bSource.clear();
                }
                AST::StringLiteral *literal = AST::cast<AST::StringLiteral *>(node->arguments->expression);
                if (literal || !m_bSource.isEmpty()) {
                    const QString source = literal ? literal->value->asString() : m_bSource;

                    QString comment;
                    bool plural = false;
                    AST::ArgumentList *commentNode = node->arguments->next;
                    if (commentNode && AST::cast<AST::StringLiteral *>(commentNode->expression)) {
                        literal = AST::cast<AST::StringLiteral *>(commentNode->expression);
                        comment = literal->value->asString();

                        AST::ArgumentList *nNode = commentNode->next;
                        if (nNode)
                            plural = true;
                    }

                    QString id;
                    QString extracomment;
                    TranslatorMessage::ExtraData extra;
                    Comment scomment = findComment(node->firstSourceLocation().startLine);
                    if (scomment.isValid()) {
                        extracomment = scomment.extracomment;
                        extra = scomment.extra;
                        id = scomment.msgid;
                    }

                    TranslatorMessage msg(m_component, source,
                        comment, QString(), m_fileName,
                        node->firstSourceLocation().startLine, QStringList(),
                        TranslatorMessage::Unfinished, plural);
                    msg.setExtraComment(extracomment.simplified());
                    msg.setId(id);
                    msg.setExtras(extra);
                    m_translator->extend(msg);
                }
            } else if (idExpr->name->asString() == QLatin1String("qsTranslate") ||
                       idExpr->name->asString() == QLatin1String("QT_TRANSLATE_NOOP")) {
                if (node->arguments && AST::cast<AST::StringLiteral *>(node->arguments->expression)) {
                    AST::StringLiteral *literal = AST::cast<AST::StringLiteral *>(node->arguments->expression);
                    const QString context = literal->value->asString();

                    QString source;
                    QString comment;
                    bool plural = false;
                    AST::ArgumentList *sourceNode = node->arguments->next;
                    if (!sourceNode)
                        return;
                    literal = AST::cast<AST::StringLiteral *>(sourceNode->expression);
                    AST::BinaryExpression *binary = AST::cast<AST::BinaryExpression *>(sourceNode->expression);
                    if (binary) {
                        if (!createString(binary))
                            m_bSource.clear();
                    }
                    if (!literal && m_bSource.isEmpty())
                        return;

                    QString id;
                    QString extracomment;
                    TranslatorMessage::ExtraData extra;
                    Comment scomment = findComment(node->firstSourceLocation().startLine);
                    if (scomment.isValid()) {
                        extracomment = scomment.extracomment;
                        extra = scomment.extra;
                        id = scomment.msgid;
                    }

                    source = literal ? literal->value->asString() : m_bSource;
                    AST::ArgumentList *commentNode = sourceNode->next;
                    if (commentNode && AST::cast<AST::StringLiteral *>(commentNode->expression)) {
                        literal = AST::cast<AST::StringLiteral *>(commentNode->expression);
                        comment = literal->value->asString();

                        AST::ArgumentList *nNode = commentNode->next;
                        if (nNode)
                            plural = true;
                    }

                    TranslatorMessage msg(context, source,
                        comment, QString(), m_fileName,
                        node->firstSourceLocation().startLine, QStringList(),
                        TranslatorMessage::Unfinished, plural);
                    msg.setExtraComment(extracomment.simplified());
                    msg.setId(id);
                    msg.setExtras(extra);
                    m_translator->extend(msg);
                }
            } else if (idExpr->name->asString() == QLatin1String("qsTrId") ||
                       idExpr->name->asString() == QLatin1String("QT_TRID_NOOP")) {
                if (!node->arguments)
                    return;

                AST::StringLiteral *literal = AST::cast<AST::StringLiteral *>(node->arguments->expression);
                if (literal) {

                    QString extracomment;
                    QString sourcetext;
                    TranslatorMessage::ExtraData extra;
                    Comment comment = findComment(node->firstSourceLocation().startLine);
                    if (comment.isValid()) {
                        extracomment = comment.extracomment;
                        sourcetext = comment.sourcetext;
                        extra = comment.extra;
                    }

                    const QString id = literal->value->asString();
                    bool plural = node->arguments->next;

                    TranslatorMessage msg(QString(), sourcetext,
                        QString(), QString(), m_fileName,
                        node->firstSourceLocation().startLine, QStringList(),
                        TranslatorMessage::Unfinished, plural);
                    msg.setExtraComment(extracomment.simplified());
                    msg.setId(id);
                    msg.setExtras(extra);
                    m_translator->extend(msg);
                }
            }
        }
    }

private:
    bool createString(AST::BinaryExpression *b)
    {
        if (!b || b->op != 0)
            return false;
        AST::BinaryExpression *l = AST::cast<AST::BinaryExpression *>(b->left);
        AST::BinaryExpression *r = AST::cast<AST::BinaryExpression *>(b->right);
        AST::StringLiteral *ls = AST::cast<AST::StringLiteral *>(b->left);
        AST::StringLiteral *rs = AST::cast<AST::StringLiteral *>(b->right);
        if ((!l && !ls) || (!r && !rs))
            return false;
        if (l) {
            if (!createString(l))
                return false;
        } else
            m_bSource.prepend(ls->value->asString());

        if (r) {
            if (!createString(r))
                return false;
        } else
            m_bSource.append(rs->value->asString());

        return true;
    }

    Comment findComment(int loc)
    {
        if (comments.isEmpty())
            return Comment();

        int i = 0;
        int commentLoc = comments.at(i).lastLine;
        while (commentLoc <= loc) {
            if (commentLoc == loc)
                return comments.at(i);
            if (i == comments.count()-1)
                break;
            commentLoc = comments.at(++i).lastLine;
        }
        return Comment();
    }

    Translator *m_translator;
    QString m_fileName;
    QString m_component;
    QString m_bSource;
};

QString createErrorString(const QString &filename, const QString &code, Parser &parser)
{
    // print out error
    QStringList lines = code.split(QLatin1Char('\n'));
    lines.append(QLatin1String("\n")); // sentinel.
    QString errorString;

    foreach (const DiagnosticMessage &m, parser.diagnosticMessages()) {

        if (m.isWarning())
            continue;

        QString error = filename + QLatin1Char(':') + QString::number(m.loc.startLine)
                        + QLatin1Char(':') + QString::number(m.loc.startColumn) + QLatin1String(": error: ")
                        + m.message + QLatin1Char('\n');

        int line = 0;
        if (m.loc.startLine > 0)
            line = m.loc.startLine - 1;

        const QString textLine = lines.at(line);

        error += textLine + QLatin1Char('\n');

        int column = m.loc.startColumn - 1;
        if (column < 0)
            column = 0;

        column = qMin(column, textLine.length());

        for (int i = 0; i < column; ++i) {
            const QChar ch = textLine.at(i);
            if (ch.isSpace())
                error += ch.unicode();
            else
                error += QLatin1Char(' ');
        }
        error += QLatin1String("^\n");
        errorString += error;
    }
    return errorString;
}

bool processComment(const QChar *chars, int length, Comment &comment)
{
    // Try to match the logic of the QtScript parser.
    if (!length)
        return comment.isValid();
    if (*chars == QLatin1Char(':') && chars[1].isSpace()) {
        comment.extracomment += QString(chars+1, length-1);
    } else if (*chars == QLatin1Char('=') && chars[1].isSpace()) {
        comment.msgid = QString(chars+2, length-2).simplified();
    } else if (*chars == QLatin1Char('~') && chars[1].isSpace()) {
        QString text = QString(chars+2, length-2).trimmed();
        int k = text.indexOf(QLatin1Char(' '));
        if (k > -1)
            comment.extra.insert(text.left(k), text.mid(k + 1).trimmed());
    } else if (*chars == QLatin1Char('%') && chars[1].isSpace()) {
        comment.sourcetext.reserve(comment.sourcetext.length() + length-2);
        ushort *ptr = (ushort *)comment.sourcetext.data() + comment.sourcetext.length();
        int p = 2, c;
        forever {
            if (p >= length)
                break;
            c = chars[p++].unicode();
            if (isspace(c))
                continue;
            if (c != '"')
                break;
            forever {
                if (p >= length)
                    break;
                c = chars[p++].unicode();
                if (c == '"')
                    break;
                if (c == '\\') {
                    if (p >= length)
                        break;
                    c = chars[p++].unicode();
                    if (c == '\n')
                        break;
                    *ptr++ = '\\';
                }
                *ptr++ = c;
            }
        }
        comment.sourcetext.resize(ptr - (ushort *)comment.sourcetext.data());
    }
    return comment.isValid();
}

bool loadQml(Translator &translator, const QString &filename, ConversionData &cd)
{
    cd.m_sourceFileName = filename;
    QFile file(filename);
    if (!file.open(QIODevice::ReadOnly)) {
        cd.appendError(LU::tr("Cannot open %1: %2").arg(filename, file.errorString()));
        return false;
    }

    const QString code = QTextStream(&file).readAll();

    Engine driver;
    Parser parser(&driver);

    NodePool nodePool(filename, &driver);
    driver.setNodePool(&nodePool);

    Lexer lexer(&driver);
    lexer.setCode(code, /*line = */ 1);
    driver.setLexer(&lexer);

    if (parser.parse()) {
        FindTrCalls trCalls;

        // build up a list of comments that contain translation information.
        for (int i = 0; i < driver.comments().size(); ++i) {
            AST::SourceLocation loc = driver.comments().at(i);
            QString commentStr = code.mid(loc.offset, loc.length);

            if (trCalls.comments.isEmpty() || trCalls.comments.last().lastLine != int(loc.startLine)) {
                Comment comment;
                comment.lastLine = loc.startLine+1;
                if (processComment(commentStr.constData(), commentStr.length(), comment))
                    trCalls.comments.append(comment);
            } else {
                Comment &lastComment = trCalls.comments.last();
                lastComment.lastLine += 1;
                processComment(commentStr.constData(), commentStr.length(), lastComment);
            }
        }

        //find all tr calls in the code
        trCalls(&translator, filename, parser.ast());
    } else {
        QString error = createErrorString(filename, code, parser);
        cd.appendError(error);
        return false;
    }
    return true;
}

QT_END_NAMESPACE
