/****************************************************************************
**
** Copyright (C) 2016 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the QtQml 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 <private/qqmljsengine_p.h>
#include <private/qqmljslexer_p.h>
#include <private/qqmljsparser_p.h>
#include <QtCore/QCoreApplication>
#include <QtCore/QStringList>
#include <QtCore/QFile>
#include <QtCore/QFileInfo>
#include <QtCore/QDir>
#include <iostream>
#include <cstdlib>

QT_BEGIN_NAMESPACE

//
// QML/JS minifier
//
namespace QQmlJS {

enum RegExpFlag {
    Global     = 0x01,
    IgnoreCase = 0x02,
    Multiline  = 0x04
};


class QmlminLexer: protected Lexer, public Directives
{
    QQmlJS::Engine _engine;
    QString _fileName;
    QString _directives;

protected:
    QVector<int> _stateStack;
    QList<int> _tokens;
    QList<QString> _tokenStrings;
    int yytoken = -1;
    QString yytokentext;

    void lex() {
        if (_tokens.isEmpty()) {
            _tokens.append(Lexer::lex());
            _tokenStrings.append(tokenText());
        }

        yytoken = _tokens.takeFirst();
        yytokentext = _tokenStrings.takeFirst();
    }

    int lookaheadToken()
    {
        if (yytoken < 0)
            lex();
        return yytoken;
    }

    void pushToken(int token)
    {
        _tokens.prepend(yytoken);
        _tokenStrings.prepend(yytokentext);
        yytoken = token;
        yytokentext = QString();
    }

public:
    QmlminLexer()
        : Lexer(&_engine), _stateStack(128) {}
    virtual ~QmlminLexer() {}

    QString fileName() const { return _fileName; }

    bool operator()(const QString &fileName, const QString &code)
    {
        int startToken = T_FEED_JS_SCRIPT;
        const QFileInfo fileInfo(fileName);
        if (fileInfo.suffix().toLower() == QLatin1String("qml"))
            startToken = T_FEED_UI_PROGRAM;
        setCode(code, /*line = */ 1, /*qmlMode = */ startToken == T_FEED_UI_PROGRAM);
        _fileName = fileName;
        _directives.clear();
        return parse(startToken);
    }

    QString directives()
    {
        return _directives;
    }

    //
    // Handle the .pragma/.import directives
    //
    void pragmaLibrary() override
    {
        _directives += QLatin1String(".pragma library\n");
    }

    void importFile(const QString &jsfile, const QString &module, int line, int column) override
    {
        _directives += QLatin1String(".import");
        _directives += QLatin1Char('"');
        _directives += quote(jsfile);
        _directives += QLatin1Char('"');
        _directives += QLatin1String("as ");
        _directives += module;
        _directives += QLatin1Char('\n');
        Q_UNUSED(line);
        Q_UNUSED(column);
    }

    void importModule(const QString &uri, const QString &version, const QString &module, int line, int column) override
    {
        _directives += QLatin1String(".import ");
        _directives += uri;
        _directives += QLatin1Char(' ');
        _directives += version;
        _directives += QLatin1String(" as ");
        _directives += module;
        _directives += QLatin1Char('\n');
        Q_UNUSED(line);
        Q_UNUSED(column);
    }

