// Copyright 2021 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 <gtest/gtest.h>
#include <webgpu/webgpu_cpp.h>

#include <utility>
#include <vector>

#include "partition_alloc/pointers/raw_ptr.h"
#include "src/dawn/native/ChainUtils.h"
#include "src/dawn/native/Toggles.h"
#include "src/dawn/native/utils/WGPUHelpers.h"
#include "src/dawn/tests/DawnNativeTest.h"
#include "src/dawn/tests/MockCallback.h"
#include "src/dawn/tests/unittests/native/mocks/BindGroupLayoutMock.h"
#include "src/dawn/tests/unittests/native/mocks/BindGroupMock.h"
#include "src/dawn/tests/unittests/native/mocks/BufferMock.h"
#include "src/dawn/tests/unittests/native/mocks/CommandBufferMock.h"
#include "src/dawn/tests/unittests/native/mocks/ComputePipelineMock.h"
#include "src/dawn/tests/unittests/native/mocks/DawnMockTest.h"
#include "src/dawn/tests/unittests/native/mocks/DeviceMock.h"
#include "src/dawn/tests/unittests/native/mocks/ExternalTextureMock.h"
#include "src/dawn/tests/unittests/native/mocks/PipelineLayoutMock.h"
#include "src/dawn/tests/unittests/native/mocks/QuerySetMock.h"
#include "src/dawn/tests/unittests/native/mocks/RenderPipelineMock.h"
#include "src/dawn/tests/unittests/native/mocks/SamplerMock.h"
#include "src/dawn/tests/unittests/native/mocks/ShaderModuleMock.h"
#include "src/dawn/tests/unittests/native/mocks/TextureMock.h"
#include "src/dawn/utils/ComboRenderPipelineDescriptor.h"
#include "src/dawn/utils/TestUtils.h"
#include "src/dawn/utils/WGPUHelpers.h"

namespace dawn::native {
namespace {

using ::testing::_;
using ::testing::ByMove;
using ::testing::InSequence;
using ::testing::Mock;
using testing::MockCppCallback;
using ::testing::NiceMock;
using ::testing::Return;
using ::testing::StrictMock;

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

static constexpr std::string_view kComputeShader = R"(
        @compute @workgroup_size(1) fn main() {}
    )";

static constexpr std::string_view kVertexShader = R"(
        @vertex fn main() -> @builtin(position) vec4f {
            return vec4f(0.0, 0.0, 0.0, 0.0);
        }
    )";

static constexpr std::string_view kFragmentShader = R"(
        @fragment fn main() {}
    )";

// Use a sampler that's not the default as it would reuse the placeholder sampler, which only gets
// destroyed during device destruction.
static constexpr SamplerDescriptor kSamplerDesc = {.label = "",
                                                   .minFilter = wgpu::FilterMode::Linear};

// Stores and scopes a raw mock object ptr expectation. This is particularly useful on objects that
// are expected to be destroyed at the end of the scope. In most cases, when the validation in this
// class's destructor is ran, the pointer is probably already freed.
class ScopedRawPtrExpectation {
  public:
    explicit ScopedRawPtrExpectation(void* ptr) : mPtr(ptr) {}
    ~ScopedRawPtrExpectation() { Mock::VerifyAndClearExpectations(mPtr); }

  private:
    // This pointer is explicitely meant to test expectations against a deleted
    // object. So it is allowed to dangle.
    raw_ptr<void, DisableDanglingPtrDetection> mPtr = nullptr;
};

class DestroyObjectTests : public DawnMockTest {
  public:
    DestroyObjectTests() : DawnMockTest() {
        // Skipping validation on descriptors as coverage for validation is already present.
        mDeviceToggles.ForceSet(Toggle::SkipValidation, true);
    }
};

TEST_F(DestroyObjectTests, BindGroupNativeExplicit) {
    BindGroupDescriptor desc = {};
    desc.layout = mDeviceMock->GetEmptyBindGroupLayout();
    desc.entries = {};

    Ref<BindGroupMock> bindGroupMock = AcquireRef(new BindGroupMock(mDeviceMock, Unpack(&desc)));
    EXPECT_CALL(*bindGroupMock.Get(), DestroyImpl).Times(1);

    EXPECT_TRUE(bindGroupMock->IsAlive());
    bindGroupMock->Destroy();
    EXPECT_FALSE(bindGroupMock->IsAlive());
}

// If the reference count on API objects reach 0, they should delete themselves. Note that GTest
// will also complain if there is a memory leak.
TEST_F(DestroyObjectTests, BindGroupImplicit) {
    BindGroupDescriptor desc = {};
    desc.layout = mDeviceMock->GetEmptyBindGroupLayout();
    desc.entries = {};

    Ref<BindGroupMock> bindGroupMock = AcquireRef(new BindGroupMock(mDeviceMock, Unpack(&desc)));
    EXPECT_CALL(*bindGroupMock.Get(), DestroyImpl).Times(1);
    {
        ScopedRawPtrExpectation scoped(bindGroupMock.Get());

        EXPECT_CALL(*mDeviceMock, CreateBindGroupImpl)
            .WillOnce(Return(ByMove(std::move(bindGroupMock))));
        wgpu::BindGroup bindGroup = device.CreateBindGroup(ToCppAPI(&desc));

        EXPECT_TRUE(FromAPI(bindGroup.Get())->IsAlive());
    }
}

TEST_F(DestroyObjectTests, BindGroupLayoutNativeExplicit) {
    // Use an non-empty bind group layout to avoid hitting the internal empty layout in the cache.
    BindGroupLayoutDescriptor desc = {};
    std::vector<BindGroupLayoutEntry> entries;
    entries.push_back(utils::BindingLayoutEntryInitializationHelper(
        0, wgpu::ShaderStage::Compute, wgpu::BufferBindingType::Uniform));
    desc.entries = entries;

    Ref<BindGroupLayoutMock> bindGroupLayoutMock =
        AcquireRef(new BindGroupLayoutMock(mDeviceMock, Unpack(&desc)));
    EXPECT_CALL(*bindGroupLayoutMock.Get(), DestroyImpl).Times(1);

    EXPECT_TRUE(bindGroupLayoutMock->IsAlive());
    bindGroupLayoutMock->Destroy();
    EXPECT_FALSE(bindGroupLayoutMock->IsAlive());
}

// If the reference count on API objects reach 0, they should delete themselves. Note that GTest
// will also complain if there is a memory leak.
TEST_F(DestroyObjectTests, BindGroupLayoutImplicit) {
    // Use an non-empty bind group layout to avoid hitting the internal empty layout in the cache.
    BindGroupLayoutDescriptor desc = {};
    std::vector<BindGroupLayoutEntry> entries;
    entries.push_back(utils::BindingLayoutEntryInitializationHelper(
        0, wgpu::ShaderStage::Compute, wgpu::BufferBindingType::Uniform));
    desc.entries = entries;

    Ref<BindGroupLayoutMock> bindGroupLayoutMock =
        AcquireRef(new BindGroupLayoutMock(mDeviceMock, Unpack(&desc)));
    EXPECT_CALL(*bindGroupLayoutMock.Get(), DestroyImpl).Times(1);
    {
        ScopedRawPtrExpectation scoped(bindGroupLayoutMock.Get());

        EXPECT_CALL(*mDeviceMock, CreateBindGroupLayoutImpl)
            .WillOnce(Return(ByMove(std::move(bindGroupLayoutMock))));
        wgpu::BindGroupLayout bindGroupLayout = device.CreateBindGroupLayout(ToCppAPI(&desc));

        EXPECT_TRUE(FromAPI(bindGroupLayout.Get())->IsAlive());
    }
}

