// Copyright 2019 The Dawn Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#include "tests/unittests/wire/WireTest.h"

using namespace testing;
using namespace dawn_wire;

namespace {

    // Mock classes to add expectations on the wire calling callbacks
    class MockBufferMapReadCallback {
      public:
        MOCK_METHOD4(Call,
                     void(DawnBufferMapAsyncStatus status,
                          const uint32_t* ptr,
                          uint64_t dataLength,
                          void* userdata));
    };

    std::unique_ptr<StrictMock<MockBufferMapReadCallback>> mockBufferMapReadCallback;
    void ToMockBufferMapReadCallback(DawnBufferMapAsyncStatus status,
                                     const void* ptr,
                                     uint64_t dataLength,
                                     void* userdata) {
        // Assume the data is uint32_t to make writing matchers easier
        mockBufferMapReadCallback->Call(status, static_cast<const uint32_t*>(ptr), dataLength,
                                        userdata);
    }

    class MockBufferMapWriteCallback {
      public:
        MOCK_METHOD4(Call,
                     void(DawnBufferMapAsyncStatus status,
                          uint32_t* ptr,
                          uint64_t dataLength,
                          void* userdata));
    };

    std::unique_ptr<StrictMock<MockBufferMapWriteCallback>> mockBufferMapWriteCallback;
    uint32_t* lastMapWritePointer = nullptr;
    void ToMockBufferMapWriteCallback(DawnBufferMapAsyncStatus status,
                                      void* ptr,
                                      uint64_t dataLength,
                                      void* userdata) {
        // Assume the data is uint32_t to make writing matchers easier
        lastMapWritePointer = static_cast<uint32_t*>(ptr);
        mockBufferMapWriteCallback->Call(status, lastMapWritePointer, dataLength, userdata);
    }

    class MockBufferCreateMappedCallback {
      public:
        MOCK_METHOD5(Call,
                     void(DawnBufferMapAsyncStatus status,
                          DawnBuffer buffer,
                          uint32_t* ptr,
                          uint64_t dataLength,
                          void* userdata));
    };

    std::unique_ptr<StrictMock<MockBufferCreateMappedCallback>> mockCreateBufferMappedCallback;
    uint32_t* lastCreateMappedPointer = nullptr;
    void ToMockCreateBufferMappedCallback(DawnBufferMapAsyncStatus status,
                                          DawnCreateBufferMappedResult result,
                                          void* userdata) {
        // Assume the data is uint32_t to make writing matchers easier
        lastCreateMappedPointer = static_cast<uint32_t*>(result.data);
        // Unpack DawnCreateBufferMappedResult to make writing matchers easier
        mockCreateBufferMappedCallback->Call(status, result.buffer, lastCreateMappedPointer,
                                             result.dataLength, userdata);
    }

}  // anonymous namespace

class WireBufferMappingTests : public WireTest {
  public:
    WireBufferMappingTests() {
    }
    ~WireBufferMappingTests() override = default;

    void SetUp() override {
        WireTest::SetUp();

        mockBufferMapReadCallback = std::make_unique<StrictMock<MockBufferMapReadCallback>>();
        mockBufferMapWriteCallback = std::make_unique<StrictMock<MockBufferMapWriteCallback>>();
        mockCreateBufferMappedCallback =
            std::make_unique<StrictMock<MockBufferCreateMappedCallback>>();

        DawnBufferDescriptor descriptor;
        descriptor.nextInChain = nullptr;
        descriptor.label = nullptr;
        descriptor.size = kBufferSize;

        apiBuffer = api.GetNewBuffer();
        buffer = dawnDeviceCreateBuffer(device, &descriptor);

        EXPECT_CALL(api, DeviceCreateBuffer(apiDevice, _))
            .WillOnce(Return(apiBuffer))
            .RetiresOnSaturation();
        FlushClient();
    }

    void TearDown() override {
        WireTest::TearDown();

        // Delete mocks so that expectations are checked
        mockBufferMapReadCallback = nullptr;
        mockBufferMapWriteCallback = nullptr;
        mockCreateBufferMappedCallback = nullptr;
    }

    void FlushServer() {
        WireTest::FlushServer();

        Mock::VerifyAndClearExpectations(&mockBufferMapReadCallback);
        Mock::VerifyAndClearExpectations(&mockBufferMapWriteCallback);
        Mock::VerifyAndClearExpectations(&mockCreateBufferMappedCallback);
    }