protected:
    virtual bool parse(int startToken) = 0;

    static QString quote(const QString &string)
    {
        QString quotedString;
        for (const QChar &ch : string) {
            if (ch == QLatin1Char('"'))
                quotedString += QLatin1String("\\\"");
            else {
                if (ch == QLatin1Char('\\')) quotedString += QLatin1String("\\\\");
                else if (ch == QLatin1Char('\"')) quotedString += QLatin1String("\\\"");
                else if (ch == QLatin1Char('\b')) quotedString += QLatin1String("\\b");
                else if (ch == QLatin1Char('\f')) quotedString += QLatin1String("\\f");
                else if (ch == QLatin1Char('\n')) quotedString += QLatin1String("\\n");
                else if (ch == QLatin1Char('\r')) quotedString += QLatin1String("\\r");
                else if (ch == QLatin1Char('\t')) quotedString += QLatin1String("\\t");
                else if (ch == QLatin1Char('\v')) quotedString += QLatin1String("\\v");
                else if (ch == QLatin1Char('\0')) quotedString += QLatin1String("\\0");
                else quotedString += ch;
            }
        }
        return quotedString;
    }

    bool isIdentChar(const QChar &ch) const
    {
        if (ch.isLetterOrNumber())
            return true;
        else if (ch == QLatin1Char('_') || ch == QLatin1Char('$'))
            return true;
        return false;
    }

    bool isRegExpRule(int ruleno) const
    {
        return ruleno == J_SCRIPT_REGEXPLITERAL_RULE1 ||
                ruleno == J_SCRIPT_REGEXPLITERAL_RULE2;
    }

    void handleLookaheads(int ruleno) {
        if (ruleno == J_SCRIPT_EXPRESSIONSTATEMENTLOOKAHEAD_RULE) {
            int token = lookaheadToken();
            if (token == T_LBRACE)
                pushToken(T_FORCE_BLOCK);
            else if (token == T_FUNCTION || token == T_CLASS || token == T_LET || token == T_CONST)
                pushToken(T_FORCE_DECLARATION);
        } else if (ruleno == J_SCRIPT_CONCISEBODYLOOKAHEAD_RULE) {
            int token = lookaheadToken();
            if (token == T_LBRACE)
                pushToken(T_FORCE_BLOCK);
        } else if (ruleno == J_SCRIPT_EXPORTDECLARATIONLOOKAHEAD_RULE) {
            int token = lookaheadToken();
            if (token == T_FUNCTION || token == T_CLASS)
                pushToken(T_FORCE_DECLARATION);
        }
    }

    bool scanRestOfRegExp(int ruleno, QString *restOfRegExp)
    {
        if (! scanRegExp(ruleno == J_SCRIPT_REGEXPLITERAL_RULE1 ? Lexer::NoPrefix : Lexer::EqualPrefix))
            return false;

        *restOfRegExp = regExpPattern();
        if (ruleno == J_SCRIPT_REGEXPLITERAL_RULE2) {
            Q_ASSERT(! restOfRegExp->isEmpty());
            Q_ASSERT(restOfRegExp->at(0) == QLatin1Char('='));
            *restOfRegExp = restOfRegExp->mid(1); // strip the prefix
        }
        *restOfRegExp += QLatin1Char('/');
        const RegExpFlag flags = (RegExpFlag) regExpFlags();
        if (flags & Global)
            *restOfRegExp += QLatin1Char('g');
        if (flags & IgnoreCase)
            *restOfRegExp += QLatin1Char('i');
        if (flags & Multiline)
            *restOfRegExp += QLatin1Char('m');

        if (regExpFlags() == 0) {
            // Add an extra space after the regexp literal delimiter (aka '/').
            // This will avoid possible problems when pasting tokens like `instanceof'
            // after the regexp literal.
            *restOfRegExp += QLatin1Char(' ');
        }
        return true;
    }
};


class Minify: public QmlminLexer
{
    QString _minifiedCode;
    int _maxWidth;
    int _width;

public:
    Minify(int maxWidth);

    QString minifiedCode() const;

protected:
    void append(const QString &s);
    bool parse(int startToken) override;
    void escape(const QChar &ch, QString *out);
};

Minify::Minify(int maxWidth)
    : _maxWidth(maxWidth), _width(0)
{
}

QString Minify::minifiedCode() const
{
    return _minifiedCode;
}

void Minify::append(const QString &s)
{
    if (!s.isEmpty()) {
        if (_maxWidth) {
            // Prefer not to exceed the maximum chars per line (but don't break up segments)
            int segmentLength = s.count();
            if (_width && ((_width + segmentLength) > _maxWidth)) {
                _minifiedCode.append(QLatin1Char('\n'));
                _width = 0;
            }

            _width += segmentLength;
        }

        _minifiedCode.append(s);
    }
}

void Minify::escape(const QChar &ch, QString *out)
{
    out->append(QLatin1String("\\u"));
    const QString hx = QString::number(ch.unicode(), 16);
    switch (hx.length()) {
    case 1: out->append(QLatin1String("000")); break;
    case 2: out->append(QLatin1String("00")); break;
    case 3: out->append(QLatin1Char('0')); break;
    case 4: break;
    default: Q_ASSERT(!"unreachable");
    }
    out->append(hx);
}