TEST_F(DestroyObjectTests, BufferNativeExplicit) {
    BufferDescriptor desc = {};
    desc.size = 16;
    desc.usage = wgpu::BufferUsage::Uniform;

    Ref<BufferMock> bufferMock = AcquireRef(new BufferMock(mDeviceMock, &desc));
    EXPECT_CALL(*bufferMock.Get(), DestroyImpl).Times(1);

    EXPECT_TRUE(bufferMock->IsAlive());
    bufferMock->Destroy();
    EXPECT_FALSE(bufferMock->IsAlive());
}

TEST_F(DestroyObjectTests, BufferApiExplicit) {
    BufferDescriptor desc = {};
    desc.size = 16;
    desc.usage = wgpu::BufferUsage::Uniform;

    Ref<BufferMock> bufferMock = AcquireRef(new BufferMock(mDeviceMock, &desc));
    EXPECT_CALL(*bufferMock.Get(), DestroyImpl).Times(1);

    EXPECT_CALL(*mDeviceMock, CreateBufferImpl).WillOnce(Return(ByMove(std::move(bufferMock))));
    wgpu::Buffer buffer = device.CreateBuffer(ToCppAPI(&desc));

    EXPECT_TRUE(FromAPI(buffer.Get())->IsAlive());
    buffer.Destroy();
    EXPECT_FALSE(FromAPI(buffer.Get())->IsAlive());
}

// If the reference count on API objects reach 0, they should delete themselves. Note that GTest
// will also complain if there is a memory leak.
TEST_F(DestroyObjectTests, BufferImplicit) {
    BufferDescriptor desc = {};
    desc.size = 16;
    desc.usage = wgpu::BufferUsage::Uniform;

    Ref<BufferMock> bufferMock = AcquireRef(new BufferMock(mDeviceMock, &desc));
    EXPECT_CALL(*bufferMock.Get(), DestroyImpl).Times(1);
    {
        ScopedRawPtrExpectation scoped(bufferMock.Get());

        EXPECT_CALL(*mDeviceMock, CreateBufferImpl).WillOnce(Return(ByMove(std::move(bufferMock))));
        wgpu::Buffer buffer = device.CreateBuffer(ToCppAPI(&desc));

        EXPECT_TRUE(FromAPI(buffer.Get())->IsAlive());
    }
}

TEST_F(DestroyObjectTests, MappedBufferApiExplicit) {
    BufferDescriptor desc = {};
    desc.size = 16;
    desc.usage = wgpu::BufferUsage::MapRead;

    MockMapAsyncCallback cb;
    EXPECT_CALL(cb, Call).Times(1);
    Ref<BufferMock> bufferMock = AcquireRef(new BufferMock(mDeviceMock, &desc));
    {
        InSequence seq;
        EXPECT_CALL(*bufferMock.Get(), MapAsyncImpl).WillOnce([]() -> MaybeError { return {}; });
        EXPECT_CALL(*bufferMock.Get(), DestroyImpl).Times(1);
        EXPECT_CALL(*bufferMock.Get(), UnmapImpl).Times(1);
    }
    {
        EXPECT_CALL(*mDeviceMock, CreateBufferImpl).WillOnce(Return(ByMove(std::move(bufferMock))));
        wgpu::Buffer buffer = device.CreateBuffer(ToCppAPI(&desc));
        buffer.MapAsync(wgpu::MapMode::Read, 0, 16, wgpu::CallbackMode::AllowProcessEvents,
                        cb.Callback());
        ProcessEvents();

        EXPECT_TRUE(FromAPI(buffer.Get())->IsAlive());
        buffer.Destroy();
        EXPECT_FALSE(FromAPI(buffer.Get())->IsAlive());
    }
}

// If the reference count on API objects reach 0, they should delete themselves. Note that GTest
// will also complain if there is a memory leak.
TEST_F(DestroyObjectTests, MappedBufferImplicit) {
    BufferDescriptor desc = {};
    desc.size = 16;
    desc.usage = wgpu::BufferUsage::MapRead;

    MockMapAsyncCallback cb;
    EXPECT_CALL(cb, Call).Times(1);
    Ref<BufferMock> bufferMock = AcquireRef(new BufferMock(mDeviceMock, &desc));
    {
        InSequence seq;
        EXPECT_CALL(*bufferMock.Get(), MapAsyncImpl).WillOnce([]() -> MaybeError { return {}; });
        EXPECT_CALL(*bufferMock.Get(), DestroyImpl).Times(1);
        EXPECT_CALL(*bufferMock.Get(), UnmapImpl).Times(1);
    }
    {
        ScopedRawPtrExpectation scoped(bufferMock.Get());

        EXPECT_CALL(*mDeviceMock, CreateBufferImpl).WillOnce(Return(ByMove(std::move(bufferMock))));
        wgpu::Buffer buffer = device.CreateBuffer(ToCppAPI(&desc));
        buffer.MapAsync(wgpu::MapMode::Read, 0, 16, wgpu::CallbackMode::AllowProcessEvents,
                        cb.Callback());
        ProcessEvents();

        EXPECT_TRUE(FromAPI(buffer.Get())->IsAlive());
    }
}

TEST_F(DestroyObjectTests, CommandBufferNativeExplicit) {
    CommandEncoderDescriptor commandEncoderDesc = {};
    Ref<CommandEncoder> commandEncoder =
        CommandEncoder::Create(mDeviceMock, Unpack(&commandEncoderDesc));

    CommandBufferDescriptor commandBufferDesc = {};

    Ref<CommandBufferMock> commandBufferMock =
        AcquireRef(new CommandBufferMock(mDeviceMock, commandEncoder.Get(), &commandBufferDesc));
    EXPECT_CALL(*commandBufferMock.Get(), DestroyImpl).Times(1);

    EXPECT_TRUE(commandBufferMock->IsAlive());
    commandBufferMock->Destroy();
    EXPECT_FALSE(commandBufferMock->IsAlive());
}

// If the reference count on API objects reach 0, they should delete themselves. Note that GTest
// will also complain if there is a memory leak.
TEST_F(DestroyObjectTests, CommandBufferImplicit) {
    CommandEncoderDescriptor commandEncoderDesc = {};
    wgpu::CommandEncoder commandEncoder =
        device.CreateCommandEncoder(ToCppAPI(&commandEncoderDesc));

    CommandBufferDescriptor commandBufferDesc = {};

    Ref<CommandBufferMock> commandBufferMock = AcquireRef(
        new CommandBufferMock(mDeviceMock, FromAPI(commandEncoder.Get()), &commandBufferDesc));
    EXPECT_CALL(*commandBufferMock.Get(), DestroyImpl).Times(1);
    {
        ScopedRawPtrExpectation scoped(commandBufferMock.Get());

        EXPECT_CALL(*mDeviceMock, CreateCommandBuffer)
            .WillOnce(Return(ByMove(std::move(commandBufferMock))));
        wgpu::CommandBuffer commandBuffer = commandEncoder.Finish(ToCppAPI(&commandBufferDesc));

        EXPECT_TRUE(FromAPI(commandBuffer.Get())->IsAlive());
    }
}

