/*
 * Copyright (C) 2018 Igalia S.L.
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Library General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Library General Public License for more details.
 *
 * You should have received a copy of the GNU Library General Public License
 * along with this library; see the file COPYING.LIB.  If not, write to
 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
 * Boston, MA 02110-1301, USA.
 */

#include "config.h"
#include "JSCContext.h"

#include "JSCClassPrivate.h"
#include "JSCContextPrivate.h"
#include "JSCExceptionPrivate.h"
#include "JSCInlines.h"
#include "JSCValuePrivate.h"
#include "JSCVirtualMachinePrivate.h"
#include "JSCWrapperMap.h"
#include "JSRetainPtr.h"
#include "JSWithScope.h"
#include "OpaqueJSString.h"
#include "Parser.h"
#include <wtf/glib/GUniquePtr.h>
#include <wtf/glib/WTFGType.h>

/**
 * SECTION: JSCContext
 * @short_description: JavaScript execution context
 * @title: JSCContext
 *
 * JSCContext represents a JavaScript execution context, where all operations
 * take place and where the values will be associated.
 *
 * When a new context is created, a global object is allocated and the built-in JavaScript
 * objects (Object, Function, String, Array) are populated. You can execute JavaScript in
 * the context by using jsc_context_evaluate() or jsc_context_evaluate_with_source_uri().
 * It's also possible to register custom objects in the context with jsc_context_register_class().
 */

enum {
    PROP_0,

    PROP_VIRTUAL_MACHINE,
};

struct JSCContextExceptionHandler {
    JSCContextExceptionHandler(JSCExceptionHandler handler, void* userData = nullptr, GDestroyNotify destroyNotifyFunction = nullptr)
        : handler(handler)
        , userData(userData)
        , destroyNotifyFunction(destroyNotifyFunction)
    {
    }

    ~JSCContextExceptionHandler()
    {
        if (destroyNotifyFunction)
            destroyNotifyFunction(userData);
    }

    JSCContextExceptionHandler(JSCContextExceptionHandler&& other)
    {
        std::swap(handler, other.handler);
        std::swap(userData, other.userData);
        std::swap(destroyNotifyFunction, other.destroyNotifyFunction);
    }

    JSCContextExceptionHandler(const JSCContextExceptionHandler&) = delete;
    JSCContextExceptionHandler& operator=(const JSCContextExceptionHandler&) = delete;

    JSCExceptionHandler handler { nullptr };
    void* userData { nullptr };
    GDestroyNotify destroyNotifyFunction { nullptr };
};

struct _JSCContextPrivate {
    GRefPtr<JSCVirtualMachine> vm;
    JSRetainPtr<JSGlobalContextRef> jsContext;
    GRefPtr<JSCException> exception;
    Vector<JSCContextExceptionHandler> exceptionHandlers;
};

WEBKIT_DEFINE_TYPE(JSCContext, jsc_context, G_TYPE_OBJECT)

static void jscContextSetVirtualMachine(JSCContext* context, GRefPtr<JSCVirtualMachine>&& vm)
{
    JSCContextPrivate* priv = context->priv;
    if (vm) {
        ASSERT(!priv->vm);
        priv->vm = WTFMove(vm);
        ASSERT(!priv->jsContext);
        GUniquePtr<char> name(g_strdup_printf("%p-jsContext", &Thread::current()));
        if (auto* data = g_object_get_data(G_OBJECT(priv->vm.get()), name.get())) {
            priv->jsContext = static_cast<JSGlobalContextRef>(data);
            g_object_set_data(G_OBJECT(priv->vm.get()), name.get(), nullptr);
        } else
            priv->jsContext = JSRetainPtr<JSGlobalContextRef>(Adopt, JSGlobalContextCreateInGroup(jscVirtualMachineGetContextGroup(priv->vm.get()), nullptr));
        auto* globalObject = toJSGlobalObject(priv->jsContext.get());
        if (!globalObject->wrapperMap())
            globalObject->setWrapperMap(makeUnique<JSC::WrapperMap>(priv->jsContext.get()));
        jscVirtualMachineAddContext(priv->vm.get(), context);
    } else if (priv->vm) {
        ASSERT(priv->jsContext);
        jscVirtualMachineRemoveContext(priv->vm.get(), context);
        priv->jsContext = nullptr;
        priv->vm = nullptr;
    }
}

static void jscContextGetProperty(GObject* object, guint propID, GValue* value, GParamSpec* paramSpec)
{
    JSCContextPrivate* priv = JSC_CONTEXT(object)->priv;

    switch (propID) {
    case PROP_VIRTUAL_MACHINE:
        g_value_set_object(value, priv->vm.get());
        break;
    default:
        G_OBJECT_WARN_INVALID_PROPERTY_ID(object, propID, paramSpec);
    }
}

static void jscContextSetProperty(GObject* object, guint propID, const GValue* value, GParamSpec* paramSpec)
{
    JSCContext* context = JSC_CONTEXT(object);

    switch (propID) {
    case PROP_VIRTUAL_MACHINE:
        if (gpointer vm = g_value_get_object(value))
            jscContextSetVirtualMachine(context, GRefPtr<JSCVirtualMachine>(JSC_VIRTUAL_MACHINE(vm)));
        break;
    default:
        G_OBJECT_WARN_INVALID_PROPERTY_ID(object, propID, paramSpec);
    }
}

static void jscContextConstructed(GObject* object)
{
    G_OBJECT_CLASS(jsc_context_parent_class)->constructed(object);

    JSCContext* context = JSC_CONTEXT(object);
    if (!context->priv->vm)
        jscContextSetVirtualMachine(context, adoptGRef(jsc_virtual_machine_new()));

    context->priv->exceptionHandlers.append(JSCContextExceptionHandler([](JSCContext* context, JSCException* exception, gpointer) {
        jsc_context_throw_exception(context, exception);
    }));
}