bool Minify::parse(int startToken)
{
    int yyaction = 0;
    int yytos = -1;
    QString assembled;

    _minifiedCode.clear();
    _tokens.append(startToken);
    _tokenStrings.append(QString());

    if (startToken == T_FEED_JS_SCRIPT) {
        // parse optional pragma directive
        DiagnosticMessage error;
        if (scanDirectives(this, &error)) {
            // append the scanned directives to the minifier code.
            append(directives());

            _tokens.append(tokenKind());
            _tokenStrings.append(tokenText());
        } else {
            std::cerr << qPrintable(fileName()) << ':' << tokenStartLine() << ':'
                << tokenStartColumn() << ": syntax error" << std::endl;
            return false;
        }
    }

    do {
        if (++yytos == _stateStack.size())
            _stateStack.resize(_stateStack.size() * 2);

        _stateStack[yytos] = yyaction;

    again:
        if (yytoken == -1 && action_index[yyaction] != -TERMINAL_COUNT)
            lex();

        yyaction = t_action(yyaction, yytoken);
        if (yyaction > 0) {
            if (yyaction == ACCEPT_STATE) {
                --yytos;
                if (!assembled.isEmpty())
                    append(assembled);
                return true;
            }

            const QChar lastChar = assembled.isEmpty() ? (_minifiedCode.isEmpty() ? QChar()
                                                                                  : _minifiedCode.at(_minifiedCode.length() - 1))
                                                       : assembled.at(assembled.length() - 1);

            if (yytoken == T_SEMICOLON) {
                assembled += QLatin1Char(';');

                append(assembled);
                assembled.clear();

            } else if (yytoken == T_PLUS || yytoken == T_MINUS || yytoken == T_PLUS_PLUS || yytoken == T_MINUS_MINUS) {
                if (lastChar == QLatin1Char(spell[yytoken][0])) {
                    // don't merge unary signs, additive expressions and postfix/prefix increments.
                    assembled += QLatin1Char(' ');
                }

                assembled += QLatin1String(spell[yytoken]);

            } else if (yytoken == T_NUMERIC_LITERAL) {
                if (isIdentChar(lastChar))
                    assembled += QLatin1Char(' ');

                if (yytokentext.startsWith('.'))
                    assembled += QLatin1Char('0');

                assembled += yytokentext;

                if (assembled.endsWith(QLatin1Char('.')))
                    assembled += QLatin1Char('0');

            } else if (yytoken == T_IDENTIFIER) {
                QString identifier = yytokentext;

                if (classify(identifier.constData(), identifier.size(), qmlMode()) != T_IDENTIFIER) {
                    // the unescaped identifier is a keyword. In this case just replace
                    // the last character of the identifier with it escape sequence.
                    const QChar ch = identifier.at(identifier.length() - 1);
                    identifier.chop(1);
                    escape(ch, &identifier);
                }

                if (isIdentChar(lastChar))
                    assembled += QLatin1Char(' ');

                assembled += identifier;

            } else if (yytoken == T_STRING_LITERAL || yytoken == T_MULTILINE_STRING_LITERAL) {
                assembled += QLatin1Char('"');
                assembled += quote(yytokentext);
                assembled += QLatin1Char('"');
            } else {
                if (isIdentChar(lastChar)) {
                    if (! yytokentext.isEmpty()) {
                        const QChar ch = yytokentext.at(0);
                        if (isIdentChar(ch))
                            assembled += QLatin1Char(' ');
                    }
                }
                assembled += yytokentext;
            }
            yytoken = -1;
        } else if (yyaction < 0) {
            const int ruleno = -yyaction - 1;
            yytos -= rhs[ruleno];

            handleLookaheads(ruleno);

            if (isRegExpRule(ruleno)) {
                QString restOfRegExp;

                if (! scanRestOfRegExp(ruleno, &restOfRegExp))
                    break; // break the loop, it wil report a syntax error

                assembled += restOfRegExp;
            }
            yyaction = nt_action(_stateStack[yytos], lhs[ruleno] - TERMINAL_COUNT);
        }
    } while (yyaction);

    const int yyerrorstate = _stateStack[yytos];

    // automatic insertion of `;'
    if (yytoken != -1 && ((t_action(yyerrorstate, T_AUTOMATIC_SEMICOLON) && canInsertAutomaticSemicolon(yytoken))
                          || t_action(yyerrorstate, T_COMPATIBILITY_SEMICOLON))) {
        _tokens.prepend(yytoken);
        _tokenStrings.prepend(yytokentext);
        yyaction = yyerrorstate;
        yytoken = T_SEMICOLON;
        goto again;
    }

    std::cerr << qPrintable(fileName()) << ':' << tokenStartLine() << ':' << tokenStartColumn()
         << ": syntax error" << std::endl;
    return false;
}