  protected:
    static constexpr uint64_t kBufferSize = sizeof(uint32_t);
    // A successfully created buffer
    DawnBuffer buffer;
    DawnBuffer apiBuffer;
};

// MapRead-specific tests

// Check mapping for reading a succesfully created buffer
TEST_F(WireBufferMappingTests, MappingForReadSuccessBuffer) {
    dawnBufferMapReadAsync(buffer, ToMockBufferMapReadCallback, nullptr);

    uint32_t bufferContent = 31337;
    EXPECT_CALL(api, OnBufferMapReadAsyncCallback(apiBuffer, _, _))
        .WillOnce(InvokeWithoutArgs([&]() {
            api.CallMapReadCallback(apiBuffer, DAWN_BUFFER_MAP_ASYNC_STATUS_SUCCESS, &bufferContent,
                                    kBufferSize);
        }));

    FlushClient();

    EXPECT_CALL(*mockBufferMapReadCallback, Call(DAWN_BUFFER_MAP_ASYNC_STATUS_SUCCESS,
                                                 Pointee(Eq(bufferContent)), kBufferSize, _))
        .Times(1);

    FlushServer();

    dawnBufferUnmap(buffer);
    EXPECT_CALL(api, BufferUnmap(apiBuffer)).Times(1);

    FlushClient();
}

// Check that things work correctly when a validation error happens when mapping the buffer for
// reading
TEST_F(WireBufferMappingTests, ErrorWhileMappingForRead) {
    dawnBufferMapReadAsync(buffer, ToMockBufferMapReadCallback, nullptr);

    EXPECT_CALL(api, OnBufferMapReadAsyncCallback(apiBuffer, _, _))
        .WillOnce(InvokeWithoutArgs([&]() {
            api.CallMapReadCallback(apiBuffer, DAWN_BUFFER_MAP_ASYNC_STATUS_ERROR, nullptr, 0);
        }));

    FlushClient();

    EXPECT_CALL(*mockBufferMapReadCallback, Call(DAWN_BUFFER_MAP_ASYNC_STATUS_ERROR, nullptr, 0, _))
        .Times(1);

    FlushServer();
}

// Check that the map read callback is called with UNKNOWN when the buffer is destroyed before the
// request is finished
TEST_F(WireBufferMappingTests, DestroyBeforeReadRequestEnd) {
    dawnBufferMapReadAsync(buffer, ToMockBufferMapReadCallback, nullptr);

    // Return success
    EXPECT_CALL(api, OnBufferMapReadAsyncCallback(apiBuffer, _, _))
        .WillOnce(InvokeWithoutArgs([&]() {
            api.CallMapReadCallback(apiBuffer, DAWN_BUFFER_MAP_ASYNC_STATUS_SUCCESS, nullptr, 0);
        }));

    // Destroy before the client gets the success, so the callback is called with unknown.
    EXPECT_CALL(*mockBufferMapReadCallback,
                Call(DAWN_BUFFER_MAP_ASYNC_STATUS_UNKNOWN, nullptr, 0, _))
        .Times(1);
    dawnBufferRelease(buffer);
    EXPECT_CALL(api, BufferRelease(apiBuffer));

    FlushClient();
    FlushServer();
}

// Check the map read callback is called with UNKNOWN when the map request would have worked, but
// Unmap was called
TEST_F(WireBufferMappingTests, UnmapCalledTooEarlyForRead) {
    dawnBufferMapReadAsync(buffer, ToMockBufferMapReadCallback, nullptr);

    uint32_t bufferContent = 31337;
    EXPECT_CALL(api, OnBufferMapReadAsyncCallback(apiBuffer, _, _))
        .WillOnce(InvokeWithoutArgs([&]() {
            api.CallMapReadCallback(apiBuffer, DAWN_BUFFER_MAP_ASYNC_STATUS_SUCCESS, &bufferContent,
                                    kBufferSize);
        }));

    FlushClient();

    // Oh no! We are calling Unmap too early!
    EXPECT_CALL(*mockBufferMapReadCallback,
                Call(DAWN_BUFFER_MAP_ASYNC_STATUS_UNKNOWN, nullptr, 0, _))
        .Times(1);
    dawnBufferUnmap(buffer);

    // The callback shouldn't get called, even when the request succeeded on the server side
    FlushServer();
}