static void jscContextDispose(GObject* object)
{
    JSCContext* context = JSC_CONTEXT(object);
    jscContextSetVirtualMachine(context, nullptr);

    G_OBJECT_CLASS(jsc_context_parent_class)->dispose(object);
}

static void jsc_context_class_init(JSCContextClass* klass)
{
    GObjectClass* objClass = G_OBJECT_CLASS(klass);
    objClass->get_property = jscContextGetProperty;
    objClass->set_property = jscContextSetProperty;
    objClass->constructed = jscContextConstructed;
    objClass->dispose = jscContextDispose;

    /**
     * JSCContext:virtual-machine:
     *
     * The #JSCVirtualMachine in which the context was created.
     */
    g_object_class_install_property(objClass,
        PROP_VIRTUAL_MACHINE,
        g_param_spec_object(
            "virtual-machine",
            "JSCVirtualMachine",
            "JSC Virtual Machine",
            JSC_TYPE_VIRTUAL_MACHINE,
            static_cast<GParamFlags>(WEBKIT_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY)));
}

GRefPtr<JSCContext> jscContextGetOrCreate(JSGlobalContextRef jsContext)
{
    auto vm = jscVirtualMachineGetOrCreate(toRef(&toJS(jsContext)->vm()));
    if (GRefPtr<JSCContext> context = jscVirtualMachineGetContext(vm.get(), jsContext))
        return context;

    GUniquePtr<char> name(g_strdup_printf("%p-jsContext", &Thread::current()));
    g_object_set_data(G_OBJECT(vm.get()), name.get(), jsContext);
    return adoptGRef(jsc_context_new_with_virtual_machine(vm.get()));
}

JSGlobalContextRef jscContextGetJSContext(JSCContext* context)
{
    ASSERT(JSC_IS_CONTEXT(context));

    JSCContextPrivate* priv = context->priv;
    return priv->jsContext.get();
}

static JSC::WrapperMap& wrapperMap(JSCContext* context)
{
    auto* map = toJSGlobalObject(context->priv->jsContext.get())->wrapperMap();
    ASSERT(map);
    return *map;
}

GRefPtr<JSCValue> jscContextGetOrCreateValue(JSCContext* context, JSValueRef jsValue)
{
    return wrapperMap(context).gobjectWrapper(context, jsValue);
}

void jscContextValueDestroyed(JSCContext* context, JSValueRef jsValue)
{
    wrapperMap(context).unwrap(jsValue);
}

JSC::JSObject* jscContextGetJSWrapper(JSCContext* context, gpointer wrappedObject)
{
    return wrapperMap(context).jsWrapper(wrappedObject);
}

JSC::JSObject* jscContextGetOrCreateJSWrapper(JSCContext* context, JSClassRef jsClass, JSValueRef prototype, gpointer wrappedObject, GDestroyNotify destroyFunction)
{
    if (auto* jsWrapper = jscContextGetJSWrapper(context, wrappedObject))
        return jsWrapper;

    return wrapperMap(context).createJSWrappper(context->priv->jsContext.get(), jsClass, prototype, wrappedObject, destroyFunction);
}

JSGlobalContextRef jscContextCreateContextWithJSWrapper(JSCContext* context, JSClassRef jsClass, JSValueRef prototype, gpointer wrappedObject, GDestroyNotify destroyFunction)
{
    return wrapperMap(context).createContextWithJSWrappper(jscVirtualMachineGetContextGroup(context->priv->vm.get()), jsClass, prototype, wrappedObject, destroyFunction);
}

gpointer jscContextWrappedObject(JSCContext* context, JSObjectRef jsObject)
{
    return wrapperMap(context).wrappedObject(context->priv->jsContext.get(), jsObject);
}

JSCClass* jscContextGetRegisteredClass(JSCContext* context, JSClassRef jsClass)
{
    return wrapperMap(context).registeredClass(jsClass);
}

CallbackData jscContextPushCallback(JSCContext* context, JSValueRef calleeValue, JSValueRef thisValue, size_t argumentCount, const JSValueRef* arguments)
{
    Thread& thread = Thread::current();
    auto* previousStack = static_cast<CallbackData*>(thread.m_apiData);
    CallbackData data = { context, WTFMove(context->priv->exception), calleeValue, thisValue, argumentCount, arguments, previousStack };
    thread.m_apiData = &data;
    return data;
}

void jscContextPopCallback(JSCContext* context, CallbackData&& data)
{
    Thread& thread = Thread::current();
    context->priv->exception = WTFMove(data.preservedException);
    thread.m_apiData = data.next;
}

JSValueRef jscContextGArrayToJSArray(JSCContext* context, GPtrArray* gArray, JSValueRef* exception)
{
    JSCContextPrivate* priv = context->priv;
    auto* jsArray = JSObjectMakeArray(priv->jsContext.get(), 0, nullptr, exception);
    if (*exception)
        return JSValueMakeUndefined(priv->jsContext.get());

    if (!gArray)
        return jsArray;

    auto* jsArrayObject = JSValueToObject(priv->jsContext.get(), jsArray, exception);
    if (*exception)
        return JSValueMakeUndefined(priv->jsContext.get());

    for (unsigned i = 0; i < gArray->len; ++i) {
        gpointer item = g_ptr_array_index(gArray, i);
        if (!item)
            JSObjectSetPropertyAtIndex(priv->jsContext.get(), jsArrayObject, i, JSValueMakeNull(priv->jsContext.get()), exception);
        else if (JSC_IS_VALUE(item))
            JSObjectSetPropertyAtIndex(priv->jsContext.get(), jsArrayObject, i, jscValueGetJSValue(JSC_VALUE(item)), exception);
        else
            *exception = toRef(JSC::createTypeError(toJS(priv->jsContext.get()), makeString("invalid item type in GPtrArray")));

        if (*exception)
            return JSValueMakeUndefined(priv->jsContext.get());
    }

    return jsArray;
}