TEST_F(DestroyObjectTests, ComputePipelineNativeExplicit) {
    Ref<ShaderModuleMock> csModuleMock =
        ShaderModuleMock::Create(mDeviceMock, kComputeShader.data());
    ComputePipelineDescriptor desc = {};
    desc.compute.module = csModuleMock.Get();

    Ref<ComputePipelineMock> computePipelineMock = ComputePipelineMock::Create(mDeviceMock, &desc);
    EXPECT_CALL(*computePipelineMock.Get(), DestroyImpl).Times(1);

    EXPECT_TRUE(computePipelineMock->IsAlive());
    computePipelineMock->Destroy();
    EXPECT_FALSE(computePipelineMock->IsAlive());
}

// If the reference count on API objects reach 0, they should delete themselves. Note that GTest
// will also complain if there is a memory leak.
TEST_F(DestroyObjectTests, ComputePipelineImplicit) {
    Ref<ShaderModuleMock> csModuleMock =
        ShaderModuleMock::Create(mDeviceMock, kComputeShader.data());
    ComputePipelineDescriptor desc = {};
    desc.compute.module = csModuleMock.Get();

    // Compute pipelines are initialized during their creation via the device.
    Ref<ComputePipelineMock> computePipelineMock = ComputePipelineMock::Create(mDeviceMock, &desc);
    EXPECT_CALL(*computePipelineMock.Get(), InitializeImpl).Times(1);
    EXPECT_CALL(*computePipelineMock.Get(), DestroyImpl).Times(1);

    {
        ScopedRawPtrExpectation scoped(computePipelineMock.Get());

        EXPECT_CALL(*mDeviceMock, CreateUninitializedComputePipelineImpl)
            .WillOnce(Return(ByMove(std::move(computePipelineMock))));
        wgpu::ComputePipeline computePipeline = device.CreateComputePipeline(ToCppAPI(&desc));

        EXPECT_TRUE(FromAPI(computePipeline.Get())->IsAlive());
    }
}

TEST_F(DestroyObjectTests, ExternalTextureNativeExplicit) {
    TextureDescriptor textureDesc = {};
    textureDesc.usage = wgpu::TextureUsage::CopySrc | wgpu::TextureUsage::CopyDst;
    textureDesc.size.width = 1;
    textureDesc.size.height = 1;
    textureDesc.format = wgpu::TextureFormat::RGBA8Unorm;
    Ref<TextureMock> textureMock = AcquireRef(new NiceMock<TextureMock>(mDeviceMock, &textureDesc));

    TextureViewDescriptor textureViewDesc = {};
    textureViewDesc.format = wgpu::TextureFormat::RGBA8Unorm;
    Ref<TextureViewMock> textureViewMock =
        AcquireRef(new NiceMock<TextureViewMock>(textureMock.Get(), Unpack(&textureViewDesc)));

    ExternalTextureDescriptor desc = {};
    std::array<float, 12> placeholderConstantArray = {};
    desc.yuvToRgbConversionMatrix = placeholderConstantArray.data();
    desc.gamutConversionMatrix = placeholderConstantArray.data();
    desc.srcTransferFunctionParameters = placeholderConstantArray.data();
    desc.dstTransferFunctionParameters = placeholderConstantArray.data();
    desc.cropSize = {1, 1};
    desc.apparentSize = {1, 1};
    desc.plane0 = textureViewMock.Get();

    Ref<ExternalTextureMock> externalTextureMock = ExternalTextureMock::Create(mDeviceMock, &desc);
    EXPECT_CALL(*externalTextureMock.Get(), DestroyImpl).Times(1);

    EXPECT_TRUE(externalTextureMock->IsAlive());
    externalTextureMock->Destroy();
    EXPECT_FALSE(externalTextureMock->IsAlive());
}

TEST_F(DestroyObjectTests, ExternalTextureApiExplicit) {
    TextureDescriptor textureDesc = {};
    textureDesc.usage = wgpu::TextureUsage::CopySrc | wgpu::TextureUsage::CopyDst;
    textureDesc.size.width = 1;
    textureDesc.size.height = 1;
    textureDesc.format = wgpu::TextureFormat::RGBA8Unorm;
    Ref<TextureMock> textureMock = AcquireRef(new NiceMock<TextureMock>(mDeviceMock, &textureDesc));

    TextureViewDescriptor textureViewDesc = {};
    textureViewDesc.format = wgpu::TextureFormat::RGBA8Unorm;
    Ref<TextureViewMock> textureViewMock =
        AcquireRef(new NiceMock<TextureViewMock>(textureMock.Get(), Unpack(&textureViewDesc)));

    ExternalTextureDescriptor desc = {};
    std::array<float, 12> placeholderConstantArray = {};
    desc.yuvToRgbConversionMatrix = placeholderConstantArray.data();
    desc.gamutConversionMatrix = placeholderConstantArray.data();
    desc.srcTransferFunctionParameters = placeholderConstantArray.data();
    desc.dstTransferFunctionParameters = placeholderConstantArray.data();
    desc.cropSize = {1, 1};
    desc.apparentSize = {1, 1};
    desc.plane0 = textureViewMock.Get();

    Ref<ExternalTextureMock> externalTextureMock = ExternalTextureMock::Create(mDeviceMock, &desc);
    EXPECT_CALL(*externalTextureMock.Get(), DestroyImpl).Times(1);

    EXPECT_CALL(*mDeviceMock, CreateExternalTextureImpl)
        .WillOnce(Return(ByMove(std::move(externalTextureMock))));
    wgpu::ExternalTexture externalTexture = device.CreateExternalTexture(ToCppAPI(&desc));

    EXPECT_TRUE(FromAPI(externalTexture.Get())->IsAlive());
    externalTexture.Destroy();
    EXPECT_FALSE(FromAPI(externalTexture.Get())->IsAlive());
}

TEST_F(DestroyObjectTests, ExternalTextureImplicit) {
    TextureDescriptor textureDesc = {};
    textureDesc.usage = wgpu::TextureUsage::CopySrc | wgpu::TextureUsage::CopyDst;
    textureDesc.size.width = 1;
    textureDesc.size.height = 1;
    textureDesc.format = wgpu::TextureFormat::RGBA8Unorm;
    Ref<TextureMock> textureMock = AcquireRef(new NiceMock<TextureMock>(mDeviceMock, &textureDesc));

    TextureViewDescriptor textureViewDesc = {};
    textureViewDesc.format = wgpu::TextureFormat::RGBA8Unorm;
    Ref<TextureViewMock> textureViewMock =
        AcquireRef(new NiceMock<TextureViewMock>(textureMock.Get(), Unpack(&textureViewDesc)));

    ExternalTextureDescriptor desc = {};
    std::array<float, 12> placeholderConstantArray = {};
    desc.yuvToRgbConversionMatrix = placeholderConstantArray.data();
    desc.gamutConversionMatrix = placeholderConstantArray.data();
    desc.srcTransferFunctionParameters = placeholderConstantArray.data();
    desc.dstTransferFunctionParameters = placeholderConstantArray.data();
    desc.cropSize = {1, 1};
    desc.apparentSize = {1, 1};
    desc.plane0 = textureViewMock.Get();

    Ref<ExternalTextureMock> externalTextureMock = ExternalTextureMock::Create(mDeviceMock, &desc);
    EXPECT_CALL(*externalTextureMock.Get(), DestroyImpl).Times(1);
    {
        ScopedRawPtrExpectation scoped(externalTextureMock.Get());

        EXPECT_CALL(*mDeviceMock, CreateExternalTextureImpl)
            .WillOnce(Return(ByMove(std::move(externalTextureMock))));
        wgpu::ExternalTexture externalTexture = device.CreateExternalTexture(ToCppAPI(&desc));

        EXPECT_TRUE(FromAPI(externalTexture.Get())->IsAlive());
    }
}