// Check that an error map read callback gets nullptr while a buffer is already mapped
TEST_F(WireBufferMappingTests, MappingForReadingErrorWhileAlreadyMappedGetsNullptr) {
    // Successful map
    dawnBufferMapReadAsync(buffer, ToMockBufferMapReadCallback, nullptr);

    uint32_t bufferContent = 31337;
    EXPECT_CALL(api, OnBufferMapReadAsyncCallback(apiBuffer, _, _))
        .WillOnce(InvokeWithoutArgs([&]() {
            api.CallMapReadCallback(apiBuffer, DAWN_BUFFER_MAP_ASYNC_STATUS_SUCCESS, &bufferContent,
                                    kBufferSize);
        }))
        .RetiresOnSaturation();

    FlushClient();

    EXPECT_CALL(*mockBufferMapReadCallback, Call(DAWN_BUFFER_MAP_ASYNC_STATUS_SUCCESS,
                                                 Pointee(Eq(bufferContent)), kBufferSize, _))
        .Times(1);

    FlushServer();

    // Map failure while the buffer is already mapped
    dawnBufferMapReadAsync(buffer, ToMockBufferMapReadCallback, nullptr);
    EXPECT_CALL(api, OnBufferMapReadAsyncCallback(apiBuffer, _, _))
        .WillOnce(InvokeWithoutArgs([&]() {
            api.CallMapReadCallback(apiBuffer, DAWN_BUFFER_MAP_ASYNC_STATUS_ERROR, nullptr, 0);
        }));

    FlushClient();

    EXPECT_CALL(*mockBufferMapReadCallback, Call(DAWN_BUFFER_MAP_ASYNC_STATUS_ERROR, nullptr, 0, _))
        .Times(1);

    FlushServer();
}

// Test that the MapReadCallback isn't fired twice when unmap() is called inside the callback
TEST_F(WireBufferMappingTests, UnmapInsideMapReadCallback) {
    dawnBufferMapReadAsync(buffer, ToMockBufferMapReadCallback, nullptr);

    uint32_t bufferContent = 31337;
    EXPECT_CALL(api, OnBufferMapReadAsyncCallback(apiBuffer, _, _))
        .WillOnce(InvokeWithoutArgs([&]() {
            api.CallMapReadCallback(apiBuffer, DAWN_BUFFER_MAP_ASYNC_STATUS_SUCCESS, &bufferContent,
                                    kBufferSize);
        }));

    FlushClient();

    EXPECT_CALL(*mockBufferMapReadCallback, Call(DAWN_BUFFER_MAP_ASYNC_STATUS_SUCCESS,
                                                 Pointee(Eq(bufferContent)), kBufferSize, _))
        .WillOnce(InvokeWithoutArgs([&]() { dawnBufferUnmap(buffer); }));

    FlushServer();

    EXPECT_CALL(api, BufferUnmap(apiBuffer)).Times(1);

    FlushClient();
}

// Test that the MapReadCallback isn't fired twice the buffer external refcount reaches 0 in the
// callback
TEST_F(WireBufferMappingTests, DestroyInsideMapReadCallback) {
    dawnBufferMapReadAsync(buffer, ToMockBufferMapReadCallback, nullptr);

    uint32_t bufferContent = 31337;
    EXPECT_CALL(api, OnBufferMapReadAsyncCallback(apiBuffer, _, _))
        .WillOnce(InvokeWithoutArgs([&]() {
            api.CallMapReadCallback(apiBuffer, DAWN_BUFFER_MAP_ASYNC_STATUS_SUCCESS, &bufferContent,
                                    kBufferSize);
        }));

    FlushClient();

    EXPECT_CALL(*mockBufferMapReadCallback, Call(DAWN_BUFFER_MAP_ASYNC_STATUS_SUCCESS,
                                                 Pointee(Eq(bufferContent)), kBufferSize, _))
        .WillOnce(InvokeWithoutArgs([&]() { dawnBufferRelease(buffer); }));

    FlushServer();

    EXPECT_CALL(api, BufferRelease(apiBuffer));

    FlushClient();
}

// MapWrite-specific tests