static GRefPtr<GPtrArray> jscContextJSArrayToGArray(JSCContext* context, JSValueRef jsArray, JSValueRef* exception)
{
    JSCContextPrivate* priv = context->priv;
    if (JSValueIsNull(priv->jsContext.get(), jsArray))
        return nullptr;

    if (!JSValueIsArray(priv->jsContext.get(), jsArray)) {
        *exception = toRef(JSC::createTypeError(toJS(priv->jsContext.get()), makeString("invalid js type for GPtrArray")));
        return nullptr;
    }

    auto* jsArrayObject = JSValueToObject(priv->jsContext.get(), jsArray, exception);
    if (*exception)
        return nullptr;

    JSRetainPtr<JSStringRef> lengthString(Adopt, JSStringCreateWithUTF8CString("length"));
    auto* jsLength = JSObjectGetProperty(priv->jsContext.get(), jsArrayObject, lengthString.get(), exception);
    if (*exception)
        return nullptr;

    auto length = JSC::toUInt32(JSValueToNumber(priv->jsContext.get(), jsLength, exception));
    if (*exception)
        return nullptr;

    GRefPtr<GPtrArray> gArray = adoptGRef(g_ptr_array_new_with_free_func(g_object_unref));
    for (unsigned i = 0; i < length; ++i) {
        auto* jsItem = JSObjectGetPropertyAtIndex(priv->jsContext.get(), jsArrayObject, i, exception);
        if (*exception)
            return nullptr;

        g_ptr_array_add(gArray.get(), jsItem ? jscContextGetOrCreateValue(context, jsItem).leakRef() : nullptr);
    }

    return gArray;
}

GUniquePtr<char*> jscContextJSArrayToGStrv(JSCContext* context, JSValueRef jsArray, JSValueRef* exception)
{
    JSCContextPrivate* priv = context->priv;
    if (JSValueIsNull(priv->jsContext.get(), jsArray))
        return nullptr;

    if (!JSValueIsArray(priv->jsContext.get(), jsArray)) {
        *exception = toRef(JSC::createTypeError(toJS(priv->jsContext.get()), makeString("invalid js type for GStrv")));
        return nullptr;
    }

    auto* jsArrayObject = JSValueToObject(priv->jsContext.get(), jsArray, exception);
    if (*exception)
        return nullptr;

    JSRetainPtr<JSStringRef> lengthString(Adopt, JSStringCreateWithUTF8CString("length"));
    auto* jsLength = JSObjectGetProperty(priv->jsContext.get(), jsArrayObject, lengthString.get(), exception);
    if (*exception)
        return nullptr;

    auto length = JSC::toUInt32(JSValueToNumber(priv->jsContext.get(), jsLength, exception));
    if (*exception)
        return nullptr;

    GUniquePtr<char*> strv(static_cast<char**>(g_new0(char*, length + 1)));
    for (unsigned i = 0; i < length; ++i) {
        auto* jsItem = JSObjectGetPropertyAtIndex(priv->jsContext.get(), jsArrayObject, i, exception);
        if (*exception)
            return nullptr;

        auto jsValueItem = jscContextGetOrCreateValue(context, jsItem);
        if (!jsc_value_is_string(jsValueItem.get())) {
            *exception = toRef(JSC::createTypeError(toJS(priv->jsContext.get()), makeString("invalid js type for GStrv: item ", String::number(i), " is not a string")));
            return nullptr;
        }

        strv.get()[i] = jsc_value_to_string(jsValueItem.get());
    }

    return strv;
}

JSValueRef jscContextGValueToJSValue(JSCContext* context, const GValue* value, JSValueRef* exception)
{
    JSCContextPrivate* priv = context->priv;

    switch (g_type_fundamental(G_VALUE_TYPE(value))) {
    case G_TYPE_BOOLEAN:
        return JSValueMakeBoolean(priv->jsContext.get(), g_value_get_boolean(value));
    case G_TYPE_CHAR:
    case G_TYPE_INT:
        return JSValueMakeNumber(priv->jsContext.get(), value->data[0].v_int);
    case G_TYPE_ENUM:
        return JSValueMakeNumber(priv->jsContext.get(), g_value_get_enum(value));
    case G_TYPE_FLAGS:
        return JSValueMakeNumber(priv->jsContext.get(), g_value_get_flags(value));
    case G_TYPE_UCHAR:
    case G_TYPE_UINT:
        return JSValueMakeNumber(priv->jsContext.get(), value->data[0].v_uint);
    case G_TYPE_FLOAT:
        return JSValueMakeNumber(priv->jsContext.get(), value->data[0].v_float);
    case G_TYPE_DOUBLE:
        return JSValueMakeNumber(priv->jsContext.get(), value->data[0].v_double);
    case G_TYPE_LONG:
        return JSValueMakeNumber(priv->jsContext.get(), value->data[0].v_long);
    case G_TYPE_ULONG:
        return JSValueMakeNumber(priv->jsContext.get(), value->data[0].v_ulong);
    case G_TYPE_INT64:
        return JSValueMakeNumber(priv->jsContext.get(), value->data[0].v_int64);
    case G_TYPE_UINT64:
        return JSValueMakeNumber(priv->jsContext.get(), value->data[0].v_uint64);
    case G_TYPE_STRING:
        if (const char* stringValue = g_value_get_string(value)) {
            JSRetainPtr<JSStringRef> jsString(Adopt, JSStringCreateWithUTF8CString(stringValue));
            return JSValueMakeString(priv->jsContext.get(), jsString.get());
        }
        return JSValueMakeNull(priv->jsContext.get());
    case G_TYPE_POINTER:
    case G_TYPE_OBJECT:
    case G_TYPE_BOXED:
        if (auto* ptr = value->data[0].v_pointer) {
            if (auto* jsWrapper = jscContextGetJSWrapper(context, ptr))
                return toRef(jsWrapper);

            if (g_type_is_a(G_VALUE_TYPE(value), JSC_TYPE_VALUE))
                return jscValueGetJSValue(JSC_VALUE(ptr));

            if (g_type_is_a(G_VALUE_TYPE(value), JSC_TYPE_EXCEPTION))
                return jscExceptionGetJSValue(JSC_EXCEPTION(ptr));

            if (g_type_is_a(G_VALUE_TYPE(value), G_TYPE_PTR_ARRAY))
                return jscContextGArrayToJSArray(context, static_cast<GPtrArray*>(ptr), exception);

            if (g_type_is_a(G_VALUE_TYPE(value), G_TYPE_STRV)) {
                auto** strv = static_cast<char**>(ptr);
                auto strvLength = g_strv_length(strv);
                GRefPtr<GPtrArray> gArray = adoptGRef(g_ptr_array_new_full(strvLength, g_object_unref));
                for (unsigned i = 0; i < strvLength; i++)
                    g_ptr_array_add(gArray.get(), jsc_value_new_string(context, strv[i]));
                return jscContextGArrayToJSArray(context, gArray.get(), exception);
            }
        } else
            return JSValueMakeNull(priv->jsContext.get());

        break;
    case G_TYPE_PARAM:
    case G_TYPE_INTERFACE:
    case G_TYPE_VARIANT:
    default:
        break;
    }

    *exception = toRef(JSC::createTypeError(toJS(priv->jsContext.get()), makeString("unsupported type ", g_type_name(G_VALUE_TYPE(value)))));
    return JSValueMakeUndefined(priv->jsContext.get());
}

