/*
 * Copyright (C) 2018 Igalia S.L.
 * Copyright (C) 2006-2018 Apple Inc. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#include "config.h"
#include "JSCCallbackFunction.h"

#include "APICallbackFunction.h"
#include "APICast.h"
#include "IsoSubspacePerVM.h"
#include "JSCClassPrivate.h"
#include "JSCContextPrivate.h"
#include "JSDestructibleObjectHeapCellType.h"
#include "JSCExceptionPrivate.h"
#include "JSCInlines.h"
#include "JSFunction.h"
#include "JSGlobalObject.h"
#include "JSLock.h"

namespace JSC {

static JSValueRef callAsFunction(JSContextRef callerContext, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
{
    return static_cast<JSCCallbackFunction*>(toJS(function))->call(callerContext, thisObject, argumentCount, arguments, exception);
}

static JSObjectRef callAsConstructor(JSContextRef callerContext, JSObjectRef constructor, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
{
    return static_cast<JSCCallbackFunction*>(toJS(constructor))->construct(callerContext, argumentCount, arguments, exception);
}

const ClassInfo JSCCallbackFunction::s_info = { "CallbackFunction", &InternalFunction::s_info, nullptr, nullptr, CREATE_METHOD_TABLE(JSCCallbackFunction) };

JSCCallbackFunction* JSCCallbackFunction::create(VM& vm, JSGlobalObject* globalObject, const String& name, Type type, JSCClass* jscClass, GRefPtr<GClosure>&& closure, GType returnType, Optional<Vector<GType>>&& parameters)
{
    Structure* structure = globalObject->glibCallbackFunctionStructure();
    JSCCallbackFunction* function = new (NotNull, allocateCell<JSCCallbackFunction>(vm.heap)) JSCCallbackFunction(vm, structure, type, jscClass, WTFMove(closure), returnType, WTFMove(parameters));
    function->finishCreation(vm, name);
    return function;
}

JSCCallbackFunction::JSCCallbackFunction(VM& vm, Structure* structure, Type type, JSCClass* jscClass, GRefPtr<GClosure>&& closure, GType returnType, Optional<Vector<GType>>&& parameters)
    : InternalFunction(vm, structure, APICallbackFunction::call<JSCCallbackFunction>, type == Type::Constructor ? APICallbackFunction::construct<JSCCallbackFunction> : nullptr)
    , m_functionCallback(callAsFunction)
    , m_constructCallback(callAsConstructor)
    , m_type(type)
    , m_class(jscClass)
    , m_closure(WTFMove(closure))
    , m_returnType(returnType)
    , m_parameters(WTFMove(parameters))
{
    ASSERT(type != Type::Constructor || jscClass);
    if (G_CLOSURE_NEEDS_MARSHAL(m_closure.get()))
        g_closure_set_marshal(m_closure.get(), g_cclosure_marshal_generic);
}

JSValueRef JSCCallbackFunction::call(JSContextRef callerContext, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
{
    JSLockHolder locker(toJS(callerContext));
    auto context = jscContextGetOrCreate(toGlobalRef(globalObject()->globalExec()));
    auto* jsContext = jscContextGetJSContext(context.get());

    if (m_type == Type::Constructor) {
        *exception = toRef(JSC::createTypeError(toJS(jsContext), "cannot call a class constructor without |new|"_s));
        return JSValueMakeUndefined(jsContext);
    }

    gpointer instance = nullptr;
    if (m_type == Type::Method) {
        instance = jscContextWrappedObject(context.get(), thisObject);
        if (!instance) {
            *exception = toRef(JSC::createTypeError(toJS(jsContext), "invalid instance type in method"_s));
            return JSValueMakeUndefined(jsContext);
        }
    }

    auto callbackData = jscContextPushCallback(context.get(), toRef(this), thisObject, argumentCount, arguments);

    // GClosure always expect to have at least the instance parameter.
    bool addInstance = instance || (m_parameters && m_parameters->isEmpty());

    auto parameterCount = m_parameters ? std::min(m_parameters->size(), argumentCount) : 1;
    if (addInstance)
        parameterCount++;
    auto* values = static_cast<GValue*>(g_alloca(sizeof(GValue) * parameterCount));
    memset(values, 0, sizeof(GValue) * parameterCount);

    size_t firstParameter = 0;
    if (addInstance) {
        g_value_init(&values[0], G_TYPE_POINTER);
        g_value_set_pointer(&values[0], instance);
        firstParameter = 1;
    }
    if (m_parameters) {
        for (size_t i = firstParameter; i < parameterCount && !*exception; ++i)
            jscContextJSValueToGValue(context.get(), arguments[i - firstParameter], m_parameters.value()[i - firstParameter], &values[i], exception);
    } else {
        auto* parameters = g_ptr_array_new_full(argumentCount, g_object_unref);
        for (size_t i = 0; i < argumentCount; ++i)
            g_ptr_array_add(parameters, jscContextGetOrCreateValue(context.get(), arguments[i]).leakRef());
        g_value_init(&values[firstParameter], G_TYPE_PTR_ARRAY);
        g_value_take_boxed(&values[firstParameter], parameters);
    }

    GValue returnValue = G_VALUE_INIT;
    if (m_returnType != G_TYPE_NONE)
        g_value_init(&returnValue, m_returnType);

    if (!*exception)
        g_closure_invoke(m_closure.get(), m_returnType != G_TYPE_NONE ? &returnValue : nullptr, parameterCount, values, nullptr);

    for (size_t i = 0; i < parameterCount; ++i)
        g_value_unset(&values[i]);

    if (auto* jscException = jsc_context_get_exception(context.get()))
        *exception = jscExceptionGetJSValue(jscException);

    jscContextPopCallback(context.get(), WTFMove(callbackData));

    if (m_returnType == G_TYPE_NONE)
        return JSValueMakeUndefined(jsContext);

    auto* retval = *exception ? JSValueMakeUndefined(jsContext) : jscContextGValueToJSValue(context.get(), &returnValue, exception);
    g_value_unset(&returnValue);
    return retval;
}

JSObjectRef JSCCallbackFunction::construct(JSContextRef callerContext, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
{
    JSLockHolder locker(toJS(callerContext));
    auto context = jscContextGetOrCreate(toGlobalRef(globalObject()->globalExec()));
    auto* jsContext = jscContextGetJSContext(context.get());

    if (m_returnType == G_TYPE_NONE) {
        *exception = toRef(JSC::createTypeError(toJS(jsContext), "constructors cannot be void"_s));
        return nullptr;
    }

    auto callbackData = jscContextPushCallback(context.get(), toRef(this), nullptr, argumentCount, arguments);

    GValue returnValue = G_VALUE_INIT;
    g_value_init(&returnValue, m_returnType);

    if (m_parameters && m_parameters->isEmpty()) {
        // GClosure always expect to have at least the instance parameter.
        GValue dummyValue = G_VALUE_INIT;
        g_value_init(&dummyValue, G_TYPE_POINTER);
        g_closure_invoke(m_closure.get(), &returnValue, 1, &dummyValue, nullptr);
        g_value_unset(&dummyValue);
    } else {
        auto parameterCount = m_parameters ? std::min(m_parameters->size(), argumentCount) : 1;
        auto* values = static_cast<GValue*>(g_alloca(sizeof(GValue) * parameterCount));
        memset(values, 0, sizeof(GValue) * parameterCount);

        if (m_parameters) {
            for (size_t i = 0; i < parameterCount && !*exception; ++i)
                jscContextJSValueToGValue(context.get(), arguments[i], m_parameters.value()[i], &values[i], exception);
        } else {
            auto* parameters = g_ptr_array_new_full(argumentCount, g_object_unref);
            for (size_t i = 0; i < argumentCount; ++i)
                g_ptr_array_add(parameters, jscContextGetOrCreateValue(context.get(), arguments[i]).leakRef());
            g_value_init(&values[0], G_TYPE_PTR_ARRAY);
            g_value_take_boxed(&values[0], parameters);
        }

        if (!*exception)
            g_closure_invoke(m_closure.get(), &returnValue, parameterCount, values, nullptr);

        for (size_t i = 0; i < parameterCount; ++i)
            g_value_unset(&values[i]);
    }

    if (auto* jscException = jsc_context_get_exception(context.get()))
        *exception = jscExceptionGetJSValue(jscException);

    jscContextPopCallback(context.get(), WTFMove(callbackData));

    if (*exception) {
        g_value_unset(&returnValue);
        return nullptr;
    }

    switch (g_type_fundamental(G_VALUE_TYPE(&returnValue))) {
    case G_TYPE_POINTER:
    case G_TYPE_BOXED:
    case G_TYPE_OBJECT:
        if (auto* ptr = returnValue.data[0].v_pointer)
            return toRef(jscClassGetOrCreateJSWrapper(m_class.get(), context.get(), ptr));
        *exception = toRef(JSC::createTypeError(toJS(jsContext), "constructor returned null"_s));
        break;
    default:
        *exception = toRef(JSC::createTypeError(toJS(jsContext), makeString("invalid type ", g_type_name(G_VALUE_TYPE(&returnValue)), " returned by constructor")));
        break;
    }
    g_value_unset(&returnValue);
    return nullptr;
}

void JSCCallbackFunction::destroy(JSCell* cell)
{
    static_cast<JSCCallbackFunction*>(cell)->JSCCallbackFunction::~JSCCallbackFunction();
}

IsoSubspace* JSCCallbackFunction::subspaceForImpl(VM& vm)
{
    NeverDestroyed<IsoSubspacePerVM> perVM([] (VM& vm) -> IsoSubspacePerVM::SubspaceParameters { return ISO_SUBSPACE_PARAMETERS(vm.destructibleObjectHeapCellType.get(), JSCCallbackFunction); });
    return &perVM.get().forVM(vm);
}

} // namespace JSC
