/****************************************************************************
**
** Copyright (C) 2016 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the V4VM 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/qv4object_p.h"
#include "private/qv4runtime_p.h"
#include "private/qv4functionobject_p.h"
#include "private/qv4errorobject_p.h"
#include "private/qv4globalobject_p.h"
#include "private/qv4codegen_p.h"
#include "private/qv4objectproto_p.h"
#include "private/qv4mm_p.h"
#include "private/qv4context_p.h"
#include "private/qv4script_p.h"
#include "private/qv4string_p.h"
#include "private/qv4module_p.h"
#include "private/qqmlbuiltinfunctions_p.h"

#include <QtCore/QCoreApplication>
#include <QtCore/QFile>
#include <QtCore/QFileInfo>
#include <QtCore/QDateTime>
#include <private/qqmljsengine_p.h>
#include <private/qqmljslexer_p.h>
#include <private/qqmljsparser_p.h>
#include <private/qqmljsast_p.h>

#include <iostream>

static void showException(QV4::ExecutionContext *ctx, const QV4::Value &exception, const QV4::StackTrace &trace)
{
    QV4::Scope scope(ctx);
    QV4::ScopedValue ex(scope, exception);
    QV4::ErrorObject *e = ex->as<QV4::ErrorObject>();
    if (!e) {
        std::cerr << "Uncaught exception: " << qPrintable(ex->toQString()) << std::endl;
    } else {
        std::cerr << "Uncaught exception: " << qPrintable(e->toQStringNoThrow()) << std::endl;
    }

    for (const QV4::StackFrame &frame : trace) {
        std::cerr << "    at " << qPrintable(frame.function) << " (" << qPrintable(frame.source);
        if (frame.line >= 0)
            std::cerr << ':' << frame.line;
        std::cerr << ')' << std::endl;
    }
}

int main(int argc, char *argv[])
{
    QCoreApplication app(argc, argv);
    QCoreApplication::setApplicationVersion(QLatin1String(QT_VERSION_STR));
    QStringList args = app.arguments();
    args.removeFirst();

    bool runAsQml = false;
    bool runAsModule = false;
    bool cache = false;

    if (!args.isEmpty()) {
        if (args.constFirst() == QLatin1String("--jit")) {
            qputenv("QV4_JIT_CALL_THRESHOLD", QByteArray("0"));
            args.removeFirst();
        }
        if (args.constFirst() == QLatin1String("--interpret")) {
            qputenv("QV4_FORCE_INTERPRETER", QByteArray("1"));
            args.removeFirst();
        }

        if (args.constFirst() == QLatin1String("--qml")) {
            runAsQml = true;
            args.removeFirst();
        }

        if (args.constFirst() == QLatin1String("--module")) {
            runAsModule = true;
            args.removeFirst();
        }

        if (args.constFirst() == QLatin1String("--cache")) {
            cache = true;
            args.removeFirst();
        }

        if (args.constFirst() == QLatin1String("--help")) {
            std::cerr << "Usage: qmljs [|--jit|--interpret|--qml] file..." << std::endl;
            return EXIT_SUCCESS;
        }
    }

    QV4::ExecutionEngine vm;

    QV4::Scope scope(&vm);
    QV4::ScopedContext ctx(scope, vm.rootContext());

    QV4::GlobalExtensions::init(vm.globalObject, QJSEngine::ConsoleExtension | QJSEngine::GarbageCollectionExtension);

    for (const QString &fn : qAsConst(args)) {
        QV4::ScopedValue result(scope);
        if (runAsModule) {
            auto moduleUnit = vm.loadModule(QUrl::fromLocalFile(QFileInfo(fn).absoluteFilePath()));
            if (moduleUnit) {
                if (moduleUnit->instantiate(&vm))
                    moduleUnit->evaluate();
            } else {
                vm.throwError(QStringLiteral("Could not load module file"));
            }
        } else {
            QFile file(fn);
            if (!file.open(QFile::ReadOnly)) {
                std::cerr << "Error: cannot open file " << fn.toUtf8().constData() << std::endl;
                return EXIT_FAILURE;
            }
            QScopedPointer<QV4::Script> script;
            if (cache && QFile::exists(fn + QLatin1Char('c'))) {
                QQmlRefPointer<QV4::ExecutableCompilationUnit> unit
                        = QV4::ExecutableCompilationUnit::create();
                QString error;
                if (unit->loadFromDisk(QUrl::fromLocalFile(fn), QFileInfo(fn).lastModified(), &error)) {
                    script.reset(new QV4::Script(&vm, nullptr, unit));
                } else {
                    std::cout << "Error loading" << qPrintable(fn) << "from disk cache:" << qPrintable(error) << std::endl;
                }
            }
            if (!script) {
                QByteArray ba = file.readAll();
                const QString code = QString::fromUtf8(ba.constData(), ba.length());
                file.close();

                script.reset(new QV4::Script(ctx, QV4::Compiler::ContextType::Global, code, fn));
                script->parseAsBinding = runAsQml;
                script->parse();
            }
            if (!scope.engine->hasException) {
                const auto unit = script->compilationUnit;
                if (cache && unit && !(unit->unitData()->flags & QV4::CompiledData::Unit::StaticData)) {
                    if (unit->unitData()->sourceTimeStamp == 0) {
                        const_cast<QV4::CompiledData::Unit*>(unit->unitData())->sourceTimeStamp = QFileInfo(fn).lastModified().toMSecsSinceEpoch();
                    }
                    QString saveError;
                    if (!unit->saveToDisk(QUrl::fromLocalFile(fn), &saveError)) {
                        std::cout << "Error saving JS cache file: " << qPrintable(saveError) << std::endl;
                    }
                }
//                QElapsedTimer t; t.start();
                result = script->run();
//                std::cout << t.elapsed() << " ms. elapsed" << std::endl;
            }
        }
        if (scope.engine->hasException) {
            QV4::StackTrace trace;
            QV4::ScopedValue ex(scope, scope.engine->catchException(&trace));
            showException(ctx, ex, trace);
            return EXIT_FAILURE;
        }
        if (!result->isUndefined()) {
            if (! qgetenv("SHOW_EXIT_VALUE").isEmpty())
                std::cout << "exit value: " << qPrintable(result->toQString()) << std::endl;
        }
    }

    return EXIT_SUCCESS;
}