void jscContextJSValueToGValue(JSCContext* context, JSValueRef jsValue, GType type, GValue* value, JSValueRef* exception)
{
    JSCContextPrivate* priv = context->priv;
    g_value_init(value, type);

    auto fundamentalType = g_type_fundamental(G_VALUE_TYPE(value));
    switch (fundamentalType) {
    case G_TYPE_INT:
        g_value_set_int(value, JSValueToNumber(priv->jsContext.get(), jsValue, exception));
        break;
    case G_TYPE_FLOAT:
        g_value_set_float(value, JSValueToNumber(priv->jsContext.get(), jsValue, exception));
        break;
    case G_TYPE_DOUBLE:
        g_value_set_double(value, JSValueToNumber(priv->jsContext.get(), jsValue, exception));
        break;
    case G_TYPE_BOOLEAN:
        g_value_set_boolean(value, JSValueToBoolean(priv->jsContext.get(), jsValue));
        break;
    case G_TYPE_STRING:
        if (!JSValueIsNull(priv->jsContext.get(), jsValue)) {
            JSRetainPtr<JSStringRef> jsString(Adopt, JSValueToStringCopy(priv->jsContext.get(), jsValue, exception));
            if (*exception)
                return;
            size_t maxSize = JSStringGetMaximumUTF8CStringSize(jsString.get());
            auto* string = static_cast<char*>(g_malloc(maxSize));
            JSStringGetUTF8CString(jsString.get(), string, maxSize);
            g_value_take_string(value, string);
        } else
            g_value_set_string(value, nullptr);
        break;
    case G_TYPE_CHAR:
        g_value_set_schar(value, JSValueToNumber(priv->jsContext.get(), jsValue, exception));
        break;
    case G_TYPE_UCHAR:
        g_value_set_uchar(value, JSValueToNumber(priv->jsContext.get(), jsValue, exception));
        break;
    case G_TYPE_UINT:
        g_value_set_uint(value, JSValueToNumber(priv->jsContext.get(), jsValue, exception));
        break;
    case G_TYPE_POINTER:
    case G_TYPE_OBJECT:
    case G_TYPE_BOXED: {
        gpointer wrappedObject = nullptr;

        if (!JSValueIsNull(priv->jsContext.get(), jsValue)) {
            auto jsObject = JSValueToObject(priv->jsContext.get(), jsValue, exception);
            if (*exception)
                return;

            wrappedObject = jscContextWrappedObject(context, jsObject);
            if (!wrappedObject) {
                if (g_type_is_a(G_VALUE_TYPE(value), JSC_TYPE_VALUE)) {
                    auto jscValue = jscContextGetOrCreateValue(context, jsValue);
                    g_value_set_object(value, jscValue.get());
                    return;
                }

                if (g_type_is_a(G_VALUE_TYPE(value), JSC_TYPE_EXCEPTION)) {
                    auto exception = jscExceptionCreate(context, jsValue);
                    g_value_set_object(value, exception.get());
                    return;
                }

                if (g_type_is_a(G_VALUE_TYPE(value), G_TYPE_PTR_ARRAY)) {
                    auto gArray = jscContextJSArrayToGArray(context, jsValue, exception);
                    if (!*exception)
                        g_value_take_boxed(value, gArray.leakRef());
                    return;
                }

                if (g_type_is_a(G_VALUE_TYPE(value), G_TYPE_STRV)) {
                    auto strv = jscContextJSArrayToGStrv(context, jsValue, exception);
                    if (!*exception)
                        g_value_take_boxed(value, strv.release());
                    return;
                }

                *exception = toRef(JSC::createTypeError(toJS(priv->jsContext.get()), "invalid pointer type"_s));
                return;
            }
        }
        if (fundamentalType == G_TYPE_POINTER)
            g_value_set_pointer(value, wrappedObject);
        else if (fundamentalType == G_TYPE_BOXED)
            g_value_set_boxed(value, wrappedObject);
        else if (G_IS_OBJECT(wrappedObject))
            g_value_set_object(value, wrappedObject);
        else
            *exception = toRef(JSC::createTypeError(toJS(priv->jsContext.get()), "wrapped object is not a GObject"_s));
        break;
    }
    case G_TYPE_LONG:
        g_value_set_long(value, JSValueToNumber(priv->jsContext.get(), jsValue, exception));
        break;
    case G_TYPE_ULONG:
        g_value_set_ulong(value, JSValueToNumber(priv->jsContext.get(), jsValue, exception));
        break;
    case G_TYPE_INT64:
        g_value_set_int64(value, JSValueToNumber(priv->jsContext.get(), jsValue, exception));
        break;
    case G_TYPE_UINT64:
        g_value_set_uint64(value, JSValueToNumber(priv->jsContext.get(), jsValue, exception));
        break;
    case G_TYPE_ENUM:
        g_value_set_enum(value, JSValueToNumber(priv->jsContext.get(), jsValue, exception));
        break;
    case G_TYPE_FLAGS:
        g_value_set_flags(value, JSValueToNumber(priv->jsContext.get(), jsValue, exception));
        break;
    case G_TYPE_PARAM:
    case G_TYPE_INTERFACE:
    case G_TYPE_VARIANT:
    default:
        *exception = toRef(JSC::createTypeError(toJS(priv->jsContext.get()), makeString("unsupported type ", g_type_name(G_VALUE_TYPE(value)))));
        break;
    }
}