TEST_F(DestroyObjectTests, PipelineLayoutNativeExplicit) {
    BindGroupLayoutBase* bgl = mDeviceMock->GetEmptyBindGroupLayout();
    PipelineLayoutDescriptor desc = {};
    desc.bindGroupLayouts = SpanFromRef<BindGroupIndex>(bgl);

    Ref<PipelineLayoutMock> pipelineLayoutMock =
        AcquireRef(new PipelineLayoutMock(mDeviceMock, &desc));
    EXPECT_CALL(*pipelineLayoutMock.Get(), DestroyImpl).Times(1);

    EXPECT_TRUE(pipelineLayoutMock->IsAlive());
    pipelineLayoutMock->Destroy();
    EXPECT_FALSE(pipelineLayoutMock->IsAlive());
}

// If the reference count on API objects reach 0, they should delete themselves. Note that GTest
// will also complain if there is a memory leak.
TEST_F(DestroyObjectTests, PipelineLayoutImplicit) {
    Ref<BindGroupLayoutMock> bindGroupLayoutMock;
    wgpu::BindGroupLayout bindGroupLayout;
    {
        // Use an non-empty bind group layout to avoid hitting the internal empty layout in the
        // cache.
        BindGroupLayoutDescriptor desc = {};
        std::vector<BindGroupLayoutEntry> entries;
        entries.push_back(utils::BindingLayoutEntryInitializationHelper(
            0, wgpu::ShaderStage::Compute, wgpu::BufferBindingType::Uniform));
        desc.entries = entries;

        ScopedRawPtrExpectation scoped(mDeviceMock);
        bindGroupLayoutMock = AcquireRef(new BindGroupLayoutMock(mDeviceMock, Unpack(&desc)));
        EXPECT_CALL(*mDeviceMock, CreateBindGroupLayoutImpl).WillOnce(Return(bindGroupLayoutMock));
        bindGroupLayout = device.CreateBindGroupLayout(ToCppAPI(&desc));
    }

    BindGroupLayoutBase* bgl = FromAPI(bindGroupLayout.Get());
    PipelineLayoutDescriptor desc = {};
    desc.bindGroupLayouts = SpanFromRef<BindGroupIndex>(bgl);

    Ref<PipelineLayoutMock> pipelineLayoutMock =
        AcquireRef(new PipelineLayoutMock(mDeviceMock, &desc));
    EXPECT_CALL(*pipelineLayoutMock.Get(), DestroyImpl).Times(1);
    {
        ScopedRawPtrExpectation scoped(pipelineLayoutMock.Get());

        EXPECT_CALL(*mDeviceMock, CreatePipelineLayoutImpl)
            .WillOnce(Return(ByMove(std::move(pipelineLayoutMock))));
        wgpu::PipelineLayout pipelineLayout = device.CreatePipelineLayout(ToCppAPI(&desc));

        EXPECT_TRUE(FromAPI(pipelineLayout.Get())->IsAlive());
    }
}

TEST_F(DestroyObjectTests, QuerySetNativeExplicit) {
    QuerySetDescriptor desc = {};
    desc.type = wgpu::QueryType::Occlusion;
    desc.count = 1;

    Ref<QuerySetMock> querySetMock = AcquireRef(new QuerySetMock(mDeviceMock, &desc));
    EXPECT_CALL(*querySetMock.Get(), DestroyImpl).Times(1);

    EXPECT_TRUE(querySetMock->IsAlive());
    querySetMock->Destroy();
    EXPECT_FALSE(querySetMock->IsAlive());
}

TEST_F(DestroyObjectTests, QuerySetApiExplicit) {
    QuerySetDescriptor desc = {};
    desc.type = wgpu::QueryType::Occlusion;
    desc.count = 1;

    Ref<QuerySetMock> querySetMock = AcquireRef(new QuerySetMock(mDeviceMock, &desc));
    EXPECT_CALL(*querySetMock.Get(), DestroyImpl).Times(1);

    EXPECT_CALL(*mDeviceMock, CreateQuerySetImpl).WillOnce(Return(ByMove(std::move(querySetMock))));
    wgpu::QuerySet querySet = device.CreateQuerySet(ToCppAPI(&desc));

    EXPECT_TRUE(FromAPI(querySet.Get())->IsAlive());
    querySet.Destroy();
    EXPECT_FALSE(FromAPI(querySet.Get())->IsAlive());
}

// If the reference count on API objects reach 0, they should delete themselves. Note that GTest
// will also complain if there is a memory leak.
TEST_F(DestroyObjectTests, QuerySetImplicit) {
    QuerySetDescriptor desc = {};
    desc.type = wgpu::QueryType::Occlusion;
    desc.count = 1;

    Ref<QuerySetMock> querySetMock = AcquireRef(new QuerySetMock(mDeviceMock, &desc));
    EXPECT_CALL(*querySetMock.Get(), DestroyImpl).Times(1);
    {
        ScopedRawPtrExpectation scoped(querySetMock.Get());

        EXPECT_CALL(*mDeviceMock, CreateQuerySetImpl)
            .WillOnce(Return(ByMove(std::move(querySetMock))));
        wgpu::QuerySet querySet = device.CreateQuerySet(ToCppAPI(&desc));

        EXPECT_TRUE(FromAPI(querySet.Get())->IsAlive());
    }
}

TEST_F(DestroyObjectTests, RenderPipelineNativeExplicit) {
    Ref<ShaderModuleMock> vsModuleMock =
        ShaderModuleMock::Create(mDeviceMock, kVertexShader.data());
    RenderPipelineDescriptor desc = {};
    desc.vertex.module = vsModuleMock.Get();

    Ref<RenderPipelineMock> renderPipelineMock = RenderPipelineMock::Create(mDeviceMock, &desc);
    EXPECT_CALL(*renderPipelineMock.Get(), DestroyImpl).Times(1);

    EXPECT_TRUE(renderPipelineMock->IsAlive());
    renderPipelineMock->Destroy();
    EXPECT_FALSE(renderPipelineMock->IsAlive());
}

// If the reference count on API objects reach 0, they should delete themselves. Note that GTest
// will also complain if there is a memory leak.
TEST_F(DestroyObjectTests, RenderPipelineImplicit) {
    Ref<ShaderModuleMock> vsModuleMock =
        ShaderModuleMock::Create(mDeviceMock, kVertexShader.data());
    RenderPipelineDescriptor desc = {};
    desc.vertex.module = vsModuleMock.Get();

    // Render pipelines are initialized during their creation via the device.
    Ref<RenderPipelineMock> renderPipelineMock = RenderPipelineMock::Create(mDeviceMock, &desc);
    EXPECT_CALL(*renderPipelineMock.Get(), InitializeImpl).Times(1);
    EXPECT_CALL(*renderPipelineMock.Get(), DestroyImpl).Times(1);

    {
        ScopedRawPtrExpectation scoped(renderPipelineMock.Get());

        EXPECT_CALL(*mDeviceMock, CreateUninitializedRenderPipelineImpl)
            .WillOnce(Return(ByMove(std::move(renderPipelineMock))));
        wgpu::RenderPipeline renderPipeline = device.CreateRenderPipeline(ToCppAPI(&desc));

        EXPECT_TRUE(FromAPI(renderPipeline.Get())->IsAlive());
    }
}

