/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
 * vim: set ts=8 sts=4 et sw=4 tw=99:
 *
 * Tests JS_TransplantObject
 */
/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

#include "jsobj.h"
#include "jswrapper.h"

#include "jsapi-tests/tests.h"

#include "vm/ProxyObject.h"

const js::Class OuterWrapperClass =
    PROXY_CLASS_WITH_EXT(
        "Proxy",
        0, /* additional class flags */
        PROXY_MAKE_EXT(
            false,   /* isWrappedNative */
            nullptr  /* objectMoved */
        ));

static JSObject*
wrap(JSContext* cx, JS::HandleObject toWrap, JS::HandleObject target)
{
    JSAutoCompartment ac(cx, target);
    JS::RootedObject wrapper(cx, toWrap);
    if (!JS_WrapObject(cx, &wrapper))
        return nullptr;
    return wrapper;
}

static JSObject*
PreWrap(JSContext* cx, JS::HandleObject scope, JS::HandleObject obj,
        JS::HandleObject objectPassedToWrap)
{
    JS_GC(JS_GetRuntime(cx));
    return obj;
}

static JSObject*
Wrap(JSContext* cx, JS::HandleObject existing, JS::HandleObject obj)
{
    return js::Wrapper::New(cx, obj, &js::CrossCompartmentWrapper::singleton);
}

static const JSWrapObjectCallbacks WrapObjectCallbacks = {
    Wrap,
    PreWrap
};

BEGIN_TEST(testBug604087)
{
    js::SetWindowProxyClass(cx->runtime(), &OuterWrapperClass);

    js::WrapperOptions options;
    options.setClass(&OuterWrapperClass);
    options.setSingleton(true);
    JS::RootedObject outerObj(cx, js::Wrapper::New(cx, global, &js::Wrapper::singleton, options));
    JS::RootedObject compartment2(cx, JS_NewGlobalObject(cx, getGlobalClass(), nullptr, JS::FireOnNewGlobalHook));
    JS::RootedObject compartment3(cx, JS_NewGlobalObject(cx, getGlobalClass(), nullptr, JS::FireOnNewGlobalHook));
    JS::RootedObject compartment4(cx, JS_NewGlobalObject(cx, getGlobalClass(), nullptr, JS::FireOnNewGlobalHook));

    JS::RootedObject c2wrapper(cx, wrap(cx, outerObj, compartment2));
    CHECK(c2wrapper);
    c2wrapper->as<js::ProxyObject>().setExtra(0, js::Int32Value(2));

    JS::RootedObject c3wrapper(cx, wrap(cx, outerObj, compartment3));
    CHECK(c3wrapper);
    c3wrapper->as<js::ProxyObject>().setExtra(0, js::Int32Value(3));

    JS::RootedObject c4wrapper(cx, wrap(cx, outerObj, compartment4));
    CHECK(c4wrapper);
    c4wrapper->as<js::ProxyObject>().setExtra(0, js::Int32Value(4));
    compartment4 = c4wrapper = nullptr;

    JS::RootedObject next(cx);
    {
        JSAutoCompartment ac(cx, compartment2);
        next = js::Wrapper::New(cx, compartment2, &js::Wrapper::singleton, options);
        CHECK(next);
    }

    JS_SetWrapObjectCallbacks(JS_GetRuntime(cx), &WrapObjectCallbacks);
    CHECK(JS_TransplantObject(cx, outerObj, next));
    return true;
}
END_TEST(testBug604087)