// Check mapping for writing a succesfully created buffer
TEST_F(WireBufferMappingTests, MappingForWriteSuccessBuffer) {
    dawnBufferMapWriteAsync(buffer, ToMockBufferMapWriteCallback, nullptr);

    uint32_t serverBufferContent = 31337;
    uint32_t updatedContent = 4242;
    uint32_t zero = 0;

    EXPECT_CALL(api, OnBufferMapWriteAsyncCallback(apiBuffer, _, _))
        .WillOnce(InvokeWithoutArgs([&]() {
            api.CallMapWriteCallback(apiBuffer, DAWN_BUFFER_MAP_ASYNC_STATUS_SUCCESS,
                                     &serverBufferContent, kBufferSize);
        }));

    FlushClient();

    // The map write callback always gets a buffer full of zeroes.
    EXPECT_CALL(*mockBufferMapWriteCallback,
                Call(DAWN_BUFFER_MAP_ASYNC_STATUS_SUCCESS, Pointee(Eq(zero)), kBufferSize, _))
        .Times(1);

    FlushServer();

    // Write something to the mapped pointer
    *lastMapWritePointer = updatedContent;

    dawnBufferUnmap(buffer);
    EXPECT_CALL(api, BufferUnmap(apiBuffer)).Times(1);

    FlushClient();

    // After the buffer is unmapped, the content of the buffer is updated on the server
    ASSERT_EQ(serverBufferContent, updatedContent);
}

// Check that things work correctly when a validation error happens when mapping the buffer for
// writing
TEST_F(WireBufferMappingTests, ErrorWhileMappingForWrite) {
    dawnBufferMapWriteAsync(buffer, ToMockBufferMapWriteCallback, nullptr);

    EXPECT_CALL(api, OnBufferMapWriteAsyncCallback(apiBuffer, _, _))
        .WillOnce(InvokeWithoutArgs([&]() {
            api.CallMapWriteCallback(apiBuffer, DAWN_BUFFER_MAP_ASYNC_STATUS_ERROR, nullptr, 0);
        }));

    FlushClient();

    EXPECT_CALL(*mockBufferMapWriteCallback,
                Call(DAWN_BUFFER_MAP_ASYNC_STATUS_ERROR, nullptr, 0, _))
        .Times(1);

    FlushServer();
}

// Check that the map write callback is called with UNKNOWN when the buffer is destroyed before the
// request is finished
TEST_F(WireBufferMappingTests, DestroyBeforeWriteRequestEnd) {
    dawnBufferMapWriteAsync(buffer, ToMockBufferMapWriteCallback, nullptr);

    // Return success
    EXPECT_CALL(api, OnBufferMapWriteAsyncCallback(apiBuffer, _, _))
        .WillOnce(InvokeWithoutArgs([&]() {
            api.CallMapWriteCallback(apiBuffer, DAWN_BUFFER_MAP_ASYNC_STATUS_SUCCESS, nullptr, 0);
        }));

    // Destroy before the client gets the success, so the callback is called with unknown.
    EXPECT_CALL(*mockBufferMapWriteCallback,
                Call(DAWN_BUFFER_MAP_ASYNC_STATUS_UNKNOWN, nullptr, 0, _))
        .Times(1);
    dawnBufferRelease(buffer);
    EXPECT_CALL(api, BufferRelease(apiBuffer));

    FlushClient();
    FlushServer();
}

// Check the map read callback is called with UNKNOWN when the map request would have worked, but
// Unmap was called
TEST_F(WireBufferMappingTests, UnmapCalledTooEarlyForWrite) {
    dawnBufferMapWriteAsync(buffer, ToMockBufferMapWriteCallback, nullptr);

    uint32_t bufferContent = 31337;
    EXPECT_CALL(api, OnBufferMapWriteAsyncCallback(apiBuffer, _, _))
        .WillOnce(InvokeWithoutArgs([&]() {
            api.CallMapWriteCallback(apiBuffer, DAWN_BUFFER_MAP_ASYNC_STATUS_SUCCESS,
                                     &bufferContent, kBufferSize);
        }));

    FlushClient();

    // Oh no! We are calling Unmap too early!
    EXPECT_CALL(*mockBufferMapWriteCallback,
                Call(DAWN_BUFFER_MAP_ASYNC_STATUS_UNKNOWN, nullptr, 0, _))
        .Times(1);
    dawnBufferUnmap(buffer);

    // The callback shouldn't get called, even when the request succeeded on the server side
    FlushServer();
}

