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

#ifdef XP_UNIX
#include <fcntl.h>
#include <stdio.h>
#include <string.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>

#include "jsfriendapi.h"
#include "js/StructuredClone.h"
#include "jsapi-tests/tests.h"
#include "vm/ArrayBufferObject.h"

const char test_data[] = "1234567890ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
const char test_filename[] = "temp-bug945152_MappedArrayBuffer";

BEGIN_TEST(testMappedArrayBuffer_bug945152)
{
    TempFile test_file;
    FILE* test_stream = test_file.open(test_filename);
    CHECK(fputs(test_data, test_stream) != EOF);
    test_file.close();

    // Offset 0.
    CHECK(TestCreateObject(0, 12));

    // Aligned offset.
    CHECK(TestCreateObject(8, 12));

    // Unaligned offset.
    CHECK(CreateNewObject(11, 12) == nullptr);

    // Offset + length greater than file size.
    CHECK(CreateNewObject(8, sizeof(test_data) - 7) == nullptr);

    // Release the mapped content.
    CHECK(TestReleaseContents());

    // Neuter mapped array buffer.
    CHECK(TestNeuterObject());

    // Clone mapped array buffer.
    CHECK(TestCloneObject());

    // Steal mapped array buffer contents.
    CHECK(TestStealContents());

    // Transfer mapped array buffer contents.
    CHECK(TestTransferObject());

    test_file.remove();

    return true;
}

JSObject* CreateNewObject(const int offset, const int length)
{
    int fd = open(test_filename, O_RDONLY);
    void* ptr = JS_CreateMappedArrayBufferContents(fd, offset, length);
    close(fd);
    if (!ptr)
        return nullptr;
    JSObject* obj = JS_NewMappedArrayBufferWithContents(cx, length, ptr);
    if (!obj) {
        JS_ReleaseMappedArrayBufferContents(ptr, length);
        return nullptr;
    }
    return obj;
}

bool VerifyObject(JS::HandleObject obj, uint32_t offset, uint32_t length, const bool mapped)
{
    JS::AutoCheckCannotGC nogc;

    CHECK(obj);
    CHECK(JS_IsArrayBufferObject(obj));
    CHECK_EQUAL(JS_GetArrayBufferByteLength(obj), length);
    if (mapped)
        CHECK(JS_IsMappedArrayBufferObject(obj));
    else
        CHECK(!JS_IsMappedArrayBufferObject(obj));
    bool sharedDummy;
    const char* data =
        reinterpret_cast<const char*>(JS_GetArrayBufferData(obj, &sharedDummy, nogc));
    CHECK(data);
    CHECK(memcmp(data, test_data + offset, length) == 0);

    return true;
}

bool TestCreateObject(uint32_t offset, uint32_t length)
{
    JS::RootedObject obj(cx, CreateNewObject(offset, length));
    CHECK(VerifyObject(obj, offset, length, true));

    return true;
}

bool TestReleaseContents()
{
    int fd = open(test_filename, O_RDONLY);
    void* ptr = JS_CreateMappedArrayBufferContents(fd, 0, 12);
    close(fd);
    if (!ptr)
        return false;
    JS_ReleaseMappedArrayBufferContents(ptr, 12);

    return true;
}

bool TestNeuterObject()
{
    JS::RootedObject obj(cx, CreateNewObject(8, 12));
    CHECK(obj);
    JS_NeuterArrayBuffer(cx, obj, ChangeData);
    CHECK(isNeutered(obj));

    return true;
}

bool TestCloneObject()
{
    JS::RootedObject obj1(cx, CreateNewObject(8, 12));
    CHECK(obj1);
    JSAutoStructuredCloneBuffer cloned_buffer;
    JS::RootedValue v1(cx, JS::ObjectValue(*obj1));
    CHECK(cloned_buffer.write(cx, v1, nullptr, nullptr));
    JS::RootedValue v2(cx);
    CHECK(cloned_buffer.read(cx, &v2, nullptr, nullptr));
    JS::RootedObject obj2(cx, v2.toObjectOrNull());
    CHECK(VerifyObject(obj2, 8, 12, false));

    return true;
}

bool TestStealContents()
{
    JS::RootedObject obj(cx, CreateNewObject(8, 12));
    CHECK(obj);
    void* contents = JS_StealArrayBufferContents(cx, obj);
    CHECK(contents);
    CHECK(memcmp(contents, test_data + 8, 12) == 0);
    CHECK(isNeutered(obj));

    return true;
}

bool TestTransferObject()
{
    JS::RootedObject obj1(cx, CreateNewObject(8, 12));
    CHECK(obj1);
    JS::RootedValue v1(cx, JS::ObjectValue(*obj1));

    // Create an Array of transferable values.
    JS::AutoValueVector argv(cx);
    argv.append(v1);
    JS::RootedObject obj(cx, JS_NewArrayObject(cx, JS::HandleValueArray::subarray(argv, 0, 1)));
    CHECK(obj);
    JS::RootedValue transferable(cx, JS::ObjectValue(*obj));

    JSAutoStructuredCloneBuffer cloned_buffer;
    CHECK(cloned_buffer.write(cx, v1, transferable, nullptr, nullptr));
    JS::RootedValue v2(cx);
    CHECK(cloned_buffer.read(cx, &v2, nullptr, nullptr));
    JS::RootedObject obj2(cx, v2.toObjectOrNull());
    CHECK(VerifyObject(obj2, 8, 12, true));
    CHECK(isNeutered(obj1));

    return true;
}

bool isNeutered(JS::HandleObject obj)
{
    JS::RootedValue v(cx);
    return JS_GetProperty(cx, obj, "byteLength", &v) && v.toInt32() == 0;
}

static void GC(JSContext* cx)
{
    JS_GC(JS_GetRuntime(cx));
    // Trigger another to wait for background finalization to end.
    JS_GC(JS_GetRuntime(cx));
}

END_TEST(testMappedArrayBuffer_bug945152)
#endif
