// Copyright 2022 The Dawn & Tint Authors
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// 1. Redistributions of source code must retain the above copyright notice, this
//    list of conditions and the following disclaimer.
//
// 2. Redistributions in binary form must reproduce the above copyright notice,
//    this list of conditions and the following disclaimer in the documentation
//    and/or other materials provided with the distribution.
//
// 3. Neither the name of the copyright holder nor the names of its
//    contributors may be used to endorse or promote products derived from
//    this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

#include <utility>

#include "dawn/tests/DawnTest.h"
#include "dawn/tests/MockCallback.h"
#include "dawn/utils/WGPUHelpers.h"

namespace dawn {
namespace {

using testing::_;
using testing::HasSubstr;
using testing::Invoke;
using testing::MockCppCallback;
using testing::Return;

using MockMapAsyncCallback = MockCppCallback<void (*)(wgpu::MapAsyncStatus, wgpu::StringView)>;

class DeviceLifetimeTests : public DawnTest {
  protected:
    void SetUp() override {
        DawnTest::SetUp();

        // TODO(crbug.com/474139502): [Capture] hit device guard on replay.
        DAWN_SUPPRESS_TEST_IF(IsCaptureReplayCheckingEnabled());
    }
};

// Test that the device can be dropped before its queue.
TEST_P(DeviceLifetimeTests, DroppedBeforeQueue) {
    wgpu::Queue queue = device.GetQueue();

    device = nullptr;
}

// Test that the device can be dropped while an onSubmittedWorkDone callback is in flight.
TEST_P(DeviceLifetimeTests, DroppedWhileQueueOnSubmittedWorkDone) {
    // Submit some work.
    wgpu::CommandEncoder encoder = device.CreateCommandEncoder(nullptr);
    wgpu::CommandBuffer commandBuffer = encoder.Finish();
    queue.Submit(1, &commandBuffer);

    // Ask for an onSubmittedWorkDone callback and drop the device.
    queue.OnSubmittedWorkDone(wgpu::CallbackMode::AllowProcessEvents,
                              [](wgpu::QueueWorkDoneStatus status, wgpu::StringView) {
                                  EXPECT_EQ(status, wgpu::QueueWorkDoneStatus::Success);
                              });

    device = nullptr;
}

// Test that the device can be dropped inside an onSubmittedWorkDone callback.
TEST_P(DeviceLifetimeTests, DroppedInsideQueueOnSubmittedWorkDone) {
    // Submit some work.
    wgpu::CommandEncoder encoder = device.CreateCommandEncoder(nullptr);
    wgpu::CommandBuffer commandBuffer = encoder.Finish();
    queue.Submit(1, &commandBuffer);

    // Ask for an onSubmittedWorkDone callback and drop the device inside the callback.
    queue.OnSubmittedWorkDone(wgpu::CallbackMode::AllowProcessEvents,
                              [this](wgpu::QueueWorkDoneStatus status, wgpu::StringView) {
                                  EXPECT_EQ(status, wgpu::QueueWorkDoneStatus::Success);
                                  this->device = nullptr;
                              });

    WaitForAllOperations();
}

// Test that the device can be dropped while a popErrorScope callback is in flight.
TEST_P(DeviceLifetimeTests, DroppedWhilePopErrorScope) {
    device.PushErrorScope(wgpu::ErrorFilter::Validation);
    bool done = false;

    device.PopErrorScope(
        wgpu::CallbackMode::AllowProcessEvents,
        [](wgpu::PopErrorScopeStatus status, wgpu::ErrorType type, wgpu::StringView, bool* done) {
            *done = true;
            EXPECT_EQ(status, wgpu::PopErrorScopeStatus::Success);
            EXPECT_EQ(type, wgpu::ErrorType::NoError);
        },
        &done);
    device = nullptr;

    while (!done) {
        WaitABit();
    }
}

// Test that the device can be dropped inside an popErrorScope callback.
TEST_P(DeviceLifetimeTests, DroppedInsidePopErrorScope) {
    struct Userdata {
        wgpu::Device device;
        bool done;
    };
    device.PushErrorScope(wgpu::ErrorFilter::Validation);

    // Ask for a popErrorScope callback and drop the device inside the callback.
    Userdata data = Userdata{std::move(device), false};
    data.device.PopErrorScope(
        wgpu::CallbackMode::AllowProcessEvents,
        [](wgpu::PopErrorScopeStatus status, wgpu::ErrorType type, wgpu::StringView,
           Userdata* userdata) {
            EXPECT_EQ(status, wgpu::PopErrorScopeStatus::Success);
            EXPECT_EQ(type, wgpu::ErrorType::NoError);
            userdata->device = nullptr;
            userdata->done = true;
        },
        &data);

    while (!data.done) {
        WaitABit();
    }
}

// Test that the device can be dropped before a buffer created from it.
TEST_P(DeviceLifetimeTests, DroppedBeforeBuffer) {
    wgpu::BufferDescriptor desc = {};
    desc.size = 4;
    desc.usage = wgpu::BufferUsage::CopySrc | wgpu::BufferUsage::CopyDst;
    wgpu::Buffer buffer = device.CreateBuffer(&desc);

    device = nullptr;
}

// Test that the device can be dropped while a buffer created from it is being mapped.
TEST_P(DeviceLifetimeTests, DroppedWhileMappingBuffer) {
    wgpu::BufferDescriptor desc = {};
    desc.size = 4;
    desc.usage = wgpu::BufferUsage::MapRead | wgpu::BufferUsage::CopyDst;
    wgpu::Buffer buffer = device.CreateBuffer(&desc);

    MockMapAsyncCallback cb;
    EXPECT_CALL(cb, Call(wgpu::MapAsyncStatus::Aborted, _)).Times(1);

    buffer.MapAsync(wgpu::MapMode::Read, 0, wgpu::kWholeMapSize,
                    wgpu::CallbackMode::AllowProcessEvents, cb.Callback());

    device = nullptr;
    WaitForAllOperations();
}

// Test that the device can be dropped before a mapped buffer created from it.
TEST_P(DeviceLifetimeTests, DroppedBeforeMappedBuffer) {
    wgpu::BufferDescriptor desc = {};
    desc.size = 4;
    desc.usage = wgpu::BufferUsage::MapRead | wgpu::BufferUsage::CopyDst;
    wgpu::Buffer buffer = device.CreateBuffer(&desc);

    MapAsyncAndWait(buffer, wgpu::MapMode::Read, 0, wgpu::kWholeMapSize);

    device = nullptr;
}

// Test that the device can be dropped before a mapped at creation buffer created from it.
TEST_P(DeviceLifetimeTests, DroppedBeforeMappedAtCreationBuffer) {
    wgpu::BufferDescriptor desc = {};
    desc.size = 4;
    desc.usage = wgpu::BufferUsage::MapRead | wgpu::BufferUsage::CopyDst;
    desc.mappedAtCreation = true;
    wgpu::Buffer buffer = device.CreateBuffer(&desc);

    device = nullptr;
}

// Test that the device can be dropped before a buffer created from it, then mapping the buffer
// fails.
TEST_P(DeviceLifetimeTests, DroppedThenMapBuffer) {
    wgpu::BufferDescriptor desc = {};
    desc.size = 4;
    desc.usage = wgpu::BufferUsage::MapRead | wgpu::BufferUsage::CopyDst;
    wgpu::Buffer buffer = device.CreateBuffer(&desc);

    device = nullptr;

    MockMapAsyncCallback cb;
    EXPECT_CALL(cb, Call(wgpu::MapAsyncStatus::Aborted, HasSubstr("lost"))).Times(1);

    buffer.MapAsync(wgpu::MapMode::Read, 0, wgpu::kWholeMapSize,
                    wgpu::CallbackMode::AllowProcessEvents, cb.Callback());
    WaitForAllOperations();
}

// Test that the device can be dropped before a buffer created from it, then mapping the buffer
// twice (one inside callback) will both fail.
TEST_P(DeviceLifetimeTests, Dropped_ThenMapBuffer_ThenMapBufferInCallback) {
    wgpu::BufferDescriptor desc = {};
    desc.size = 4;
    desc.usage = wgpu::BufferUsage::MapRead | wgpu::BufferUsage::CopyDst;
    wgpu::Buffer buffer = device.CreateBuffer(&desc);

    device = nullptr;

    // First mapping.
    buffer.MapAsync(wgpu::MapMode::Read, 0, wgpu::kWholeMapSize,
                    wgpu::CallbackMode::AllowProcessEvents,
                    [&buffer](wgpu::MapAsyncStatus status, wgpu::StringView message) {
                        EXPECT_EQ(status, wgpu::MapAsyncStatus::Aborted);
                        EXPECT_THAT(message, HasSubstr("lost"));

                        // Second mapping
                        buffer.MapAsync(wgpu::MapMode::Read, 0, wgpu::kWholeMapSize,
                                        wgpu::CallbackMode::AllowProcessEvents,
                                        [](wgpu::MapAsyncStatus status, wgpu::StringView message) {
                                            EXPECT_EQ(status, wgpu::MapAsyncStatus::Aborted);
                                            EXPECT_THAT(message, HasSubstr("lost"));
                                        });
                    });

    WaitForAllOperations();
}

// Test that the device can be dropped inside a buffer map callback.
TEST_P(DeviceLifetimeTests, DroppedInsideBufferMapCallback) {
    wgpu::BufferDescriptor desc = {};
    desc.size = 4;
    desc.usage = wgpu::BufferUsage::MapRead | wgpu::BufferUsage::CopyDst;
    wgpu::Buffer buffer = device.CreateBuffer(&desc);

    buffer.MapAsync(wgpu::MapMode::Read, 0, wgpu::kWholeMapSize,
                    wgpu::CallbackMode::AllowProcessEvents,
                    [this, buffer](wgpu::MapAsyncStatus status, wgpu::StringView) {
                        EXPECT_EQ(status, wgpu::MapAsyncStatus::Success);
                        device = nullptr;

                        // Mapped data should be null since the buffer is implicitly destroyed.
                        // TODO(crbug.com/dawn/1424): On the wire client, we don't track device
                        // child objects so the mapped data is still available when the device is
                        // destroyed.
                        if (!UsesWire()) {
                            EXPECT_EQ(buffer.GetConstMappedRange(), nullptr);
                        }
                    });

    WaitForAllOperations();

    // Mapped data should be null since the buffer is implicitly destroyed.
    // TODO(crbug.com/dawn/1424): On the wire client, we don't track device child objects so the
    // mapped data is still available when the device is destroyed.
    if (!UsesWire()) {
        EXPECT_EQ(buffer.GetConstMappedRange(), nullptr);
    }
}

// Test that the device can be dropped while a write buffer operation is enqueued.
TEST_P(DeviceLifetimeTests, DroppedWhileWriteBuffer) {
    wgpu::BufferDescriptor desc = {};
    desc.size = 4;
    desc.usage = wgpu::BufferUsage::CopySrc | wgpu::BufferUsage::CopyDst;
    wgpu::Buffer buffer = device.CreateBuffer(&desc);

    uint32_t value = 7;
    queue.WriteBuffer(buffer, 0, &value, sizeof(value));
    device = nullptr;
}

// Test that the device can be dropped while a write buffer operation is enqueued and then
// a queue submit occurs. This is slightly different from the former test since it ensures
// that pending work is flushed.
TEST_P(DeviceLifetimeTests, DroppedWhileWriteBufferAndSubmit) {
    wgpu::BufferDescriptor desc = {};
    desc.size = 4;
    desc.usage = wgpu::BufferUsage::CopySrc | wgpu::BufferUsage::CopyDst;
    wgpu::Buffer buffer = device.CreateBuffer(&desc);

    uint32_t value = 7;
    queue.WriteBuffer(buffer, 0, &value, sizeof(value));
    queue.Submit(0, nullptr);
    device = nullptr;
}

// Test that the device can be dropped while createPipelineAsync is in flight
TEST_P(DeviceLifetimeTests, DroppedWhileCreatePipelineAsync) {
    wgpu::ComputePipelineDescriptor desc;
    desc.compute.module = utils::CreateShaderModule(device, R"(
    @compute @workgroup_size(1) fn main() {
    })");

    device.CreateComputePipelineAsync(
        &desc,
        UsesWire() ? wgpu::CallbackMode::AllowSpontaneous : wgpu::CallbackMode::AllowProcessEvents,
        [](wgpu::CreatePipelineAsyncStatus status, wgpu::ComputePipeline pipeline,
           wgpu::StringView) {
            EXPECT_EQ(wgpu::CreatePipelineAsyncStatus::Success, status);
            EXPECT_NE(pipeline, nullptr);
        });

    device = nullptr;
}

// Test that the device can be dropped inside a createPipelineAsync callback
TEST_P(DeviceLifetimeTests, DroppedInsideCreatePipelineAsync) {
    wgpu::ComputePipelineDescriptor desc;
    desc.compute.module = utils::CreateShaderModule(device, R"(
    @compute @workgroup_size(1) fn main() {
    })");

    bool done = false;
    device.CreateComputePipelineAsync(&desc, wgpu::CallbackMode::AllowProcessEvents,
                                      [this, &done](wgpu::CreatePipelineAsyncStatus status,
                                                    wgpu::ComputePipeline, wgpu::StringView) {
                                          EXPECT_EQ(wgpu::CreatePipelineAsyncStatus::Success,
                                                    status);
                                          device = nullptr;
                                          done = true;
                                      });

    while (!done) {
        WaitABit();
    }
}

// Test that the device can be dropped while createPipelineAsync which will hit the frontend cache
// is in flight
TEST_P(DeviceLifetimeTests, DroppedWhileCreatePipelineAsyncAlreadyCached) {
    wgpu::ComputePipelineDescriptor desc;
    desc.compute.module = utils::CreateShaderModule(device, R"(
    @compute @workgroup_size(1) fn main() {
    })");

    // Create a pipeline ahead of time so it's in the cache.
    wgpu::ComputePipeline p = device.CreateComputePipeline(&desc);

    bool done = false;
    device.CreateComputePipelineAsync(&desc, wgpu::CallbackMode::AllowProcessEvents,
                                      [&done](wgpu::CreatePipelineAsyncStatus status,
                                              wgpu::ComputePipeline pipeline, wgpu::StringView) {
                                          EXPECT_EQ(wgpu::CreatePipelineAsyncStatus::Success,
                                                    status);
                                          EXPECT_NE(pipeline, nullptr);
                                          done = true;
                                      });
    device = nullptr;

    while (!done) {
        WaitABit();
    }
}

// Test that the device can be dropped inside a createPipelineAsync callback which will hit the
// frontend cache
TEST_P(DeviceLifetimeTests, DroppedInsideCreatePipelineAsyncAlreadyCached) {
    wgpu::ComputePipelineDescriptor desc;
    desc.compute.module = utils::CreateShaderModule(device, R"(
    @compute @workgroup_size(1) fn main() {
    })");

    // Create a pipeline ahead of time so it's in the cache.
    wgpu::ComputePipeline p = device.CreateComputePipeline(&desc);

    bool done = false;
    device.CreateComputePipelineAsync(
        &desc, wgpu::CallbackMode::AllowProcessEvents,
        [this, &done](wgpu::CreatePipelineAsyncStatus status, wgpu::ComputePipeline pipeline,
                      wgpu::StringView) {
            EXPECT_EQ(wgpu::CreatePipelineAsyncStatus::Success, status);
            EXPECT_NE(pipeline, nullptr);
            device = nullptr;
            done = true;
        });

    while (!done) {
        WaitABit();
    }
}

// Test that the device can be dropped while createPipelineAsync which will race with a compilation
// to add the same pipeline to the frontend cache
TEST_P(DeviceLifetimeTests, DroppedWhileCreatePipelineAsyncRaceCache) {
    wgpu::ComputePipelineDescriptor desc;
    desc.compute.module = utils::CreateShaderModule(device, R"(
    @compute @workgroup_size(1) fn main() {
    })");

    device.CreateComputePipelineAsync(
        &desc,
        UsesWire() ? wgpu::CallbackMode::AllowSpontaneous : wgpu::CallbackMode::AllowProcessEvents,
        [](wgpu::CreatePipelineAsyncStatus status, wgpu::ComputePipeline pipeline,
           wgpu::StringView) {
            EXPECT_EQ(wgpu::CreatePipelineAsyncStatus::Success, status);
            EXPECT_NE(pipeline, nullptr);
        });

    // Create the same pipeline synchronously which will get added to the cache.
    wgpu::ComputePipeline p = device.CreateComputePipeline(&desc);

    device = nullptr;
}

// Test that the device can be dropped inside a createPipelineAsync callback which will race
// with a compilation to add the same pipeline to the frontend cache
TEST_P(DeviceLifetimeTests, DroppedInsideCreatePipelineAsyncRaceCache) {
    wgpu::ComputePipelineDescriptor desc;
    desc.compute.module = utils::CreateShaderModule(device, R"(
    @compute @workgroup_size(1) fn main() {
    })");

    bool done = false;
    device.CreateComputePipelineAsync(
        &desc, wgpu::CallbackMode::AllowProcessEvents,
        [this, &done](wgpu::CreatePipelineAsyncStatus status, wgpu::ComputePipeline pipeline,
                      wgpu::StringView) {
            EXPECT_EQ(wgpu::CreatePipelineAsyncStatus::Success, status);
            EXPECT_NE(pipeline, nullptr);
            device = nullptr;
            done = true;
        });

    // Create the same pipeline synchronously which will get added to the cache.
    wgpu::ComputePipeline p = device.CreateComputePipeline(&desc);

    while (!done) {
        WaitABit();
    }
}

// Tests that dropping 2nd device inside 1st device's callback triggered by instance.ProcessEvents
// won't crash.
TEST_P(DeviceLifetimeTests, DropDevice2InProcessEvents) {
    wgpu::Device device2 = CreateDevice();

    struct UserData {
        wgpu::Device device2;
        bool done = false;
    } userdata;

    userdata.device2 = std::move(device2);

    device.PushErrorScope(wgpu::ErrorFilter::Validation);

    // The following callback will drop the 2nd device. It won't be triggered until
    // instance.ProcessEvents() is called.
    device.PopErrorScope(
        wgpu::CallbackMode::AllowProcessEvents,
        [](wgpu::PopErrorScopeStatus status, wgpu::ErrorType type, wgpu::StringView,
           UserData* userdata) {
            userdata->device2 = nullptr;
            userdata->done = true;
        },
        &userdata);

    while (!userdata.done) {
        WaitABit();
    }
}

DAWN_INSTANTIATE_TEST(DeviceLifetimeTests,
                      D3D11Backend(),
                      D3D12Backend(),
                      MetalBackend(),
                      NullBackend(),
                      OpenGLBackend(),
                      OpenGLESBackend(),
                      VulkanBackend(),
                      WebGPUBackend());

}  // anonymous namespace
}  // namespace dawn