TEST_F(DestroyObjectTests, SamplerNativeExplicit) {
    Ref<SamplerMock> samplerMock = AcquireRef(new SamplerMock(mDeviceMock, &kSamplerDesc));
    EXPECT_CALL(*samplerMock.Get(), DestroyImpl).Times(1);

    EXPECT_TRUE(samplerMock->IsAlive());
    samplerMock->Destroy();
    EXPECT_FALSE(samplerMock->IsAlive());
}

// If the reference count on API objects reach 0, they should delete themselves. Note that GTest
// will also complain if there is a memory leak.
TEST_F(DestroyObjectTests, SamplerImplicit) {
    Ref<SamplerMock> samplerMock = AcquireRef(new SamplerMock(mDeviceMock, &kSamplerDesc));
    EXPECT_CALL(*samplerMock.Get(), DestroyImpl).Times(1);
    {
        ScopedRawPtrExpectation scoped(samplerMock.Get());

        EXPECT_CALL(*mDeviceMock, CreateSamplerImpl)
            .WillOnce(Return(ByMove(std::move(samplerMock))));
        wgpu::Sampler sampler = device.CreateSampler(ToCppAPI(&kSamplerDesc));

        EXPECT_TRUE(FromAPI(sampler.Get())->IsAlive());
    }
}

TEST_F(DestroyObjectTests, ShaderModuleNativeExplicit) {
    Ref<ShaderModuleMock> shaderModuleMock =
        ShaderModuleMock::Create(mDeviceMock, kVertexShader.data());
    EXPECT_CALL(*shaderModuleMock.Get(), DestroyImpl).Times(1);

    EXPECT_TRUE(shaderModuleMock->IsAlive());
    shaderModuleMock->Destroy();
    EXPECT_FALSE(shaderModuleMock->IsAlive());
}

TEST_F(DestroyObjectTests, ShaderModuleImplicit) {
    ShaderSourceWGSL wgslDesc = {};
    wgslDesc.code = kVertexShader.data();
    ShaderModuleDescriptor desc = {};
    desc.nextInChain = &wgslDesc;

    Ref<ShaderModuleMock> shaderModuleMock = ShaderModuleMock::Create(mDeviceMock, &desc);
    EXPECT_CALL(*shaderModuleMock.Get(), DestroyImpl).Times(1);
    {
        ScopedRawPtrExpectation scoped(shaderModuleMock.Get());

        EXPECT_CALL(*mDeviceMock, CreateShaderModuleImpl)
            .WillOnce(Return(ByMove(std::move(shaderModuleMock))));
        wgpu::ShaderModule shaderModule = device.CreateShaderModule(ToCppAPI(&desc));

        EXPECT_TRUE(FromAPI(shaderModule.Get())->IsAlive());
    }
}

TEST_F(DestroyObjectTests, TextureNativeExplicit) {
    TextureDescriptor desc = {};
    desc.usage = wgpu::TextureUsage::CopySrc | wgpu::TextureUsage::CopyDst;
    desc.size.width = 1;
    desc.size.height = 1;
    desc.format = wgpu::TextureFormat::RGBA8Unorm;

    Ref<TextureMock> textureMock = AcquireRef(new TextureMock(mDeviceMock, &desc));
    EXPECT_CALL(*textureMock.Get(), DestroyImpl).Times(1);

    EXPECT_TRUE(textureMock->IsAlive());
    textureMock->Destroy();
    EXPECT_FALSE(textureMock->IsAlive());
}

TEST_F(DestroyObjectTests, TextureApiExplicit) {
    TextureDescriptor desc = {};
    desc.usage = wgpu::TextureUsage::CopySrc | wgpu::TextureUsage::CopyDst;
    desc.size.width = 1;
    desc.size.height = 1;
    desc.format = wgpu::TextureFormat::RGBA8Unorm;

    Ref<TextureMock> textureMock = AcquireRef(new TextureMock(mDeviceMock, &desc));
    EXPECT_CALL(*textureMock.Get(), DestroyImpl).Times(1);

    EXPECT_CALL(*mDeviceMock, CreateTextureImpl).WillOnce(Return(ByMove(std::move(textureMock))));
    wgpu::Texture texture = device.CreateTexture(ToCppAPI(&desc));

    EXPECT_TRUE(FromAPI(texture.Get())->IsAlive());
    texture.Destroy();
    EXPECT_FALSE(FromAPI(texture.Get())->IsAlive());
}

// If the reference count on API objects reach 0, they should delete themselves. Note that GTest
// will also complain if there is a memory leak.
TEST_F(DestroyObjectTests, TextureImplicit) {
    TextureDescriptor desc = {};
    desc.usage = wgpu::TextureUsage::CopySrc | wgpu::TextureUsage::CopyDst;
    desc.size.width = 1;
    desc.size.height = 1;
    desc.format = wgpu::TextureFormat::RGBA8Unorm;

    Ref<TextureMock> textureMock = AcquireRef(new TextureMock(mDeviceMock, &desc));
    EXPECT_CALL(*textureMock.Get(), DestroyImpl).Times(1);
    {
        ScopedRawPtrExpectation scoped(textureMock.Get());

        EXPECT_CALL(*mDeviceMock, CreateTextureImpl)
            .WillOnce(Return(ByMove(std::move(textureMock))));
        wgpu::Texture texture = device.CreateTexture(ToCppAPI(&desc));

        EXPECT_TRUE(FromAPI(texture.Get())->IsAlive());
    }
}

TEST_F(DestroyObjectTests, TextureViewNativeExplicit) {
    TextureDescriptor textureDesc = {};
    textureDesc.usage = wgpu::TextureUsage::CopySrc | wgpu::TextureUsage::CopyDst;
    textureDesc.size.width = 1;
    textureDesc.size.height = 1;
    textureDesc.format = wgpu::TextureFormat::RGBA8Unorm;
    Ref<TextureMock> textureMock = AcquireRef(new NiceMock<TextureMock>(mDeviceMock, &textureDesc));

    TextureViewDescriptor desc = {};
    desc.format = wgpu::TextureFormat::RGBA8Unorm;
    {
        // Explicitly destroy the texture view.
        Ref<TextureViewMock> textureViewMock =
            AcquireRef(new TextureViewMock(textureMock.Get(), Unpack(&desc)));
        EXPECT_CALL(*textureViewMock.Get(), DestroyImpl).Times(1);

        EXPECT_TRUE(textureViewMock->IsAlive());
        textureViewMock->Destroy();
        EXPECT_FALSE(textureViewMock->IsAlive());
    }
    {
        // Destroying the owning texture should cause the view to be destroyed as well.
        Ref<TextureViewMock> textureViewMock =
            AcquireRef(new TextureViewMock(textureMock.Get(), Unpack(&desc)));
        EXPECT_CALL(*textureViewMock.Get(), DestroyImpl).Times(1);

        EXPECT_TRUE(textureViewMock->IsAlive());
        textureMock->Destroy();
        EXPECT_FALSE(textureViewMock->IsAlive());
    }
}