/**
 * jsc_context_new:
 *
 * Create a new #JSCContext. The context is created in a new #JSCVirtualMachine.
 * Use jsc_context_new_with_virtual_machine() to create a new #JSCContext in an
 * existing #JSCVirtualMachine.
 *
 * Returns: (transfer full): the newly created #JSCContext.
 */
JSCContext* jsc_context_new()
{
    return JSC_CONTEXT(g_object_new(JSC_TYPE_CONTEXT, nullptr));
}

/**
 * jsc_context_new_with_virtual_machine:
 * @vm: a #JSCVirtualMachine
 *
 * Create a new #JSCContext in @virtual_machine.
 *
 * Returns: (transfer full): the newly created #JSCContext.
 */
JSCContext* jsc_context_new_with_virtual_machine(JSCVirtualMachine* vm)
{
    g_return_val_if_fail(JSC_IS_VIRTUAL_MACHINE(vm), nullptr);
    return JSC_CONTEXT(g_object_new(JSC_TYPE_CONTEXT, "virtual-machine", vm, nullptr));
}

/**
 * jsc_context_get_virtual_machine:
 * @context: a #JSCContext
 *
 * Get the #JSCVirtualMachine where @context was created.
 *
 * Returns: (transfer none): the #JSCVirtualMachine where the #JSCContext was created.
 */
JSCVirtualMachine* jsc_context_get_virtual_machine(JSCContext* context)
{
    g_return_val_if_fail(JSC_IS_CONTEXT(context), nullptr);

    return context->priv->vm.get();
}

/**
 * jsc_context_get_exception:
 * @context: a #JSCContext
 *
 * Get the last unhandled exception thrown in @context by API functions calls.
 *
 * Returns: (transfer none) (nullable): a #JSCException or %NULL if there isn't any
 *    unhandled exception in the #JSCContext.
 */
JSCException* jsc_context_get_exception(JSCContext *context)
{
    g_return_val_if_fail(JSC_IS_CONTEXT(context), nullptr);

    return context->priv->exception.get();
}

/**
 * jsc_context_throw:
 * @context: a #JSCContext
 * @error_message: an error message
 *
 * Throw an exception to @context using the given error message. The created #JSCException
 * can be retrieved with jsc_context_get_exception().
 */
void jsc_context_throw(JSCContext* context, const char* errorMessage)
{
    g_return_if_fail(JSC_IS_CONTEXT(context));

    context->priv->exception = adoptGRef(jsc_exception_new(context, errorMessage));
}

/**
 * jsc_context_throw_printf:
 * @context: a #JSCContext
 * @format: the string format
 * @...: the parameters to insert into the format string
 *
 * Throw an exception to @context using the given formatted string as error message.
 * The created #JSCException can be retrieved with jsc_context_get_exception().
 */
void jsc_context_throw_printf(JSCContext* context, const char* format, ...)
{
    g_return_if_fail(JSC_IS_CONTEXT(context));

    va_list args;
    va_start(args, format);
    context->priv->exception = adoptGRef(jsc_exception_new_vprintf(context, format, args));
    va_end(args);
}

/**
 * jsc_context_throw_with_name:
 * @context: a #JSCContext
 * @error_name: the error name
 * @error_message: an error message
 *
 * Throw an exception to @context using the given error name and message. The created #JSCException
 * can be retrieved with jsc_context_get_exception().
 */
void jsc_context_throw_with_name(JSCContext* context, const char* errorName, const char* errorMessage)
{
    g_return_if_fail(JSC_IS_CONTEXT(context));
    g_return_if_fail(errorName);

    context->priv->exception = adoptGRef(jsc_exception_new_with_name(context, errorName, errorMessage));
}

/**
 * jsc_context_throw_with_name_printf:
 * @context: a #JSCContext
 * @error_name: the error name
 * @format: the string format
 * @...: the parameters to insert into the format string
 *
 * Throw an exception to @context using the given error name and the formatted string as error message.
 * The created #JSCException can be retrieved with jsc_context_get_exception().
 */
void jsc_context_throw_with_name_printf(JSCContext* context, const char* errorName, const char* format, ...)
{
    g_return_if_fail(JSC_IS_CONTEXT(context));

    va_list args;
    va_start(args, format);
    context->priv->exception = adoptGRef(jsc_exception_new_with_name_vprintf(context, errorName, format, args));
    va_end(args);
}

/**
 * jsc_context_throw_exception:
 * @context: a #JSCContext
 * @exception: a #JSCException
 *
 * Throw @exception to @context.
 */
