/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
 * vim: set ts=8 sts=4 et sw=4 tw=99:
 */

#include "jscompartment.h"
#include "jsfriendapi.h"

#include "jsapi-tests/tests.h"

#include "jscompartmentinlines.h"

using namespace js;

BEGIN_TEST(testArrayBufferView_type)
{
    CHECK((TestViewType<uint8_t,
                        Create<JS_NewUint8Array, 7>,
                        JS_GetObjectAsUint8Array,
                        js::Scalar::Uint8,
                        7, 7>(cx)));

    CHECK((TestViewType<int8_t,
                        Create<JS_NewInt8Array, 33>,
                        JS_GetObjectAsInt8Array,
                        js::Scalar::Int8,
                        33, 33>(cx)));

    CHECK((TestViewType<uint8_t,
                        Create<JS_NewUint8ClampedArray, 7>,
                        JS_GetObjectAsUint8ClampedArray,
                        js::Scalar::Uint8Clamped,
                        7, 7>(cx)));

    CHECK((TestViewType<uint16_t,
                        Create<JS_NewUint16Array, 3>,
                        JS_GetObjectAsUint16Array,
                        js::Scalar::Uint16,
                        3, 6>(cx)));

    CHECK((TestViewType<int16_t,
                        Create<JS_NewInt16Array, 17>,
                        JS_GetObjectAsInt16Array,
                        js::Scalar::Int16,
                        17, 34>(cx)));

    CHECK((TestViewType<uint32_t,
                        Create<JS_NewUint32Array, 15>,
                        JS_GetObjectAsUint32Array,
                        js::Scalar::Uint32,
                        15, 60>(cx)));

    CHECK((TestViewType<int32_t,
                        Create<JS_NewInt32Array, 8>,
                        JS_GetObjectAsInt32Array,
                        js::Scalar::Int32,
                        8, 32>(cx)));

    CHECK((TestViewType<float,
                        Create<JS_NewFloat32Array, 7>,
                        JS_GetObjectAsFloat32Array,
                        js::Scalar::Float32,
                        7, 28>(cx)));

    CHECK((TestViewType<double,
                        Create<JS_NewFloat64Array, 9>,
                        JS_GetObjectAsFloat64Array,
                        js::Scalar::Float64,
                        9, 72>(cx)));

    CHECK((TestViewType<uint8_t,
                        CreateDataView,
                        JS_GetObjectAsArrayBufferView,
                        js::Scalar::MaxTypedArrayViewType,
                        8, 8>(cx)));

    JS::Rooted<JS::Value> hasTypedObject(cx);
    EVAL("typeof TypedObject !== 'undefined'", &hasTypedObject);
    if (hasTypedObject.isTrue()) {
        JS::Rooted<JS::Value> tval(cx);
        EVAL("var T = new TypedObject.StructType({ x: TypedObject.uint32 });\n"
             "new T(new ArrayBuffer(4));",
             &tval);

        JS::Rooted<JSObject*> tobj(cx, &tval.toObject());
        CHECK(!JS_IsArrayBufferViewObject(tobj));
    }

    return true;
}

static JSObject*
CreateDataView(JSContext* cx)
{
    JS::Rooted<JSObject*> buffer(cx, JS_NewArrayBuffer(cx, 8));
    if (!buffer)
        return nullptr;
    return JS_NewDataView(cx, buffer, 0, 8);
}

template<JSObject * CreateTypedArray(JSContext* cx, uint32_t length),
         size_t Length>
static JSObject*
Create(JSContext* cx)
{
    return CreateTypedArray(cx, Length);
}

template<typename T,
         JSObject * CreateViewType(JSContext* cx),
         JSObject * GetObjectAs(JSObject* obj, uint32_t* length, bool* isSharedMemory, T** data),
         js::Scalar::Type ExpectedType,
         uint32_t ExpectedLength,
         uint32_t ExpectedByteLength>
bool TestViewType(JSContext* cx)
{
    JS::Rooted<JSObject*> obj(cx, CreateViewType(cx));
    CHECK(obj);

    CHECK(JS_IsArrayBufferViewObject(obj));

    CHECK(JS_GetArrayBufferViewType(obj) == ExpectedType);

    CHECK(JS_GetArrayBufferViewByteLength(obj) == ExpectedByteLength);

    {
        JS::AutoCheckCannotGC nogc;
        bool shared1;
        T* data1 = static_cast<T*>(JS_GetArrayBufferViewData(obj, &shared1, nogc));

        T* data2;
        bool shared2;
        uint32_t len;
        CHECK(obj == GetObjectAs(obj, &len, &shared2, &data2));
        CHECK(data1 == data2);
        CHECK(shared1 == shared2);
        CHECK(len == ExpectedLength);
    }

    JS::CompartmentOptions options;
    JS::RootedObject otherGlobal(cx, JS_NewGlobalObject(cx, basicGlobalClass(), nullptr, JS::DontFireOnNewGlobalHook, options));
    CHECK(otherGlobal);

    JS::Rooted<JSObject*> buffer(cx);
    {
        AutoCompartment ac(cx, otherGlobal);
        buffer = JS_NewArrayBuffer(cx, 8);
        CHECK(buffer);
        CHECK(buffer->as<ArrayBufferObject>().byteLength() == 8);
    }
    CHECK(buffer->compartment() == otherGlobal->compartment());
    CHECK(JS_WrapObject(cx, &buffer));
    CHECK(buffer->compartment() == global->compartment());

    JS::Rooted<JSObject*> dataview(cx, JS_NewDataView(cx, buffer, 4, 4));
    CHECK(dataview);
    CHECK(dataview->is<ProxyObject>());

    JS::Rooted<JS::Value> val(cx);

    val = ObjectValue(*dataview);
    CHECK(JS_SetProperty(cx, global, "view", val));

    EVAL("view.buffer", &val);
    CHECK(val.toObject().is<ProxyObject>());

    CHECK(dataview->compartment() == global->compartment());
    JS::Rooted<JSObject*> otherView(cx, js::UncheckedUnwrap(dataview));
    CHECK(otherView->compartment() == otherGlobal->compartment());
    JS::Rooted<JSObject*> otherBuffer(cx, js::UncheckedUnwrap(&val.toObject()));
    CHECK(otherBuffer->compartment() == otherGlobal->compartment());

    EVAL("Object.getPrototypeOf(view) === DataView.prototype", &val);
    CHECK(val.toBoolean() == true);

    return true;
}

END_TEST(testArrayBufferView_type)