// Check that an error map read callback gets nullptr while a buffer is already mapped
TEST_F(WireBufferMappingTests, MappingForWritingErrorWhileAlreadyMappedGetsNullptr) {
    // Successful map
    dawnBufferMapWriteAsync(buffer, ToMockBufferMapWriteCallback, nullptr);

    uint32_t bufferContent = 31337;
    uint32_t zero = 0;
    EXPECT_CALL(api, OnBufferMapWriteAsyncCallback(apiBuffer, _, _))
        .WillOnce(InvokeWithoutArgs([&]() {
            api.CallMapWriteCallback(apiBuffer, DAWN_BUFFER_MAP_ASYNC_STATUS_SUCCESS,
                                     &bufferContent, kBufferSize);
        }))
        .RetiresOnSaturation();

    FlushClient();

    EXPECT_CALL(*mockBufferMapWriteCallback,
                Call(DAWN_BUFFER_MAP_ASYNC_STATUS_SUCCESS, Pointee(Eq(zero)), kBufferSize, _))
        .Times(1);

    FlushServer();

    // Map failure while the buffer is already mapped
    dawnBufferMapWriteAsync(buffer, ToMockBufferMapWriteCallback, nullptr);
    EXPECT_CALL(api, OnBufferMapWriteAsyncCallback(apiBuffer, _, _))
        .WillOnce(InvokeWithoutArgs([&]() {
            api.CallMapWriteCallback(apiBuffer, DAWN_BUFFER_MAP_ASYNC_STATUS_ERROR, nullptr, 0);
        }));

    FlushClient();

    EXPECT_CALL(*mockBufferMapWriteCallback,
                Call(DAWN_BUFFER_MAP_ASYNC_STATUS_ERROR, nullptr, 0, _))
        .Times(1);

    FlushServer();
}

// Test that the MapWriteCallback isn't fired twice when unmap() is called inside the callback
TEST_F(WireBufferMappingTests, UnmapInsideMapWriteCallback) {
    dawnBufferMapWriteAsync(buffer, ToMockBufferMapWriteCallback, nullptr);

    uint32_t bufferContent = 31337;
    uint32_t zero = 0;
    EXPECT_CALL(api, OnBufferMapWriteAsyncCallback(apiBuffer, _, _))
        .WillOnce(InvokeWithoutArgs([&]() {
            api.CallMapWriteCallback(apiBuffer, DAWN_BUFFER_MAP_ASYNC_STATUS_SUCCESS,
                                     &bufferContent, kBufferSize);
        }));

    FlushClient();

    EXPECT_CALL(*mockBufferMapWriteCallback,
                Call(DAWN_BUFFER_MAP_ASYNC_STATUS_SUCCESS, Pointee(Eq(zero)), kBufferSize, _))
        .WillOnce(InvokeWithoutArgs([&]() { dawnBufferUnmap(buffer); }));

    FlushServer();

    EXPECT_CALL(api, BufferUnmap(apiBuffer)).Times(1);

    FlushClient();
}

// Test that the MapWriteCallback isn't fired twice the buffer external refcount reaches 0 in the
// callback
TEST_F(WireBufferMappingTests, DestroyInsideMapWriteCallback) {
    dawnBufferMapWriteAsync(buffer, ToMockBufferMapWriteCallback, nullptr);

    uint32_t bufferContent = 31337;
    uint32_t zero = 0;
    EXPECT_CALL(api, OnBufferMapWriteAsyncCallback(apiBuffer, _, _))
        .WillOnce(InvokeWithoutArgs([&]() {
            api.CallMapWriteCallback(apiBuffer, DAWN_BUFFER_MAP_ASYNC_STATUS_SUCCESS,
                                     &bufferContent, kBufferSize);
        }));

    FlushClient();

    EXPECT_CALL(*mockBufferMapWriteCallback,
                Call(DAWN_BUFFER_MAP_ASYNC_STATUS_SUCCESS, Pointee(Eq(zero)), kBufferSize, _))
        .WillOnce(InvokeWithoutArgs([&]() { dawnBufferRelease(buffer); }));

    FlushServer();

    EXPECT_CALL(api, BufferRelease(apiBuffer));

    FlushClient();
}