void jsc_context_throw_exception(JSCContext* context, JSCException* exception)
{
    g_return_if_fail(JSC_IS_CONTEXT(context));
    g_return_if_fail(JSC_IS_EXCEPTION(exception));

    context->priv->exception = exception;
}

/**
 * jsc_context_clear_exception:
 * @context: a #JSCContext
 *
 * Clear the uncaught exception in @context if any.
 */
void jsc_context_clear_exception(JSCContext* context)
{
    g_return_if_fail(JSC_IS_CONTEXT(context));

    context->priv->exception = nullptr;
}

/**
 * JSCExceptionHandler:
 * @context: a #JSCContext
 * @exception: a #JSCException
 * @user_data: user data
 *
 * Function used to handle JavaScript exceptions in a #JSCContext.
 */

/**
 * jsc_context_push_exception_handler:
 * @context: a #JSCContext
 * @handler: a #JSCExceptionHandler
 * @user_data: (closure): user data to pass to @handler
 * @destroy_notify: (nullable): destroy notifier for @user_data
 *
 * Push an exception handler in @context. Whenever a JavaScript exception happens in
 * the #JSCContext, the given @handler will be called. The default #JSCExceptionHandler
 * simply calls jsc_context_throw_exception() to throw the exception to the #JSCContext.
 * If you don't want to catch the exception, but only get notified about it, call
 * jsc_context_throw_exception() in @handler like the default one does.
 * The last exception handler pushed is the only one used by the #JSCContext, use
 * jsc_context_pop_exception_handler() to remove it and set the previous one. When @handler
 * is removed from the context, @destroy_notify i called with @user_data as parameter.
 */
void jsc_context_push_exception_handler(JSCContext* context, JSCExceptionHandler handler, gpointer userData, GDestroyNotify destroyNotify)
{
    g_return_if_fail(JSC_IS_CONTEXT(context));
    g_return_if_fail(handler);

    context->priv->exceptionHandlers.append({ handler, userData, destroyNotify });
}

/**
 * jsc_context_pop_exception_handler:
 * @context: a #JSCContext
 *
 * Remove the last #JSCExceptionHandler previously pushed to @context with
 * jsc_context_push_exception_handler().
 */
void jsc_context_pop_exception_handler(JSCContext* context)
{
    g_return_if_fail(JSC_IS_CONTEXT(context));
    g_return_if_fail(context->priv->exceptionHandlers.size() > 1);

    context->priv->exceptionHandlers.removeLast();
}

bool jscContextHandleExceptionIfNeeded(JSCContext* context, JSValueRef jsException)
{
    if (!jsException)
        return false;

    auto exception = jscExceptionCreate(context, jsException);
    ASSERT(!context->priv->exceptionHandlers.isEmpty());
    const auto& exceptionHandler = context->priv->exceptionHandlers.last();
    exceptionHandler.handler(context, exception.get(), exceptionHandler.userData);

    return true;
}

/**
 * jsc_context_get_current:
 *
 * Get the #JSCContext that is currently executing a function. This should only be
 * called within a function or method callback, otherwise %NULL will be returned.
 *
 * Returns: (transfer none) (nullable): the #JSCContext that is currently executing.
 */
JSCContext* jsc_context_get_current()
{
    auto* data = static_cast<CallbackData*>(Thread::current().m_apiData);
    return data ? data->context.get() : nullptr;
}

/**
 * jsc_context_evaluate:
 * @context: a #JSCContext
 * @code: a JavaScript script to evaluate
 * @length: length of @code, or -1 if @code is a nul-terminated string
 *
 * Evaluate @code in @context.
 *
 * Returns: (transfer full): a #JSCValue representing the last value generated by the script.
 */
JSCValue* jsc_context_evaluate(JSCContext* context, const char* code, gssize length)
{
    return jsc_context_evaluate_with_source_uri(context, code, length, nullptr, 0);
}

static JSValueRef evaluateScriptInContext(JSGlobalContextRef jsContext, String&& script, const char* uri, unsigned lineNumber, JSValueRef* exception)
{
    JSRetainPtr<JSStringRef> scriptJS(Adopt, OpaqueJSString::tryCreate(WTFMove(script)).leakRef());
    JSRetainPtr<JSStringRef> sourceURI = uri ? adopt(JSStringCreateWithUTF8CString(uri)) : nullptr;
    return JSEvaluateScript(jsContext, scriptJS.get(), nullptr, sourceURI.get(), lineNumber, exception);
}

/**
 * jsc_context_evaluate_with_source_uri:
 * @context: a #JSCContext
 * @code: a JavaScript script to evaluate
 * @length: length of @code, or -1 if @code is a nul-terminated string
 * @uri: the source URI
 * @line_number: the starting line number
 *
 * Evaluate @code in @context using @uri as the source URI. The @line_number is the starting line number
 * in @uri; the value is one-based so the first line is 1. @uri and @line_number will be shown in exceptions and
 * they don't affect the behavior of the script.
 *
 * Returns: (transfer full): a #JSCValue representing the last value generated by the script.
 */
JSCValue* jsc_context_evaluate_with_source_uri(JSCContext* context, const char* code, gssize length, const char* uri, unsigned lineNumber)
{
    g_return_val_if_fail(JSC_IS_CONTEXT(context), nullptr);
    g_return_val_if_fail(code, nullptr);

    JSValueRef exception = nullptr;
    JSValueRef result = evaluateScriptInContext(context->priv->jsContext.get(), String::fromUTF8(code, length < 0 ? strlen(code) : length), uri, lineNumber, &exception);
    if (jscContextHandleExceptionIfNeeded(context, exception))
        return jsc_value_new_undefined(context);

    return jscContextGetOrCreateValue(context, result).leakRef();
}