TEST_F(DestroyObjectTests, TextureViewApiExplicit) {
    TextureDescriptor textureDesc = {};
    textureDesc.usage = wgpu::TextureUsage::CopySrc | wgpu::TextureUsage::CopyDst;
    textureDesc.size.width = 1;
    textureDesc.size.height = 1;
    textureDesc.format = wgpu::TextureFormat::RGBA8Unorm;
    Ref<TextureMock> textureMock = AcquireRef(new NiceMock<TextureMock>(mDeviceMock, &textureDesc));

    TextureViewDescriptor viewDesc = {};
    viewDesc.format = wgpu::TextureFormat::RGBA8Unorm;
    Ref<TextureViewMock> textureViewMock =
        AcquireRef(new TextureViewMock(textureMock.Get(), Unpack(&viewDesc)));
    EXPECT_CALL(*textureViewMock.Get(), DestroyImpl).Times(1);

    EXPECT_CALL(*mDeviceMock, CreateTextureViewImpl(textureMock.Get(), _))
        .WillOnce(Return(ByMove(std::move(textureViewMock))));
    EXPECT_CALL(*mDeviceMock, CreateTextureImpl).WillOnce(Return(ByMove(std::move(textureMock))));
    wgpu::Texture texture = device.CreateTexture(ToCppAPI(&textureDesc));
    wgpu::TextureView textureView = texture.CreateView(ToCppAPI(&viewDesc));

    EXPECT_TRUE(FromAPI(textureView.Get())->IsAlive());
    texture.Destroy();
    EXPECT_FALSE(FromAPI(textureView.Get())->IsAlive());
}

// If the reference count on API objects reach 0, they should delete themselves. Note that GTest
// will also complain if there is a memory leak.
TEST_F(DestroyObjectTests, TextureViewImplicit) {
    TextureDescriptor textureDesc = {};
    textureDesc.usage = wgpu::TextureUsage::CopySrc | wgpu::TextureUsage::CopyDst;
    textureDesc.size.width = 1;
    textureDesc.size.height = 1;
    textureDesc.format = wgpu::TextureFormat::RGBA8Unorm;
    Ref<TextureMock> textureMock = AcquireRef(new NiceMock<TextureMock>(mDeviceMock, &textureDesc));

    TextureViewDescriptor viewDesc = {};
    viewDesc.format = wgpu::TextureFormat::RGBA8Unorm;

    Ref<TextureViewMock> textureViewMock =
        AcquireRef(new TextureViewMock(textureMock.Get(), Unpack(&viewDesc)));
    EXPECT_CALL(*textureViewMock.Get(), DestroyImpl).Times(1);
    {
        ScopedRawPtrExpectation scoped(textureViewMock.Get());

        EXPECT_CALL(*mDeviceMock, CreateTextureViewImpl(textureMock.Get(), _))
            .WillOnce(Return(ByMove(std::move(textureViewMock))));
        EXPECT_CALL(*mDeviceMock, CreateTextureImpl)
            .WillOnce(Return(ByMove(std::move(textureMock))));
        wgpu::Texture texture = device.CreateTexture(ToCppAPI(&textureDesc));
        wgpu::TextureView textureView = texture.CreateView(ToCppAPI(&viewDesc));

        EXPECT_TRUE(FromAPI(textureView.Get())->IsAlive());
    }
}