// Test successful CreateBufferMapped
TEST_F(WireBufferMappingTests, CreateBufferMappedSuccess) {
    DawnBufferDescriptor descriptor;
    descriptor.nextInChain = nullptr;
    descriptor.label = nullptr;
    descriptor.size = 4;

    DawnBuffer apiBuffer = api.GetNewBuffer();
    DawnCreateBufferMappedResult apiResult;
    uint32_t apiBufferData = 1234;
    apiResult.buffer = apiBuffer;
    apiResult.data = reinterpret_cast<uint8_t*>(&apiBufferData);
    apiResult.dataLength = 4;

    DawnCreateBufferMappedResult result = dawnDeviceCreateBufferMapped(device, &descriptor);

    EXPECT_CALL(api, DeviceCreateBufferMapped(apiDevice, _))
        .WillOnce(Return(apiResult))
        .RetiresOnSaturation();

    FlushClient();

    dawnBufferUnmap(result.buffer);
    EXPECT_CALL(api, BufferUnmap(apiBuffer)).Times(1);

    FlushClient();
}

// Test that releasing after CreateBufferMapped does not call Unmap
TEST_F(WireBufferMappingTests, ReleaseAfterCreateBufferMapped) {
    DawnBufferDescriptor descriptor;
    descriptor.nextInChain = nullptr;
    descriptor.label = nullptr;
    descriptor.size = 4;

    DawnBuffer apiBuffer = api.GetNewBuffer();
    DawnCreateBufferMappedResult apiResult;
    uint32_t apiBufferData = 1234;
    apiResult.buffer = apiBuffer;
    apiResult.data = reinterpret_cast<uint8_t*>(&apiBufferData);
    apiResult.dataLength = 4;

    DawnCreateBufferMappedResult result = dawnDeviceCreateBufferMapped(device, &descriptor);

    EXPECT_CALL(api, DeviceCreateBufferMapped(apiDevice, _))
        .WillOnce(Return(apiResult))
        .RetiresOnSaturation();

    FlushClient();

    dawnBufferRelease(result.buffer);
    EXPECT_CALL(api, BufferRelease(apiBuffer)).Times(1);

    FlushClient();
}

// Test that it is valid to map a buffer after CreateBufferMapped and Unmap
TEST_F(WireBufferMappingTests, CreateBufferMappedThenMapSuccess) {
    DawnBufferDescriptor descriptor;
    descriptor.nextInChain = nullptr;
    descriptor.label = nullptr;
    descriptor.size = 4;

    DawnBuffer apiBuffer = api.GetNewBuffer();
    DawnCreateBufferMappedResult apiResult;
    uint32_t apiBufferData = 9863;
    apiResult.buffer = apiBuffer;
    apiResult.data = reinterpret_cast<uint8_t*>(&apiBufferData);
    apiResult.dataLength = 4;

    DawnCreateBufferMappedResult result = dawnDeviceCreateBufferMapped(device, &descriptor);

    EXPECT_CALL(api, DeviceCreateBufferMapped(apiDevice, _))
        .WillOnce(Return(apiResult))
        .RetiresOnSaturation();

    FlushClient();

    dawnBufferUnmap(result.buffer);
    EXPECT_CALL(api, BufferUnmap(apiBuffer)).Times(1);

    FlushClient();

    dawnBufferMapWriteAsync(result.buffer, ToMockBufferMapWriteCallback, nullptr);

    uint32_t zero = 0;
    EXPECT_CALL(api, OnBufferMapWriteAsyncCallback(apiBuffer, _, _))
        .WillOnce(InvokeWithoutArgs([&]() {
            api.CallMapWriteCallback(apiBuffer, DAWN_BUFFER_MAP_ASYNC_STATUS_SUCCESS,
                                     &apiBufferData, kBufferSize);
        }));

    FlushClient();

    EXPECT_CALL(*mockBufferMapWriteCallback,
                Call(DAWN_BUFFER_MAP_ASYNC_STATUS_SUCCESS, Pointee(Eq(zero)), kBufferSize, _))
        .Times(1);

    FlushServer();
}