/**
 * jsc_context_evaluate_in_object:
 * @context: a #JSCContext
 * @code: a JavaScript script to evaluate
 * @length: length of @code, or -1 if @code is a nul-terminated string
 * @object_instance: (nullable): an object instance
 * @object_class: (nullable): a #JSCClass or %NULL to use the default
 * @uri: the source URI
 * @line_number: the starting line number
 * @object: (out) (transfer full): return location for a #JSCValue.
 *
 * Evaluate @code and create an new object where symbols defined in @code will be added as properties,
 * instead of being added to @context global object. The new object is returned as @object parameter.
 * Similar to how jsc_value_new_object() works, if @object_instance is not %NULL @object_class must be provided too.
 * The @line_number is the starting line number in @uri; the value is one-based so the first line is 1.
 * @uri and @line_number will be shown in exceptions and they don't affect the behavior of the script.
 *
 * Returns: (transfer full): a #JSCValue representing the last value generated by the script.
 */
JSCValue* jsc_context_evaluate_in_object(JSCContext* context, const char* code, gssize length, gpointer instance, JSCClass* objectClass, const char* uri, unsigned lineNumber, JSCValue** object)
{
    g_return_val_if_fail(JSC_IS_CONTEXT(context), nullptr);
    g_return_val_if_fail(code, nullptr);
    g_return_val_if_fail(!instance || JSC_IS_CLASS(objectClass), nullptr);
    g_return_val_if_fail(object && !*object, nullptr);

    JSRetainPtr<JSGlobalContextRef> objectContext(Adopt,
        instance ? jscClassCreateContextWithJSWrapper(objectClass, context, instance) : JSGlobalContextCreateInGroup(jscVirtualMachineGetContextGroup(context->priv->vm.get()), nullptr));
    JSC::ExecState* exec = toJS(objectContext.get());
    JSC::VM& vm = exec->vm();
    auto* jsObject = vm.vmEntryGlobalObject(exec);
    jsObject->setGlobalScopeExtension(JSC::JSWithScope::create(vm, jsObject, jsObject->globalScope(), toJS(JSContextGetGlobalObject(context->priv->jsContext.get()))));
    JSValueRef exception = nullptr;
    JSValueRef result = evaluateScriptInContext(objectContext.get(), String::fromUTF8(code, length < 0 ? strlen(code) : length), uri, lineNumber, &exception);
    if (jscContextHandleExceptionIfNeeded(context, exception))
        return jsc_value_new_undefined(context);

    *object = jscContextGetOrCreateValue(context, JSContextGetGlobalObject(objectContext.get())).leakRef();

    return jscContextGetOrCreateValue(context, result).leakRef();
}

/**
 * JSCCheckSyntaxMode:
 * @JSC_CHECK_SYNTAX_MODE_SCRIPT: mode to check syntax of a script
 * @JSC_CHECK_SYNTAX_MODE_MODULE: mode to check syntax of a module
 *
 * Enum values to specify a mode to check for syntax errors in jsc_context_check_syntax().
 */

/**
 * JSCCheckSyntaxResult:
 * @JSC_CHECK_SYNTAX_RESULT_SUCCESS: no errors
 * @JSC_CHECK_SYNTAX_RESULT_RECOVERABLE_ERROR: recoverable syntax error
 * @JSC_CHECK_SYNTAX_RESULT_IRRECOVERABLE_ERROR: irrecoverable syntax error
 * @JSC_CHECK_SYNTAX_RESULT_UNTERMINATED_LITERAL_ERROR: unterminated literal error
 * @JSC_CHECK_SYNTAX_RESULT_OUT_OF_MEMORY_ERROR: out of memory error
 * @JSC_CHECK_SYNTAX_RESULT_STACK_OVERFLOW_ERROR: stack overflow error
 *
 * Enum values to specify the result of jsc_context_check_syntax().
 */

/**
 * jsc_context_check_syntax:
 * @context: a #JSCContext
 * @code: a JavaScript script to check
 * @length: length of @code, or -1 if @code is a nul-terminated string
 * @mode: a #JSCCheckSyntaxMode
 * @uri: the source URI
 * @line_number: the starting line number
 * @exception: (out) (optional) (transfer full): return location for a #JSCException, or %NULL to ignore
 *
 * Check the given @code in @context for syntax errors. The @line_number is the starting line number in @uri;
 * the value is one-based so the first line is 1. @uri and @line_number are only used to fill the @exception.
 * In case of errors @exception will be set to a new #JSCException with the details. You can pass %NULL to
 * @exception to ignore the error details.
 *
 * Returns: a #JSCCheckSyntaxResult
 */