class Tokenize: public QmlminLexer
{
    QStringList _minifiedCode;

public:
    Tokenize() {}

    QStringList tokenStream() const;

protected:
    bool parse(int startToken) override;
};

QStringList Tokenize::tokenStream() const
{
    return _minifiedCode;
}

bool Tokenize::parse(int startToken)
{
    int yyaction = 0;
    int yytos = -1;

    _minifiedCode.clear();
    _tokens.append(startToken);
    _tokenStrings.append(QString());

    if (startToken == T_FEED_JS_SCRIPT) {
        // parse optional pragma directive
        DiagnosticMessage error;
        if (scanDirectives(this, &error)) {
            // append the scanned directives as one token to
            // the token stream.
            _minifiedCode.append(directives());

            _tokens.append(tokenKind());
            _tokenStrings.append(tokenText());
        } else {
            std::cerr << qPrintable(fileName()) << ':' << tokenStartLine() << ':'
                << tokenStartColumn() << ": syntax error" << std::endl;
            return false;
        }
    }

    do {
        if (++yytos == _stateStack.size())
            _stateStack.resize(_stateStack.size() * 2);

        _stateStack[yytos] = yyaction;

    again:
        if (yytoken == -1 && action_index[yyaction] != -TERMINAL_COUNT)
            lex();

        yyaction = t_action(yyaction, yytoken);
        if (yyaction > 0) {
            if (yyaction == ACCEPT_STATE) {
                --yytos;
                return true;
            }

            if (yytoken == T_SEMICOLON)
                _minifiedCode += QLatin1String(";");
            else
                _minifiedCode += yytokentext;

            yytoken = -1;
        } else if (yyaction < 0) {
            const int ruleno = -yyaction - 1;
            yytos -= rhs[ruleno];

            handleLookaheads(ruleno);

            if (isRegExpRule(ruleno)) {
                QString restOfRegExp;

                if (! scanRestOfRegExp(ruleno, &restOfRegExp))
                    break; // break the loop, it wil report a syntax error

                _minifiedCode.last().append(restOfRegExp);
            }

            yyaction = nt_action(_stateStack[yytos], lhs[ruleno] - TERMINAL_COUNT);
        }
    } while (yyaction);

    const int yyerrorstate = _stateStack[yytos];

    // automatic insertion of `;'
    if (yytoken != -1 && ((t_action(yyerrorstate, T_AUTOMATIC_SEMICOLON) && canInsertAutomaticSemicolon(yytoken))
                          || t_action(yyerrorstate, T_COMPATIBILITY_SEMICOLON))) {
        _tokens.prepend(yytoken);
        _tokenStrings.prepend(yytokentext);
        yyaction = yyerrorstate;
        yytoken = T_SEMICOLON;
        goto again;
    }

    std::cerr << qPrintable(fileName()) << ':' << tokenStartLine() << ':'
        << tokenStartColumn() << ": syntax error" << std::endl;
    return false;
}

} // end of QQmlJS namespace

static void usage(bool showHelp = false)
{
    std::cerr << "Usage: qmlmin [options] file" << std::endl;

    if (showHelp) {
        std::cerr << " Removes comments and layout characters" << std::endl
                  << " The options are:" << std::endl
                  << "  -o<file>                write output to file rather than stdout" << std::endl
                  << "  -v --verify-only        just run the verifier, no output" << std::endl
                  << "  -w<width>               restrict line characters to width" << std::endl
                  << "  -h                      display this output" << std::endl;
    }
}

