/****************************************************************************
**
** Copyright (C) 2018 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:LGPL$
** 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 Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 3 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL3 included in the
** packaging of this file. Please review the following information to
** ensure the GNU Lesser General Public License version 3 requirements
** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 2.0 or (at your option) the GNU General
** Public license version 3 or any later version approved by the KDE Free
** Qt Foundation. The licenses are as published by the Free Software
** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
** 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-2.0.html and
** https://www.gnu.org/licenses/gpl-3.0.html.
**
** $QT_END_LICENSE$
**
****************************************************************************/


#include "qv4module_p.h"

#include <private/qv4mm_p.h>
#include <private/qv4vme_moth_p.h>
#include <private/qv4context_p.h>
#include <private/qv4symbol_p.h>
#include <private/qv4identifiertable_p.h>

#include <QScopeGuard>

using namespace QV4;

DEFINE_OBJECT_VTABLE(Module);

void Heap::Module::init(ExecutionEngine *engine, ExecutableCompilationUnit *moduleUnit)
{
    Object::init();

    // This is a back pointer and there is no need to call addref() on the unit, because the unit
    // owns this object instead.
    unit = moduleUnit;
    self.set(engine, this);

    Function *moduleFunction = unit->runtimeFunctions[unit->unitData()->indexOfRootFunction];

    const uint locals = moduleFunction->compiledFunction->nLocals;
    const size_t requiredMemory = sizeof(QV4::CallContext::Data) - sizeof(Value) + sizeof(Value) * locals;
    scope.set(engine, engine->memoryManager->allocManaged<QV4::CallContext>(requiredMemory, moduleFunction->internalClass));
    scope->init();
    scope->outer.set(engine, engine->rootContext()->d());
    scope->locals.size = locals;
    scope->locals.alloc = locals;
    scope->nArgs = 0;

    // Prepare the temporal dead zone
    scope->setupLocalTemporalDeadZone(moduleFunction->compiledFunction);

    Scope valueScope(engine);

    // It's possible for example to re-export an import, for example:
    //     import * as foo from "./bar.js"
    //     export { foo }
    // Since we don't add imports to the locals, it won't be found typically.
    // Except now we add imports at the end of the internal class in the index
    // space past the locals, so that resolveExport can find it.
    {
        Scoped<QV4::InternalClass> ic(valueScope, scope->internalClass);

        for (uint i = 0; i < unit->data->importEntryTableSize; ++i) {
            const CompiledData::ImportEntry &import = unit->data->importEntryTable()[i];
            ic = ic->addMember(engine->identifierTable->asPropertyKey(unit->runtimeStrings[import.localName]), Attr_NotConfigurable);
        }
        scope->internalClass.set(engine, ic->d());
    }


    Scoped<QV4::Module> This(valueScope, this);
    ScopedString name(valueScope, engine->newString(QStringLiteral("Module")));
    This->insertMember(engine->symbol_toStringTag(), name, Attr_ReadOnly);
    This->setPrototypeUnchecked(nullptr);
}

void Module::evaluate()
{
    if (d()->evaluated)
        return;
    d()->evaluated = true;

    ExecutableCompilationUnit *unit = d()->unit;

    unit->evaluateModuleRequests();

    ExecutionEngine *v4 = engine();
    Function *moduleFunction = unit->runtimeFunctions[unit->data->indexOfRootFunction];
    CppStackFrame frame;
    frame.init(v4, moduleFunction, nullptr, 0);
    frame.setupJSFrame(v4->jsStackTop, Value::undefinedValue(), d()->scope,
                       Value::undefinedValue(), Value::undefinedValue());

    frame.push();
    v4->jsStackTop += frame.requiredJSStackFrameSize();
    auto frameCleanup = qScopeGuard([&frame]() {
        frame.pop();
    });
    Moth::VME::exec(&frame, v4);
}

const Value *Module::resolveExport(PropertyKey id) const
{
    if (d()->unit->isESModule()) {
        if (!id.isString())
            return nullptr;
        Scope scope(engine());
        ScopedString name(scope, id.asStringOrSymbol());
        return d()->unit->resolveExport(name);
    } else {
        InternalClassEntry entry = d()->scope->internalClass->find(id);
        if (entry.isValid())
            return &d()->scope->locals[entry.index];
        return nullptr;
    }
}