// Destroying the objects on the device explicitly should result in all created objects being
// destroyed in order.
TEST_F(DestroyObjectTests, DestroyObjectsApiExplicit) {
    Ref<BindGroupMock> bindGroupMock;
    wgpu::BindGroup bindGroup;
    {
        BindGroupDescriptor desc = {};
        desc.layout = mDeviceMock->GetEmptyBindGroupLayout();
        desc.entries = {};

        ScopedRawPtrExpectation scoped(mDeviceMock);
        bindGroupMock = AcquireRef(new BindGroupMock(mDeviceMock, Unpack(&desc)));
        EXPECT_CALL(*mDeviceMock, CreateBindGroupImpl).WillOnce(Return(bindGroupMock));
        bindGroup = device.CreateBindGroup(ToCppAPI(&desc));
    }

    Ref<BindGroupLayoutMock> bindGroupLayoutMock;
    wgpu::BindGroupLayout bindGroupLayout;
    {
        // Use an non-empty bind group layout to avoid hitting the internal empty layout in the
        // cache.
        BindGroupLayoutDescriptor desc = {};
        std::vector<BindGroupLayoutEntry> entries;
        entries.push_back(utils::BindingLayoutEntryInitializationHelper(
            0, wgpu::ShaderStage::Compute, wgpu::BufferBindingType::Uniform));
        desc.entries = entries;

        ScopedRawPtrExpectation scoped(mDeviceMock);
        bindGroupLayoutMock = AcquireRef(new BindGroupLayoutMock(mDeviceMock, Unpack(&desc)));
        EXPECT_CALL(*mDeviceMock, CreateBindGroupLayoutImpl).WillOnce(Return(bindGroupLayoutMock));
        bindGroupLayout = device.CreateBindGroupLayout(ToCppAPI(&desc));
    }

    Ref<ShaderModuleMock> csModuleMock;
    wgpu::ShaderModule csModule;
    {
        ShaderSourceWGSL wgslDesc = {};
        wgslDesc.code = kComputeShader.data();
        ShaderModuleDescriptor desc = {};
        desc.nextInChain = &wgslDesc;

        ScopedRawPtrExpectation scoped(mDeviceMock);
        csModuleMock = ShaderModuleMock::Create(mDeviceMock, &desc);
        EXPECT_CALL(*mDeviceMock, CreateShaderModuleImpl).WillOnce(Return(csModuleMock));
        csModule = device.CreateShaderModule(ToCppAPI(&desc));
    }

    Ref<ShaderModuleMock> vsModuleMock;
    wgpu::ShaderModule vsModule;
    {
        ShaderSourceWGSL wgslDesc = {};
        wgslDesc.code = kVertexShader.data();
        ShaderModuleDescriptor desc = {};
        desc.nextInChain = &wgslDesc;

        ScopedRawPtrExpectation scoped(mDeviceMock);
        vsModuleMock = ShaderModuleMock::Create(mDeviceMock, &desc);
        EXPECT_CALL(*mDeviceMock, CreateShaderModuleImpl).WillOnce(Return(vsModuleMock));
        vsModule = device.CreateShaderModule(ToCppAPI(&desc));
    }

    Ref<BufferMock> bufferMock;
    wgpu::Buffer buffer;
    {
        BufferDescriptor desc = {};
        desc.size = 16;
        desc.usage = wgpu::BufferUsage::Uniform;

        ScopedRawPtrExpectation scoped(mDeviceMock);
        bufferMock = AcquireRef(new BufferMock(mDeviceMock, &desc));
        EXPECT_CALL(*mDeviceMock, CreateBufferImpl).WillOnce(Return(bufferMock));
        buffer = device.CreateBuffer(ToCppAPI(&desc));
    }

    Ref<CommandBufferMock> commandBufferMock;
    wgpu::CommandBuffer commandBuffer;
    {
        CommandEncoderDescriptor commandEncoderDesc = {};
        wgpu::CommandEncoder commandEncoder =
            device.CreateCommandEncoder(ToCppAPI(&commandEncoderDesc));

        CommandBufferDescriptor commandBufferDesc = {};

        ScopedRawPtrExpectation scoped(mDeviceMock);
        commandBufferMock = AcquireRef(
            new CommandBufferMock(mDeviceMock, FromAPI(commandEncoder.Get()), &commandBufferDesc));
        EXPECT_CALL(*mDeviceMock, CreateCommandBuffer).WillOnce(Return(commandBufferMock));
        commandBuffer = commandEncoder.Finish(ToCppAPI(&commandBufferDesc));
    }

    Ref<ComputePipelineMock> computePipelineMock;
    wgpu::ComputePipeline computePipeline;
    {
        ComputePipelineDescriptor desc = {};
        desc.compute.module = csModuleMock.Get();

        ScopedRawPtrExpectation scoped(mDeviceMock);
        computePipelineMock = ComputePipelineMock::Create(mDeviceMock, &desc);
        EXPECT_CALL(*computePipelineMock.Get(), InitializeImpl).Times(1);
        EXPECT_CALL(*mDeviceMock, CreateUninitializedComputePipelineImpl)
            .WillOnce(Return(computePipelineMock));
        computePipeline = device.CreateComputePipeline(ToCppAPI(&desc));
    }

    Ref<PipelineLayoutMock> pipelineLayoutMock;
    wgpu::PipelineLayout pipelineLayout;
    {
        // Use an non-empty bind group layout to avoid hitting the internal empty pipeline layout in
        // the cache.
        BindGroupLayoutBase* bgl = FromAPI(bindGroupLayout.Get());
        PipelineLayoutDescriptor desc = {};
        desc.bindGroupLayouts = SpanFromRef<BindGroupIndex>(bgl);

        ScopedRawPtrExpectation scoped(mDeviceMock);
        pipelineLayoutMock = AcquireRef(new PipelineLayoutMock(mDeviceMock, &desc));
        EXPECT_CALL(*mDeviceMock, CreatePipelineLayoutImpl).WillOnce(Return(pipelineLayoutMock));
        pipelineLayout = device.CreatePipelineLayout(ToCppAPI(&desc));
    }

    Ref<QuerySetMock> querySetMock;
    wgpu::QuerySet querySet;
    {
        QuerySetDescriptor desc = {};
        desc.type = wgpu::QueryType::Occlusion;
        desc.count = 1;

        ScopedRawPtrExpectation scoped(mDeviceMock);
        querySetMock = AcquireRef(new QuerySetMock(mDeviceMock, &desc));
        EXPECT_CALL(*mDeviceMock, CreateQuerySetImpl).WillOnce(Return(querySetMock));
        querySet = device.CreateQuerySet(ToCppAPI(&desc));
    }

    Ref<RenderPipelineMock> renderPipelineMock;
    wgpu::RenderPipeline renderPipeline;
    {
        RenderPipelineDescriptor desc = {};
        desc.vertex.module = vsModuleMock.Get();

        ScopedRawPtrExpectation scoped(mDeviceMock);
        renderPipelineMock = RenderPipelineMock::Create(mDeviceMock, &desc);
        EXPECT_CALL(*renderPipelineMock.Get(), InitializeImpl).Times(1);
        EXPECT_CALL(*mDeviceMock, CreateUninitializedRenderPipelineImpl)
            .WillOnce(Return(renderPipelineMock));
        renderPipeline = device.CreateRenderPipeline(ToCppAPI(&desc));
    }

    Ref<SamplerMock> samplerMock;
    wgpu::Sampler sampler;
    {
        ScopedRawPtrExpectation scoped(mDeviceMock);
        samplerMock = AcquireRef(new SamplerMock(mDeviceMock, &kSamplerDesc));
        EXPECT_CALL(*mDeviceMock, CreateSamplerImpl).WillOnce(Return(samplerMock));
        sampler = device.CreateSampler(ToCppAPI(&kSamplerDesc));
    }

    Ref<TextureMock> textureMock;
    wgpu::Texture texture;
    {
        TextureDescriptor desc = {};
        desc.usage = wgpu::TextureUsage::CopySrc | wgpu::TextureUsage::CopyDst;
        desc.size.width = 1;
        desc.size.height = 1;
        desc.format = wgpu::TextureFormat::RGBA8Unorm;

        ScopedRawPtrExpectation scoped(mDeviceMock);
        textureMock = AcquireRef(new NiceMock<TextureMock>(mDeviceMock, &desc));
        EXPECT_CALL(*mDeviceMock, CreateTextureImpl).WillOnce(Return(textureMock));
        texture = device.CreateTexture(ToCppAPI(&desc));
    }

    Ref<TextureViewMock> textureViewMock;
    wgpu::TextureView textureView;
    {
        TextureViewDescriptor desc = {};
        desc.format = wgpu::TextureFormat::RGBA8Unorm;

        ScopedRawPtrExpectation scoped(mDeviceMock);
        textureViewMock = AcquireRef(new TextureViewMock(textureMock.Get(), Unpack(&desc)));
        EXPECT_CALL(*mDeviceMock, CreateTextureViewImpl).WillOnce(Return(textureViewMock));
        textureView = texture.CreateView(ToCppAPI(&desc));
    }

    Ref<ExternalTextureMock> externalTextureMock;
    wgpu::ExternalTexture externalTexture;
    {
        ExternalTextureDescriptor desc = {};
        std::array<float, 12> placeholderConstantArray = {};
        desc.yuvToRgbConversionMatrix = placeholderConstantArray.data();
        desc.gamutConversionMatrix = placeholderConstantArray.data();
        desc.srcTransferFunctionParameters = placeholderConstantArray.data();
        desc.dstTransferFunctionParameters = placeholderConstantArray.data();
        desc.cropSize = {1, 1};
        desc.apparentSize = {1, 1};
        desc.plane0 = textureViewMock.Get();

        ScopedRawPtrExpectation scoped(mDeviceMock);
        externalTextureMock = ExternalTextureMock::Create(mDeviceMock, &desc);
        EXPECT_CALL(*mDeviceMock, CreateExternalTextureImpl).WillOnce(Return(externalTextureMock));
        externalTexture = device.CreateExternalTexture(ToCppAPI(&desc));
    }

    {
        InSequence seq;
        EXPECT_CALL(*commandBufferMock.Get(), DestroyImpl).Times(1);
        EXPECT_CALL(*renderPipelineMock.Get(), DestroyImpl).Times(1);
        EXPECT_CALL(*computePipelineMock.Get(), DestroyImpl).Times(1);
        EXPECT_CALL(*pipelineLayoutMock.Get(), DestroyImpl).Times(1);
        EXPECT_CALL(*bindGroupMock.Get(), DestroyImpl).Times(1);
        EXPECT_CALL(*bindGroupLayoutMock.Get(), DestroyImpl).Times(1);
        EXPECT_CALL(*vsModuleMock.Get(), DestroyImpl).Times(1);
        EXPECT_CALL(*csModuleMock.Get(), DestroyImpl).Times(1);
        EXPECT_CALL(*externalTextureMock.Get(), DestroyImpl).Times(1);
        EXPECT_CALL(*textureMock.Get(), DestroyImpl).Times(1);
        EXPECT_CALL(*textureViewMock.Get(), DestroyImpl).Times(1);
        EXPECT_CALL(*querySetMock.Get(), DestroyImpl).Times(1);
        EXPECT_CALL(*samplerMock.Get(), DestroyImpl).Times(1);
        EXPECT_CALL(*bufferMock.Get(), DestroyImpl).Times(1);
    }

    EXPECT_TRUE(FromAPI(bindGroup.Get())->IsAlive());
    EXPECT_TRUE(FromAPI(bindGroupLayout.Get())->IsAlive());
    EXPECT_TRUE(FromAPI(buffer.Get())->IsAlive());
    EXPECT_TRUE(FromAPI(commandBuffer.Get())->IsAlive());
    EXPECT_TRUE(FromAPI(computePipeline.Get())->IsAlive());
    EXPECT_TRUE(FromAPI(externalTexture.Get())->IsAlive());
    EXPECT_TRUE(FromAPI(pipelineLayout.Get())->IsAlive());
    EXPECT_TRUE(FromAPI(querySet.Get())->IsAlive());
    EXPECT_TRUE(FromAPI(renderPipeline.Get())->IsAlive());
    EXPECT_TRUE(FromAPI(sampler.Get())->IsAlive());
    EXPECT_TRUE(FromAPI(vsModule.Get())->IsAlive());
    EXPECT_TRUE(FromAPI(csModule.Get())->IsAlive());
    EXPECT_TRUE(FromAPI(texture.Get())->IsAlive());
    EXPECT_TRUE(FromAPI(textureView.Get())->IsAlive());

    EXPECT_CALL(mDeviceLostCallback,
                Call(CHandleIs(device.Get()), wgpu::DeviceLostReason::Destroyed, _))
        .Times(1);
    device.Destroy();

    EXPECT_FALSE(FromAPI(bindGroup.Get())->IsAlive());
    EXPECT_FALSE(FromAPI(bindGroupLayout.Get())->IsAlive());
    EXPECT_FALSE(FromAPI(buffer.Get())->IsAlive());
    EXPECT_FALSE(FromAPI(commandBuffer.Get())->IsAlive());
    EXPECT_FALSE(FromAPI(computePipeline.Get())->IsAlive());
    EXPECT_FALSE(FromAPI(externalTexture.Get())->IsAlive());
    EXPECT_FALSE(FromAPI(pipelineLayout.Get())->IsAlive());
    EXPECT_FALSE(FromAPI(querySet.Get())->IsAlive());
    EXPECT_FALSE(FromAPI(renderPipeline.Get())->IsAlive());
    EXPECT_FALSE(FromAPI(sampler.Get())->IsAlive());
    EXPECT_FALSE(FromAPI(vsModule.Get())->IsAlive());
    EXPECT_FALSE(FromAPI(csModule.Get())->IsAlive());
    EXPECT_FALSE(FromAPI(texture.Get())->IsAlive());
    EXPECT_FALSE(FromAPI(textureView.Get())->IsAlive());
}