int runQmlmin(int argc, char *argv[])
{
    QCoreApplication app(argc, argv);
    QCoreApplication::setApplicationVersion(QLatin1String(QT_VERSION_STR));

    const QStringList args = app.arguments();

    QString fileName;
    QString outputFile;
    bool verifyOnly = false;

    // By default ensure the output character width is less than 16-bits (pass 0 to disable)
    int width = USHRT_MAX;

    int index = 1;
    while (index < args.size()) {
        const QString arg = args.at(index++);
        const QString next = index < args.size() ? args.at(index) : QString();

        if (arg == QLatin1String("-h") || arg == QLatin1String("--help")) {
            usage(/*showHelp*/ true);
            return 0;
        } else if (arg == QLatin1String("-v") || arg == QLatin1String("--verify-only")) {
            verifyOnly = true;
        } else if (arg == QLatin1String("-o")) {
            if (next.isEmpty()) {
                std::cerr << "qmlmin: argument to '-o' is missing" << std::endl;
                return EXIT_FAILURE;
            } else {
                outputFile = next;
                ++index; // consume the next argument
            }
        } else if (arg.startsWith(QLatin1String("-o"))) {
            outputFile = arg.mid(2);

            if (outputFile.isEmpty()) {
                std::cerr << "qmlmin: argument to '-o' is missing" << std::endl;
                return EXIT_FAILURE;
            }
        } else if (arg == QLatin1String("-w")) {
            if (next.isEmpty()) {
                std::cerr << "qmlmin: argument to '-w' is missing" << std::endl;
                return EXIT_FAILURE;
            } else {
                bool ok;
                width = next.toInt(&ok);

                if (!ok) {
                    std::cerr << "qmlmin: argument to '-w' is invalid" << std::endl;
                    return EXIT_FAILURE;
                }

                ++index; // consume the next argument
            }
        } else if (arg.startsWith(QLatin1String("-w"))) {
            bool ok;
            width = arg.midRef(2).toInt(&ok);

            if (!ok) {
                std::cerr << "qmlmin: argument to '-w' is invalid" << std::endl;
                return EXIT_FAILURE;
            }
        } else {
            const bool isInvalidOpt = arg.startsWith(QLatin1Char('-'));
            if (! isInvalidOpt && fileName.isEmpty())
                fileName = arg;
            else {
                usage(/*show help*/ isInvalidOpt);
                if (isInvalidOpt)
                    std::cerr << "qmlmin: invalid option '" << qPrintable(arg) << '\'' << std::endl;
                else
                    std::cerr << "qmlmin: too many input files specified" << std::endl;
                return EXIT_FAILURE;
            }
        }
    }

    if (fileName.isEmpty()) {
        usage();
        return 0;
    }

    QFile file(fileName);
    if (! file.open(QFile::ReadOnly)) {
        std::cerr << "qmlmin: '" << qPrintable(fileName) << "' no such file or directory" << std::endl;
        return EXIT_FAILURE;
    }

    const QString code = QString::fromUtf8(file.readAll()); // QML files are UTF-8 encoded.
    file.close();

    QQmlJS::Minify minify(width);
    if (! minify(fileName, code)) {
        std::cerr << "qmlmin: cannot minify '" << qPrintable(fileName) << "' (not a valid QML/JS file)" << std::endl;
        return EXIT_FAILURE;
    }

    //
    // verify the output
    //
    QQmlJS::Minify secondMinify(width);
    if (! secondMinify(fileName, minify.minifiedCode()) || secondMinify.minifiedCode() != minify.minifiedCode()) {
        std::cerr << "qmlmin: cannot minify '" << qPrintable(fileName) << '\'' << std::endl;
        return EXIT_FAILURE;
    }

    QQmlJS::Tokenize originalTokens, minimizedTokens;
    originalTokens(fileName, code);
    minimizedTokens(fileName, minify.minifiedCode());

    if (originalTokens.tokenStream().size() != minimizedTokens.tokenStream().size()) {
        std::cerr << "qmlmin: cannot minify '" << qPrintable(fileName) << '\'' << std::endl;
        return EXIT_FAILURE;
    }

    if (! verifyOnly) {
        if (outputFile.isEmpty()) {
            const QByteArray chars = minify.minifiedCode().toUtf8();
            std::cout << chars.constData();
        } else {
            QFile file(outputFile);
            if (! file.open(QFile::WriteOnly)) {
                std::cerr << "qmlmin: cannot minify '" << qPrintable(fileName) << "' (permission denied)" << std::endl;
                return EXIT_FAILURE;
            }

            file.write(minify.minifiedCode().toUtf8());
            file.close();
        }
    }

    return 0;
}

QT_END_NAMESPACE

int main(int argc, char **argv)
{
    return QT_PREPEND_NAMESPACE(runQmlmin(argc, argv));
}
