/****************************************************************************
**
** Copyright (C) 2015 The Qt Company Ltd.
** Contact: http://www.qt.io/licensing/
**
** This file is part of the QtScript module of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL-ONLY$
** 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.
**
** If you have questions regarding the use of this file, please contact
** us via http://www.qt.io/contact-us/.
**
** $QT_END_LICENSE$
**
****************************************************************************/

#include "config.h"
#include "qscriptclassobject_p.h"

#include "../api/qscriptengine.h"
#include "../api/qscriptengine_p.h"
#include "../api/qscriptcontext.h"
#include "../api/qscriptcontext_p.h"
#include "../api/qscriptclass.h"
#include "../api/qscriptclasspropertyiterator.h"

#include "Error.h"
#include "PropertyNameArray.h"

Q_DECLARE_METATYPE(QScriptContext*)
Q_DECLARE_METATYPE(QScriptValue)
Q_DECLARE_METATYPE(QScriptValueList)

QT_BEGIN_NAMESPACE

namespace QScript
{

ClassObjectDelegate::ClassObjectDelegate(QScriptClass *scriptClass)
    : m_scriptClass(scriptClass)
{
}

ClassObjectDelegate::~ClassObjectDelegate()
{
}

QScriptObjectDelegate::Type ClassObjectDelegate::type() const
{
    return ClassObject;
}

bool ClassObjectDelegate::getOwnPropertySlot(QScriptObject* object,
                                             JSC::ExecState *exec,
                                             const JSC::Identifier &propertyName,
                                             JSC::PropertySlot &slot)
{
    QScriptEnginePrivate *engine = scriptEngineFromExec(exec);
    QScript::SaveFrameHelper saveFrame(engine, exec);
    // for compatibility with the old back-end, normal JS properties
    // are queried first.
    if (QScriptObjectDelegate::getOwnPropertySlot(object, exec, propertyName, slot))
        return true;

    QScriptValue scriptObject = engine->scriptValueFromJSCValue(object);
    QScriptString scriptName;
    QScriptStringPrivate scriptName_d(engine, propertyName, QScriptStringPrivate::StackAllocated);
    QScriptStringPrivate::init(scriptName, &scriptName_d);
    uint id = 0;
    QScriptClass::QueryFlags flags = m_scriptClass->queryProperty(
        scriptObject, scriptName, QScriptClass::HandlesReadAccess, &id);
    if (flags & QScriptClass::HandlesReadAccess) {
        QScriptValue value = m_scriptClass->property(scriptObject, scriptName, id);
        if (!value.isValid()) {
            // The class claims to have the property, but returned an invalid
            // value. Silently convert to undefined to avoid the invalid value
            // "escaping" into JS.
            value = QScriptValue(QScriptValue::UndefinedValue);
        }
        slot.setValue(engine->scriptValueToJSCValue(value));
        return true;
    }
    return false;
}

bool ClassObjectDelegate::getOwnPropertyDescriptor(QScriptObject *object,
                                                   JSC::ExecState *exec,
                                                   const JSC::Identifier &propertyName,
                                                   JSC::PropertyDescriptor &descriptor)
{
    QScriptEnginePrivate *engine = scriptEngineFromExec(exec);
    QScript::SaveFrameHelper saveFrame(engine, exec);
    // for compatibility with the old back-end, normal JS properties
    // are queried first.
    if (QScriptObjectDelegate::getOwnPropertyDescriptor(object, exec, propertyName, descriptor))
        return true;

    QScriptValue scriptObject = engine->scriptValueFromJSCValue(object);
    QScriptString scriptName;
    QScriptStringPrivate scriptName_d(engine, propertyName, QScriptStringPrivate::StackAllocated);
    QScriptStringPrivate::init(scriptName, &scriptName_d);
    uint id = 0;
    QScriptClass::QueryFlags qflags = m_scriptClass->queryProperty(
        scriptObject, scriptName, QScriptClass::HandlesReadAccess, &id);
    if (qflags & QScriptClass::HandlesReadAccess) {
        QScriptValue::PropertyFlags pflags = m_scriptClass->propertyFlags(scriptObject, scriptName, id);
        unsigned attribs = 0;
        if (pflags & QScriptValue::ReadOnly)
            attribs |= JSC::ReadOnly;
        if (pflags & QScriptValue::SkipInEnumeration)
            attribs |= JSC::DontEnum;
        if (pflags & QScriptValue::Undeletable)
            attribs |= JSC::DontDelete;
        if (pflags & QScriptValue::PropertyGetter)
            attribs |= JSC::Getter;
        if (pflags & QScriptValue::PropertySetter)
            attribs |= JSC::Setter;
        attribs |= pflags & QScriptValue::UserRange;
        // Rather than calling the getter, we could return an access descriptor here.
        QScriptValue value = m_scriptClass->property(scriptObject, scriptName, id);
        if (!value.isValid()) {
            // The class claims to have the property, but returned an invalid
            // value. Silently convert to undefined to avoid the invalid value
            // "escaping" into JS.
            value = QScriptValue(QScriptValue::UndefinedValue);
        }
        descriptor.setDescriptor(engine->scriptValueToJSCValue(value), attribs);
        return true;
    }
    return false;
}

void ClassObjectDelegate::put(QScriptObject* object, JSC::ExecState *exec,
                              const JSC::Identifier &propertyName,
                              JSC::JSValue value, JSC::PutPropertySlot &slot)
{
    QScriptEnginePrivate *engine = scriptEngineFromExec(exec);
    QScript::SaveFrameHelper saveFrame(engine, exec);
    QScriptValue scriptObject = engine->scriptValueFromJSCValue(object);
    QScriptString scriptName;
    QScriptStringPrivate scriptName_d(engine, propertyName, QScriptStringPrivate::StackAllocated);
    QScriptStringPrivate::init(scriptName, &scriptName_d);
    uint id = 0;
    QScriptClass::QueryFlags flags = m_scriptClass->queryProperty(
        scriptObject, scriptName, QScriptClass::HandlesWriteAccess, &id);
    if (flags & QScriptClass::HandlesWriteAccess) {
        m_scriptClass->setProperty(scriptObject, scriptName, id, engine->scriptValueFromJSCValue(value));
        return;
    }
    QScriptObjectDelegate::put(object, exec, propertyName, value, slot);
}

bool ClassObjectDelegate::deleteProperty(QScriptObject* object, JSC::ExecState *exec,
                                         const JSC::Identifier &propertyName)
{
    // ### avoid duplication of put()
    QScriptEnginePrivate *engine = scriptEngineFromExec(exec);
    QScript::SaveFrameHelper saveFrame(engine, exec);
    QScriptValue scriptObject = engine->scriptValueFromJSCValue(object);
    QScriptString scriptName;
    QScriptStringPrivate scriptName_d(engine, propertyName, QScriptStringPrivate::StackAllocated);
    QScriptStringPrivate::init(scriptName, &scriptName_d);
    uint id = 0;
    QScriptClass::QueryFlags flags = m_scriptClass->queryProperty(
        scriptObject, scriptName, QScriptClass::HandlesWriteAccess, &id);
    if (flags & QScriptClass::HandlesWriteAccess) {
        if (m_scriptClass->propertyFlags(scriptObject, scriptName, id) & QScriptValue::Undeletable)
            return false;
        m_scriptClass->setProperty(scriptObject, scriptName, id, QScriptValue());
        return true;
    }
    return QScriptObjectDelegate::deleteProperty(object, exec, propertyName);
}

void ClassObjectDelegate::getOwnPropertyNames(QScriptObject* object, JSC::ExecState *exec,
                                              JSC::PropertyNameArray &propertyNames,
                                              JSC::EnumerationMode mode)
{
    // For compatibility with the old back-end, normal JS properties
    // are added first.
    QScriptObjectDelegate::getOwnPropertyNames(object, exec, propertyNames, mode);

    QScriptEnginePrivate *engine = scriptEngineFromExec(exec);
    QScript::SaveFrameHelper saveFrame(engine, exec);
    QScriptValue scriptObject = engine->scriptValueFromJSCValue(object);
    QScriptClassPropertyIterator *it = m_scriptClass->newIterator(scriptObject);
    if (it != 0) {
        while (it->hasNext()) {
            it->next();
            QString name = it->name().toString();
            propertyNames.add(JSC::Identifier(exec, name));
        }
        delete it;
    }
}

JSC::CallType ClassObjectDelegate::getCallData(QScriptObject*, JSC::CallData &callData)
{
    if (!m_scriptClass->supportsExtension(QScriptClass::Callable))
        return JSC::CallTypeNone;
    callData.native.function = call;
    return JSC::CallTypeHost;
}

JSC::JSValue JSC_HOST_CALL ClassObjectDelegate::call(JSC::ExecState *exec, JSC::JSObject *callee,
                                             JSC::JSValue thisValue, const JSC::ArgList &args)
{
    if (!callee->inherits(&QScriptObject::info))
        return JSC::throwError(exec, JSC::TypeError, "callee is not a ClassObject object");
    QScriptObject *obj = static_cast<QScriptObject*>(callee);
    QScriptObjectDelegate *delegate = obj->delegate();
    if (!delegate || (delegate->type() != QScriptObjectDelegate::ClassObject))
        return JSC::throwError(exec, JSC::TypeError, "callee is not a ClassObject object");

    QScriptClass *scriptClass = static_cast<ClassObjectDelegate*>(delegate)->scriptClass();
    QScriptEnginePrivate *eng_p = scriptEngineFromExec(exec);

    JSC::ExecState *oldFrame = eng_p->currentFrame;
    eng_p->pushContext(exec, thisValue, args, callee);
    QScriptContext *ctx = eng_p->contextForFrame(eng_p->currentFrame);
    QScriptValue scriptObject = eng_p->scriptValueFromJSCValue(obj);
    QVariant result = scriptClass->extension(QScriptClass::Callable, QVariant::fromValue(ctx));
    eng_p->popContext();
    eng_p->currentFrame = oldFrame;
    return QScriptEnginePrivate::jscValueFromVariant(exec, result);
}

JSC::ConstructType ClassObjectDelegate::getConstructData(QScriptObject*, JSC::ConstructData &constructData)
{
    if (!m_scriptClass->supportsExtension(QScriptClass::Callable))
        return JSC::ConstructTypeNone;
    constructData.native.function = construct;
    return JSC::ConstructTypeHost;
}

JSC::JSObject* ClassObjectDelegate::construct(JSC::ExecState *exec, JSC::JSObject *callee,
                                              const JSC::ArgList &args)
{
    Q_ASSERT(callee->inherits(&QScriptObject::info));
    QScriptObject *obj = static_cast<QScriptObject*>(callee);
    QScriptObjectDelegate *delegate = obj->delegate();
    QScriptClass *scriptClass = static_cast<ClassObjectDelegate*>(delegate)->scriptClass();

    QScriptEnginePrivate *eng_p = scriptEngineFromExec(exec);
    JSC::ExecState *oldFrame = eng_p->currentFrame;
    eng_p->pushContext(exec, JSC::JSValue(), args, callee, true);
    QScriptContext *ctx = eng_p->contextForFrame(eng_p->currentFrame);

    QScriptValue defaultObject = ctx->thisObject();
    QScriptValue result = qvariant_cast<QScriptValue>(scriptClass->extension(QScriptClass::Callable, QVariant::fromValue(ctx)));
    if (!result.isObject())
        result = defaultObject;
    eng_p->popContext();
    eng_p->currentFrame = oldFrame;
    return JSC::asObject(eng_p->scriptValueToJSCValue(result));
}

bool ClassObjectDelegate::hasInstance(QScriptObject* object, JSC::ExecState *exec,
                                      JSC::JSValue value, JSC::JSValue proto)
{
    if (!scriptClass()->supportsExtension(QScriptClass::HasInstance))
        return QScriptObjectDelegate::hasInstance(object, exec, value, proto);
    QScriptValueList args;
    QScriptEnginePrivate *eng_p = scriptEngineFromExec(exec);
    QScript::SaveFrameHelper saveFrame(eng_p, exec);
    args << eng_p->scriptValueFromJSCValue(object) << eng_p->scriptValueFromJSCValue(value);
    QVariant result = scriptClass()->extension(QScriptClass::HasInstance, QVariant::fromValue(args));
    return result.toBool();
}

} // namespace QScript

QT_END_NAMESPACE