// Verify that the object's destruction (which modifies the internal object list) shouldn't race
// with other objects' IsAlive() checks. Each thread creates a buffer, checks IsAlive(), and drops
// the ref, causing the buffer to be removed from the tracking list.
TEST_F(DestroyObjectTests, IsAliveRace) {
    constexpr uint32_t kNumThreads = 10;
    constexpr uint32_t kBuffersPerThread = 100;

    dawn::utils::RunInParallel(kNumThreads, [&](uint32_t threadIndex) {
        for (uint32_t i = 0; i < kBuffersPerThread; i++) {
            // Create a buffer
            BufferDescriptor desc = {};
            desc.size = 16;
            desc.usage = wgpu::BufferUsage::Uniform;
            Ref<BufferMock> bufferMock = AcquireRef(new BufferMock(mDeviceMock, &desc));
            EXPECT_CALL(*bufferMock.Get(), DestroyImpl).Times(1);

            // Check that it's alive
            EXPECT_TRUE(bufferMock->IsAlive());

            // Drop the ref, causing destruction which removes it from the tracking list
            bufferMock = nullptr;
        }
    });
}

class DestroyObjectRegressionTests : public DawnNativeTest {};

// LastRefInCommand* tests are regression test(s) for https://crbug.com/chromium/1318792. The
// regression tests here are not exhuastive. In order to have an exhuastive test case for this
// class of failures, we should test every possible command with the commands holding the last
// references (or as last as possible) of their needed objects. For now, including simple cases
// including a stripped-down case from the original bug.

// Tests that when a RenderPipeline's last reference is held in a command in an unfinished
// CommandEncoder, that destroying the device still works as expected (and does not cause
// double-free).
TEST_F(DestroyObjectRegressionTests, LastRefInCommandRenderPipeline) {
    ::dawn::utils::BasicRenderPass pass = ::dawn::utils::CreateBasicRenderPass(device, 1, 1);

    ::dawn::utils::ComboRenderPassDescriptor passDesc{};
    wgpu::CommandEncoder encoder = device.CreateCommandEncoder();
    wgpu::RenderPassEncoder renderEncoder = encoder.BeginRenderPass(&pass.renderPassInfo);

    ::dawn::utils::ComboRenderPipelineDescriptor pipelineDesc;
    pipelineDesc.cTargets[0].writeMask = wgpu::ColorWriteMask::None;
    pipelineDesc.vertex.module = ::dawn::utils::CreateShaderModule(device, kVertexShader.data());
    pipelineDesc.cFragment.module =
        ::dawn::utils::CreateShaderModule(device, kFragmentShader.data());
    renderEncoder.SetPipeline(device.CreateRenderPipeline(&pipelineDesc));

    device.Destroy();
}

// Tests that when a ComputePipelines's last reference is held in a command in an unfinished
// CommandEncoder, that destroying the device still works as expected (and does not cause
// double-free).
TEST_F(DestroyObjectRegressionTests, LastRefInCommandComputePipeline) {
    wgpu::CommandEncoder encoder = device.CreateCommandEncoder();
    wgpu::ComputePassEncoder computeEncoder = encoder.BeginComputePass();

    wgpu::ComputePipelineDescriptor pipelineDesc;
    pipelineDesc.compute.module = ::dawn::utils::CreateShaderModule(device, kComputeShader.data());
    computeEncoder.SetPipeline(device.CreateComputePipeline(&pipelineDesc));

    device.Destroy();
}

// Tests that when a BindGroup's last reference is held in a command in an unfinished
// CommandEncoder, that destroying the device still works as expected (and does not cause
// double-free).
TEST_F(DestroyObjectRegressionTests, LastRefInCommandBindGroup) {
    wgpu::CommandEncoder encoder = device.CreateCommandEncoder();
    wgpu::ComputePassEncoder computeEncoder = encoder.BeginComputePass();

    wgpu::Sampler sampler = device.CreateSampler();
    wgpu::BindGroupLayout layout = ::dawn::utils::MakeBindGroupLayout(
        device, {{0, wgpu::ShaderStage::Compute, wgpu::SamplerBindingType::Filtering}});
    wgpu::BindGroup bindGroup = ::dawn::utils::MakeBindGroup(device, layout, {{0, sampler}});

    computeEncoder.SetBindGroup(0, bindGroup);

    device.Destroy();
}

}  // anonymous namespace
}  // namespace dawn::native