ReturnedValue Module::virtualGet(const Managed *m, PropertyKey id, const Value *receiver, bool *hasProperty)
{
    if (id.isSymbol())
        return Object::virtualGet(m, id, receiver, hasProperty);

    const Module *module = static_cast<const Module *>(m);
    const Value *v = module->resolveExport(id);
    if (hasProperty)
        *hasProperty = v != nullptr;
    if (!v)
        return Encode::undefined();
    if (v->isEmpty()) {
        Scope scope(m->engine());
        ScopedValue propName(scope, id.toStringOrSymbol(scope.engine));
        return scope.engine->throwReferenceError(propName);
    }
    return v->asReturnedValue();
}

PropertyAttributes Module::virtualGetOwnProperty(const Managed *m, PropertyKey id, Property *p)
{
    if (id.isSymbol())
        return Object::virtualGetOwnProperty(m, id, p);

    const Module *module = static_cast<const Module *>(m);
    const Value *v = module->resolveExport(id);
    if (!v) {
        if (p)
            p->value = Encode::undefined();
        return Attr_Invalid;
    }
    if (p)
        p->value = v->isEmpty() ? Encode::undefined() : v->asReturnedValue();
    if (v->isEmpty()) {
        Scope scope(m->engine());
        ScopedValue propName(scope, id.toStringOrSymbol(scope.engine));
        scope.engine->throwReferenceError(propName);
    }
    return Attr_Data | Attr_NotConfigurable;
}

bool Module::virtualHasProperty(const Managed *m, PropertyKey id)
{
    if (id.isSymbol())
        return Object::virtualHasProperty(m, id);

    const Module *module = static_cast<const Module *>(m);
    const Value *v = module->resolveExport(id);
    return v != nullptr;
}

bool Module::virtualPreventExtensions(Managed *)
{
    return true;
}

bool Module::virtualDefineOwnProperty(Managed *, PropertyKey, const Property *, PropertyAttributes)
{
    return false;
}

bool Module::virtualPut(Managed *, PropertyKey, const Value &, Value *)
{
    return false;
}

bool Module::virtualDeleteProperty(Managed *m, PropertyKey id)
{
    if (id.isSymbol())
        return Object::virtualDeleteProperty(m, id);
    const Module *module = static_cast<const Module *>(m);
    const Value *v = module->resolveExport(id);
    if (v)
        return false;
    return true;
}

struct ModuleNamespaceIterator : ObjectOwnPropertyKeyIterator
{
    QStringList exportedNames;
    int exportIndex = 0;
    ModuleNamespaceIterator(const QStringList &names) : exportedNames(names) {}
    ~ModuleNamespaceIterator() override = default;
    PropertyKey next(const Object *o, Property *pd = nullptr, PropertyAttributes *attrs = nullptr) override;

};

PropertyKey ModuleNamespaceIterator::next(const Object *o, Property *pd, PropertyAttributes *attrs)
{
    const Module *module = static_cast<const Module *>(o);
    if (exportIndex < exportedNames.count()) {
        if (attrs)
            *attrs = Attr_Data;
        Scope scope(module->engine());
        ScopedString exportName(scope, scope.engine->newString(exportedNames.at(exportIndex)));
        exportIndex++;
        const Value *v = module->resolveExport(exportName->toPropertyKey());
        if (pd) {
            if (v->isEmpty())
                scope.engine->throwReferenceError(exportName);
            else
                pd->value = *v;
        }
        return exportName->toPropertyKey();
    }
    return ObjectOwnPropertyKeyIterator::next(o, pd, attrs);
}

OwnPropertyKeyIterator *Module::virtualOwnPropertyKeys(const Object *o, Value *target)
{
    const Module *module = static_cast<const Module *>(o);
    *target = *o;

    QStringList names;
    if (module->d()->unit->isESModule()) {
        names = module->d()->unit->exportedNames();
    } else {
        Heap::InternalClass *scopeClass = module->d()->scope->internalClass;
        for (uint i = 0; i < scopeClass->size; ++i)
            names << scopeClass->keyAt(i);
    }

    return new ModuleNamespaceIterator(names);
}

Heap::Object *Module::virtualGetPrototypeOf(const Managed *)
{
    return nullptr;
}

bool Module::virtualSetPrototypeOf(Managed *, const Object *proto)
{
    return proto == nullptr;
}

bool Module::virtualIsExtensible(const Managed *)
{
    return false;
}