// Test that it is invalid to map a buffer after CreateBufferMapped before Unmap
TEST_F(WireBufferMappingTests, CreateBufferMappedThenMapFailure) {
    DawnBufferDescriptor descriptor;
    descriptor.nextInChain = nullptr;
    descriptor.label = nullptr;
    descriptor.size = 4;

    DawnBuffer apiBuffer = api.GetNewBuffer();
    DawnCreateBufferMappedResult apiResult;
    uint32_t apiBufferData = 9863;
    apiResult.buffer = apiBuffer;
    apiResult.data = reinterpret_cast<uint8_t*>(&apiBufferData);
    apiResult.dataLength = 4;

    DawnCreateBufferMappedResult result = dawnDeviceCreateBufferMapped(device, &descriptor);

    EXPECT_CALL(api, DeviceCreateBufferMapped(apiDevice, _))
        .WillOnce(Return(apiResult))
        .RetiresOnSaturation();

    FlushClient();

    dawnBufferMapWriteAsync(result.buffer, ToMockBufferMapWriteCallback, nullptr);

    EXPECT_CALL(api, OnBufferMapWriteAsyncCallback(apiBuffer, _, _))
        .WillOnce(InvokeWithoutArgs([&]() {
            api.CallMapWriteCallback(apiBuffer, DAWN_BUFFER_MAP_ASYNC_STATUS_ERROR, nullptr, 0);
        }));

    FlushClient();

    EXPECT_CALL(*mockBufferMapWriteCallback,
                Call(DAWN_BUFFER_MAP_ASYNC_STATUS_ERROR, nullptr, 0, _))
        .Times(1);

    FlushServer();

    dawnBufferUnmap(result.buffer);
    EXPECT_CALL(api, BufferUnmap(apiBuffer)).Times(1);

    FlushClient();
}

// Test successful CreateBufferMappedAsync
TEST_F(WireBufferMappingTests, CreateBufferMappedAsyncSuccess) {
    DawnBufferDescriptor descriptor;
    descriptor.nextInChain = nullptr;
    descriptor.label = nullptr;
    descriptor.size = kBufferSize;

    DawnCreateBufferMappedResult apiResult;
    uint32_t serverBufferContent = 31337;
    apiResult.buffer = apiBuffer;
    apiResult.data = reinterpret_cast<uint8_t*>(&serverBufferContent);
    apiResult.dataLength = kBufferSize;

    uint32_t updatedContent = 4242;
    uint32_t zero = 0;

    dawnDeviceCreateBufferMappedAsync(device, &descriptor, ToMockCreateBufferMappedCallback, nullptr);

    EXPECT_CALL(api, DeviceCreateBufferMapped(apiDevice, _))
        .WillOnce(Return(apiResult))
        .RetiresOnSaturation();

    FlushClient();

    DawnBuffer buffer;
    // The callback always gets a buffer full of zeroes.
    EXPECT_CALL(*mockCreateBufferMappedCallback,
                Call(DAWN_BUFFER_MAP_ASYNC_STATUS_SUCCESS, _, Pointee(Eq(zero)), kBufferSize, _))
        .WillOnce(::testing::SaveArg<1>(&buffer));

    FlushServer();

    // Write something to the mapped pointer
    *lastCreateMappedPointer = updatedContent;

    dawnBufferUnmap(buffer);
    EXPECT_CALL(api, BufferUnmap(apiBuffer)).Times(1);

    FlushClient();

    // After the buffer is unmapped, the content of the buffer is updated on the server
    ASSERT_EQ(serverBufferContent, updatedContent);
}

// Test CreateBufferMappedAsync with map error
TEST_F(WireBufferMappingTests, CreateBufferMappedAsyncMapError) {
    DawnBufferDescriptor descriptor;
    descriptor.nextInChain = nullptr;
    descriptor.label = nullptr;

    DawnCreateBufferMappedResult apiResult;
    apiResult.buffer = apiBuffer;
    apiResult.data = nullptr;  // error mapping
    apiResult.dataLength = kBufferSize;

    dawnDeviceCreateBufferMappedAsync(device, &descriptor, ToMockCreateBufferMappedCallback, nullptr);

    EXPECT_CALL(api, DeviceCreateBufferMapped(apiDevice, _))
        .WillOnce(Return(apiResult))
        .RetiresOnSaturation();

    FlushClient();

    DawnBuffer buffer;
    EXPECT_CALL(*mockCreateBufferMappedCallback,
                Call(DAWN_BUFFER_MAP_ASYNC_STATUS_ERROR, _, nullptr, 0, _))
        .WillOnce(::testing::SaveArg<1>(&buffer));

    FlushServer();

    dawnBufferUnmap(buffer);
    EXPECT_CALL(api, BufferUnmap(apiBuffer)).Times(1);

    FlushClient();
}