JSCCheckSyntaxResult jsc_context_check_syntax(JSCContext* context, const char* code, gssize length, JSCCheckSyntaxMode mode, const char* uri, unsigned lineNumber, JSCException **exception)
{
    g_return_val_if_fail(JSC_IS_CONTEXT(context), JSC_CHECK_SYNTAX_RESULT_IRRECOVERABLE_ERROR);
    g_return_val_if_fail(code, JSC_CHECK_SYNTAX_RESULT_IRRECOVERABLE_ERROR);
    g_return_val_if_fail(!exception || !*exception, JSC_CHECK_SYNTAX_RESULT_IRRECOVERABLE_ERROR);

    lineNumber = std::max<unsigned>(1, lineNumber);

    auto* jsContext = context->priv->jsContext.get();
    JSC::ExecState* exec = toJS(jsContext);
    JSC::VM& vm = exec->vm();
    JSC::JSLockHolder locker(vm);

    String sourceURLString = uri ? String::fromUTF8(uri) : String();
    JSC::SourceCode source = JSC::makeSource(String::fromUTF8(code, length < 0 ? strlen(code) : length), JSC::SourceOrigin { sourceURLString },
        URL({ }, sourceURLString), TextPosition(OrdinalNumber::fromOneBasedInt(lineNumber), OrdinalNumber()));
    bool success = false;
    JSC::ParserError error;
    switch (mode) {
    case JSC_CHECK_SYNTAX_MODE_SCRIPT:
        success = !!JSC::parse<JSC::ProgramNode>(vm, source, JSC::Identifier(), JSC::JSParserBuiltinMode::NotBuiltin,
            JSC::JSParserStrictMode::NotStrict, JSC::JSParserScriptMode::Classic, JSC::SourceParseMode::ProgramMode, JSC::SuperBinding::NotNeeded, error);
        break;
    case JSC_CHECK_SYNTAX_MODE_MODULE:
        success = !!JSC::parse<JSC::ModuleProgramNode>(vm, source, JSC::Identifier(), JSC::JSParserBuiltinMode::NotBuiltin,
            JSC::JSParserStrictMode::Strict, JSC::JSParserScriptMode::Module, JSC::SourceParseMode::ModuleAnalyzeMode, JSC::SuperBinding::NotNeeded, error);
        break;
    }

    JSCCheckSyntaxResult result = JSC_CHECK_SYNTAX_RESULT_SUCCESS;
    if (success)
        return result;

    switch (error.type()) {
    case JSC::ParserError::ErrorType::SyntaxError: {
        switch (error.syntaxErrorType()) {
        case JSC::ParserError::SyntaxErrorType::SyntaxErrorIrrecoverable:
            result = JSC_CHECK_SYNTAX_RESULT_IRRECOVERABLE_ERROR;
            break;
        case JSC::ParserError::SyntaxErrorType::SyntaxErrorUnterminatedLiteral:
            result = JSC_CHECK_SYNTAX_RESULT_UNTERMINATED_LITERAL_ERROR;
            break;
        case JSC::ParserError::SyntaxErrorType::SyntaxErrorRecoverable:
            result = JSC_CHECK_SYNTAX_RESULT_RECOVERABLE_ERROR;
            break;
        case JSC::ParserError::SyntaxErrorType::SyntaxErrorNone:
            ASSERT_NOT_REACHED();
            break;
        }
        break;
    }
    case JSC::ParserError::ErrorType::StackOverflow:
        result = JSC_CHECK_SYNTAX_RESULT_STACK_OVERFLOW_ERROR;
        break;
    case JSC::ParserError::ErrorType::OutOfMemory:
        result = JSC_CHECK_SYNTAX_RESULT_OUT_OF_MEMORY_ERROR;
        break;
    case JSC::ParserError::ErrorType::EvalError:
    case JSC::ParserError::ErrorType::ErrorNone:
        ASSERT_NOT_REACHED();
        break;
    }

    if (exception) {
        auto* jsError = error.toErrorObject(exec->lexicalGlobalObject(), source);
        *exception = jscExceptionCreate(context, toRef(exec, jsError)).leakRef();
    }

    return result;
}

/**
 * jsc_context_get_global_object:
 * @context: a #JSCContext
 *
 * Get a #JSCValue referencing the @context global object
 *
 * Returns: (transfer full): a #JSCValue
 */
JSCValue* jsc_context_get_global_object(JSCContext* context)
{
    g_return_val_if_fail(JSC_IS_CONTEXT(context), nullptr);

    return jscContextGetOrCreateValue(context, JSContextGetGlobalObject(context->priv->jsContext.get())).leakRef();
}

/**
 * jsc_context_set_value:
 * @context: a #JSCContext
 * @name: the value name
 * @value: a #JSCValue
 *
 * Set a property of @context global object with @name and @value.
 */
void jsc_context_set_value(JSCContext* context, const char* name, JSCValue* value)
{
    g_return_if_fail(JSC_IS_CONTEXT(context));
    g_return_if_fail(name);
    g_return_if_fail(JSC_IS_VALUE(value));

    auto contextObject = jscContextGetOrCreateValue(context, JSContextGetGlobalObject(context->priv->jsContext.get()));
    jsc_value_object_set_property(contextObject.get(), name, value);
}

/**
 * jsc_context_get_value:
 * @context: a #JSCContext
 * @name: the value name
 *
 * Get a property of @context global object with @name.
 *
 * Returns: (transfer full): a #JSCValue
 */
JSCValue* jsc_context_get_value(JSCContext* context, const char* name)
{
    g_return_val_if_fail(JSC_IS_CONTEXT(context), nullptr);
    g_return_val_if_fail(name, nullptr);

    auto contextObject = jscContextGetOrCreateValue(context, JSContextGetGlobalObject(context->priv->jsContext.get()));
    return jsc_value_object_get_property(contextObject.get(), name);
}

/**
 * jsc_context_register_class:
 * @context: a #JSCContext
 * @name: the class name
 * @parent_class: (nullable): a #JSCClass or %NULL
 * @vtable: (nullable): an optional #JSCClassVTable or %NULL
 * @destroy_notify: (nullable): a destroy notifier for class instances
 *
 * Register a custom class in @context using the given @name. If the new class inherits from
 * another #JSCClass, the parent should be passed as @parent_class, otherwise %NULL should be
 * used. The optional @vtable parameter allows to provide a custom implementation for handling
 * the class, for example, to handle external properties not added to the prototype.
 * When an instance of the #JSCClass is cleared in the context, @destroy_notify is called with
 * the instance as parameter.
 *
 * Returns: (transfer none): a #JSCClass
 */
JSCClass* jsc_context_register_class(JSCContext* context, const char* name, JSCClass* parentClass, JSCClassVTable* vtable, GDestroyNotify destroyFunction)
{
    g_return_val_if_fail(JSC_IS_CONTEXT(context), nullptr);
    g_return_val_if_fail(name, nullptr);
    g_return_val_if_fail(!parentClass || JSC_IS_CLASS(parentClass), nullptr);

    auto jscClass = jscClassCreate(context, name, parentClass, vtable, destroyFunction);
    wrapperMap(context).registerClass(jscClass.get());
    return jscClass.get();
}