// Test that the CreateBufferMappedCallback isn't fired twice when unmap() is called inside the
// callback
TEST_F(WireBufferMappingTests, UnmapInsideCreateBufferMappedAsyncCallback) {
    DawnBufferDescriptor descriptor;
    descriptor.nextInChain = nullptr;
    descriptor.label = nullptr;
    descriptor.size = kBufferSize;

    DawnCreateBufferMappedResult apiResult;
    uint32_t serverBufferContent = 31337;
    apiResult.buffer = apiBuffer;
    apiResult.data = reinterpret_cast<uint8_t*>(&serverBufferContent);
    apiResult.dataLength = kBufferSize;

    uint32_t zero = 0;

    dawnDeviceCreateBufferMappedAsync(device, &descriptor, ToMockCreateBufferMappedCallback, nullptr);

    EXPECT_CALL(api, DeviceCreateBufferMapped(apiDevice, _))
        .WillOnce(Return(apiResult))
        .RetiresOnSaturation();

    FlushClient();

    DawnBuffer buffer;
    // The callback always gets a buffer full of zeroes.
    EXPECT_CALL(*mockCreateBufferMappedCallback,
                Call(DAWN_BUFFER_MAP_ASYNC_STATUS_SUCCESS, _, Pointee(Eq(zero)), kBufferSize, _))
        .WillOnce(DoAll(::testing::SaveArg<1>(&buffer),
                        InvokeWithoutArgs([&]() { dawnBufferUnmap(buffer); })));

    FlushServer();

    EXPECT_CALL(api, BufferUnmap(apiBuffer)).Times(1);

    FlushClient();
}

// Test that the CreateBufferMappedCallback isn't fired twice when the buffer is deleted inside
// the callback
TEST_F(WireBufferMappingTests, ReleaseInsideCreateBufferMappedAsyncCallback) {
    DawnBufferDescriptor descriptor;
    descriptor.nextInChain = nullptr;
    descriptor.label = nullptr;
    descriptor.size = kBufferSize;

    DawnCreateBufferMappedResult apiResult;
    uint32_t serverBufferContent = 31337;
    apiResult.buffer = apiBuffer;
    apiResult.data = reinterpret_cast<uint8_t*>(&serverBufferContent);
    apiResult.dataLength = kBufferSize;

    uint32_t zero = 0;

    dawnDeviceCreateBufferMappedAsync(device, &descriptor, ToMockCreateBufferMappedCallback, nullptr);

    EXPECT_CALL(api, DeviceCreateBufferMapped(apiDevice, _))
        .WillOnce(Return(apiResult))
        .RetiresOnSaturation();

    FlushClient();

    DawnBuffer buffer;
    // The callback always gets a buffer full of zeroes.
    EXPECT_CALL(*mockCreateBufferMappedCallback,
                Call(DAWN_BUFFER_MAP_ASYNC_STATUS_SUCCESS, _, Pointee(Eq(zero)), kBufferSize, _))
        .WillOnce(DoAll(::testing::SaveArg<1>(&buffer),
                        InvokeWithoutArgs([&]() { dawnBufferRelease(buffer); })));

    FlushServer();

    EXPECT_CALL(api, BufferRelease(apiBuffer));

    FlushClient();
}

// Test that the CreateBufferMappedCallback isn't fired twice when the buffer is destroyed inside
// the callback
TEST_F(WireBufferMappingTests, DestroyInsideCreateBufferMappedAsyncCallback) {
    DawnBufferDescriptor descriptor;
    descriptor.nextInChain = nullptr;
    descriptor.label = nullptr;
    descriptor.size = kBufferSize;

    DawnCreateBufferMappedResult apiResult;
    uint32_t serverBufferContent = 31337;
    apiResult.buffer = apiBuffer;
    apiResult.data = reinterpret_cast<uint8_t*>(&serverBufferContent);
    apiResult.dataLength = kBufferSize;

    uint32_t zero = 0;

    dawnDeviceCreateBufferMappedAsync(device, &descriptor, ToMockCreateBufferMappedCallback, nullptr);

    EXPECT_CALL(api, DeviceCreateBufferMapped(apiDevice, _))
        .WillOnce(Return(apiResult))
        .RetiresOnSaturation();

    FlushClient();

    DawnBuffer buffer;
    // The callback always gets a buffer full of zeroes.
    EXPECT_CALL(*mockCreateBufferMappedCallback,
                Call(DAWN_BUFFER_MAP_ASYNC_STATUS_SUCCESS, _, Pointee(Eq(zero)), kBufferSize, _))
        .WillOnce(DoAll(::testing::SaveArg<1>(&buffer),
                        InvokeWithoutArgs([&]() { dawnBufferDestroy(buffer); })));

    FlushServer();

    EXPECT_CALL(api, BufferDestroy(apiBuffer));

    FlushClient();
}
