// Copyright 2021 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 <gtest/gtest.h>

#include "dawn/native/Toggles.h"
#include "dawn/tests/DawnNativeTest.h"
#include "dawn/utils/ComboRenderPipelineDescriptor.h"
#include "dawn/utils/WGPUHelpers.h"
#include "mocks/BindGroupLayoutMock.h"
#include "mocks/BindGroupMock.h"
#include "mocks/BufferMock.h"
#include "mocks/CommandBufferMock.h"
#include "mocks/ComputePipelineMock.h"
#include "mocks/DeviceMock.h"
#include "mocks/ExternalTextureMock.h"
#include "mocks/PipelineLayoutMock.h"
#include "mocks/QuerySetMock.h"
#include "mocks/RenderPipelineMock.h"
#include "mocks/SamplerMock.h"
#include "mocks/ShaderModuleMock.h"
#include "mocks/SwapChainMock.h"
#include "mocks/TextureMock.h"

namespace dawn::native {
namespace {

using ::testing::_;
using ::testing::ByMove;
using ::testing::InSequence;
using ::testing::Return;
using ::testing::Test;

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

    Ref<TextureMock> GetTexture() {
        if (mTexture != nullptr) {
            return mTexture;
        }
        mTexture = AcquireRef(new TextureMock(&mDevice, TextureBase::TextureState::OwnedInternal));
        EXPECT_CALL(*mTexture.Get(), DestroyImpl).Times(1);
        return mTexture;
    }

    Ref<PipelineLayoutMock> GetPipelineLayout() {
        if (mPipelineLayout != nullptr) {
            return mPipelineLayout;
        }
        mPipelineLayout = AcquireRef(new PipelineLayoutMock(&mDevice));
        EXPECT_CALL(*mPipelineLayout.Get(), DestroyImpl).Times(1);
        return mPipelineLayout;
    }

    Ref<ShaderModuleMock> GetVertexShaderModule() {
        if (mVsModule != nullptr) {
            return mVsModule;
        }
        DAWN_TRY_ASSIGN_WITH_CLEANUP(
            mVsModule, ShaderModuleMock::Create(&mDevice, R"(
            @vertex fn main() -> @builtin(position) vec4<f32> {
                return vec4<f32>(0.0, 0.0, 0.0, 1.0);
            })"),
            { ASSERT(false); }, mVsModule);
        EXPECT_CALL(*mVsModule.Get(), DestroyImpl).Times(1);
        return mVsModule;
    }

    Ref<ShaderModuleMock> GetComputeShaderModule() {
        if (mCsModule != nullptr) {
            return mCsModule;
        }
        DAWN_TRY_ASSIGN_WITH_CLEANUP(
            mCsModule, ShaderModuleMock::Create(&mDevice, R"(
            @compute @workgroup_size(1) fn main() {
            })"),
            { ASSERT(false); }, mCsModule);
        EXPECT_CALL(*mCsModule.Get(), DestroyImpl).Times(1);
        return mCsModule;
    }

  protected:
    DeviceMock mDevice;

    // The following lazy-initialized objects are used to facilitate creation of dependent
    // objects under test.
    Ref<TextureMock> mTexture;
    Ref<PipelineLayoutMock> mPipelineLayout;
    Ref<ShaderModuleMock> mVsModule;
    Ref<ShaderModuleMock> mCsModule;
};

TEST_F(DestroyObjectTests, BindGroupExplicit) {
    BindGroupMock bindGroupMock(&mDevice);
    EXPECT_CALL(bindGroupMock, 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) {
    BindGroupMock* bindGroupMock = new BindGroupMock(&mDevice);
    EXPECT_CALL(*bindGroupMock, DestroyImpl).Times(1);
    {
        BindGroupDescriptor desc = {};
        Ref<BindGroupBase> bindGroup;
        EXPECT_CALL(mDevice, CreateBindGroupImpl)
            .WillOnce(Return(ByMove(AcquireRef(bindGroupMock))));
        DAWN_ASSERT_AND_ASSIGN(bindGroup, mDevice.CreateBindGroup(&desc));

        EXPECT_TRUE(bindGroup->IsAlive());
    }
}

TEST_F(DestroyObjectTests, BindGroupLayoutExplicit) {
    BindGroupLayoutMock bindGroupLayoutMock(&mDevice);
    EXPECT_CALL(bindGroupLayoutMock, 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) {
    BindGroupLayoutMock* bindGroupLayoutMock = new BindGroupLayoutMock(&mDevice);
    EXPECT_CALL(*bindGroupLayoutMock, DestroyImpl).Times(1);
    {
        BindGroupLayoutDescriptor desc = {};
        Ref<BindGroupLayoutBase> bindGroupLayout;
        EXPECT_CALL(mDevice, CreateBindGroupLayoutImpl)
            .WillOnce(Return(ByMove(AcquireRef(bindGroupLayoutMock))));
        DAWN_ASSERT_AND_ASSIGN(bindGroupLayout, mDevice.CreateBindGroupLayout(&desc));

        EXPECT_TRUE(bindGroupLayout->IsAlive());
        EXPECT_TRUE(bindGroupLayout->IsCachedReference());
    }
}

TEST_F(DestroyObjectTests, BufferExplicit) {
    {
        BufferMock bufferMock(&mDevice, BufferBase::BufferState::Unmapped);
        EXPECT_CALL(bufferMock, DestroyImpl).Times(1);

        EXPECT_TRUE(bufferMock.IsAlive());
        bufferMock.Destroy();
        EXPECT_FALSE(bufferMock.IsAlive());
    }
    {
        BufferMock bufferMock(&mDevice, BufferBase::BufferState::Mapped);
        {
            InSequence seq;
            EXPECT_CALL(bufferMock, DestroyImpl).Times(1);
            EXPECT_CALL(bufferMock, UnmapImpl).Times(1);
        }

        EXPECT_TRUE(bufferMock.IsAlive());
        bufferMock.Destroy();
        EXPECT_FALSE(bufferMock.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) {
    {
        BufferMock* bufferMock = new BufferMock(&mDevice, BufferBase::BufferState::Unmapped);
        EXPECT_CALL(*bufferMock, DestroyImpl).Times(1);
        {
            BufferDescriptor desc = {};
            Ref<BufferBase> buffer;
            EXPECT_CALL(mDevice, CreateBufferImpl).WillOnce(Return(ByMove(AcquireRef(bufferMock))));
            DAWN_ASSERT_AND_ASSIGN(buffer, mDevice.CreateBuffer(&desc));

            EXPECT_TRUE(buffer->IsAlive());
        }
    }
    {
        BufferMock* bufferMock = new BufferMock(&mDevice, BufferBase::BufferState::Mapped);
        {
            InSequence seq;
            EXPECT_CALL(*bufferMock, DestroyImpl).Times(1);
            EXPECT_CALL(*bufferMock, UnmapImpl).Times(1);
        }
        {
            BufferDescriptor desc = {};
            Ref<BufferBase> buffer;
            EXPECT_CALL(mDevice, CreateBufferImpl).WillOnce(Return(ByMove(AcquireRef(bufferMock))));
            DAWN_ASSERT_AND_ASSIGN(buffer, mDevice.CreateBuffer(&desc));

            EXPECT_TRUE(buffer->IsAlive());
        }
    }
}

TEST_F(DestroyObjectTests, CommandBufferExplicit) {
    CommandBufferMock commandBufferMock(&mDevice);
    EXPECT_CALL(commandBufferMock, 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) {
    CommandBufferMock* commandBufferMock = new CommandBufferMock(&mDevice);
    EXPECT_CALL(*commandBufferMock, DestroyImpl).Times(1);
    {
        CommandBufferDescriptor desc = {};
        Ref<CommandBufferBase> commandBuffer;
        EXPECT_CALL(mDevice, CreateCommandBuffer)
            .WillOnce(Return(ByMove(AcquireRef(commandBufferMock))));
        DAWN_ASSERT_AND_ASSIGN(commandBuffer, mDevice.CreateCommandBuffer(nullptr, &desc));

        EXPECT_TRUE(commandBuffer->IsAlive());
    }
}

TEST_F(DestroyObjectTests, ComputePipelineExplicit) {
    ComputePipelineMock computePipelineMock(&mDevice);
    EXPECT_CALL(computePipelineMock, 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) {
    // ComputePipelines usually set their hash values at construction, but the mock does not, so
    // we set it here.
    constexpr size_t hash = 0x12345;
    ComputePipelineMock* computePipelineMock = new ComputePipelineMock(&mDevice);
    computePipelineMock->SetContentHash(hash);
    ON_CALL(*computePipelineMock, ComputeContentHash).WillByDefault(Return(hash));

    // Compute pipelines are initialized during their creation via the device.
    EXPECT_CALL(*computePipelineMock, Initialize).Times(1);
    EXPECT_CALL(*computePipelineMock, DestroyImpl).Times(1);

    {
        ComputePipelineDescriptor desc = {};
        desc.layout = GetPipelineLayout().Get();
        desc.compute.module = GetComputeShaderModule().Get();

        Ref<ComputePipelineBase> computePipeline;
        EXPECT_CALL(mDevice, CreateUninitializedComputePipelineImpl)
            .WillOnce(Return(ByMove(AcquireRef(computePipelineMock))));
        DAWN_ASSERT_AND_ASSIGN(computePipeline, mDevice.CreateComputePipeline(&desc));

        EXPECT_TRUE(computePipeline->IsAlive());
        EXPECT_TRUE(computePipeline->IsCachedReference());
    }
}

TEST_F(DestroyObjectTests, ExternalTextureExplicit) {
    ExternalTextureMock externalTextureMock(&mDevice);
    EXPECT_CALL(externalTextureMock, DestroyImpl).Times(1);

    EXPECT_TRUE(externalTextureMock.IsAlive());
    externalTextureMock.Destroy();
    EXPECT_FALSE(externalTextureMock.IsAlive());
}

TEST_F(DestroyObjectTests, ExternalTextureImplicit) {
    ExternalTextureMock* externalTextureMock = new ExternalTextureMock(&mDevice);
    EXPECT_CALL(*externalTextureMock, DestroyImpl).Times(1);
    {
        ExternalTextureDescriptor desc = {};
        Ref<ExternalTextureBase> externalTexture;
        EXPECT_CALL(mDevice, CreateExternalTextureImpl)
            .WillOnce(Return(ByMove(AcquireRef(externalTextureMock))));
        DAWN_ASSERT_AND_ASSIGN(externalTexture, mDevice.CreateExternalTextureImpl(&desc));

        EXPECT_TRUE(externalTexture->IsAlive());
    }
}

TEST_F(DestroyObjectTests, PipelineLayoutExplicit) {
    PipelineLayoutMock pipelineLayoutMock(&mDevice);
    EXPECT_CALL(pipelineLayoutMock, 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) {
    PipelineLayoutMock* pipelineLayoutMock = new PipelineLayoutMock(&mDevice);
    EXPECT_CALL(*pipelineLayoutMock, DestroyImpl).Times(1);
    {
        PipelineLayoutDescriptor desc = {};
        Ref<PipelineLayoutBase> pipelineLayout;
        EXPECT_CALL(mDevice, CreatePipelineLayoutImpl)
            .WillOnce(Return(ByMove(AcquireRef(pipelineLayoutMock))));
        DAWN_ASSERT_AND_ASSIGN(pipelineLayout, mDevice.CreatePipelineLayout(&desc));

        EXPECT_TRUE(pipelineLayout->IsAlive());
        EXPECT_TRUE(pipelineLayout->IsCachedReference());
    }
}

TEST_F(DestroyObjectTests, QuerySetExplicit) {
    QuerySetMock querySetMock(&mDevice);
    EXPECT_CALL(querySetMock, DestroyImpl).Times(1);

    EXPECT_TRUE(querySetMock.IsAlive());
    querySetMock.Destroy();
    EXPECT_FALSE(querySetMock.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) {
    QuerySetMock* querySetMock = new QuerySetMock(&mDevice);
    EXPECT_CALL(*querySetMock, DestroyImpl).Times(1);
    {
        QuerySetDescriptor desc = {};
        Ref<QuerySetBase> querySet;
        EXPECT_CALL(mDevice, CreateQuerySetImpl).WillOnce(Return(ByMove(AcquireRef(querySetMock))));
        DAWN_ASSERT_AND_ASSIGN(querySet, mDevice.CreateQuerySet(&desc));

        EXPECT_TRUE(querySet->IsAlive());
    }
}

TEST_F(DestroyObjectTests, RenderPipelineExplicit) {
    RenderPipelineMock renderPipelineMock(&mDevice);
    EXPECT_CALL(renderPipelineMock, 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) {
    // RenderPipelines usually set their hash values at construction, but the mock does not, so
    // we set it here.
    constexpr size_t hash = 0x12345;
    RenderPipelineMock* renderPipelineMock = new RenderPipelineMock(&mDevice);
    renderPipelineMock->SetContentHash(hash);
    ON_CALL(*renderPipelineMock, ComputeContentHash).WillByDefault(Return(hash));

    // Render pipelines are initialized during their creation via the device.
    EXPECT_CALL(*renderPipelineMock, Initialize).Times(1);
    EXPECT_CALL(*renderPipelineMock, DestroyImpl).Times(1);

    {
        RenderPipelineDescriptor desc = {};
        desc.layout = GetPipelineLayout().Get();
        desc.vertex.module = GetVertexShaderModule().Get();

        Ref<RenderPipelineBase> renderPipeline;
        EXPECT_CALL(mDevice, CreateUninitializedRenderPipelineImpl)
            .WillOnce(Return(ByMove(AcquireRef(renderPipelineMock))));
        DAWN_ASSERT_AND_ASSIGN(renderPipeline, mDevice.CreateRenderPipeline(&desc));

        EXPECT_TRUE(renderPipeline->IsAlive());
        EXPECT_TRUE(renderPipeline->IsCachedReference());
    }
}

TEST_F(DestroyObjectTests, SamplerExplicit) {
    SamplerMock samplerMock(&mDevice);
    EXPECT_CALL(samplerMock, 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) {
    SamplerMock* samplerMock = new SamplerMock(&mDevice);
    EXPECT_CALL(*samplerMock, DestroyImpl).Times(1);
    {
        SamplerDescriptor desc = {};
        Ref<SamplerBase> sampler;
        EXPECT_CALL(mDevice, CreateSamplerImpl).WillOnce(Return(ByMove(AcquireRef(samplerMock))));
        DAWN_ASSERT_AND_ASSIGN(sampler, mDevice.CreateSampler(&desc));

        EXPECT_TRUE(sampler->IsAlive());
        EXPECT_TRUE(sampler->IsCachedReference());
    }
}

TEST_F(DestroyObjectTests, ShaderModuleExplicit) {
    ShaderModuleMock shaderModuleMock(&mDevice);
    EXPECT_CALL(shaderModuleMock, DestroyImpl).Times(1);

    EXPECT_TRUE(shaderModuleMock.IsAlive());
    shaderModuleMock.Destroy();
    EXPECT_FALSE(shaderModuleMock.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, ShaderModuleImplicit) {
    ShaderModuleMock* shaderModuleMock = new ShaderModuleMock(&mDevice);
    EXPECT_CALL(*shaderModuleMock, DestroyImpl).Times(1);
    {
        ShaderModuleWGSLDescriptor wgslDesc;
        wgslDesc.source = R"(
                @compute @workgroup_size(1) fn main() {
                }
            )";
        ShaderModuleDescriptor desc = {};
        desc.nextInChain = &wgslDesc;
        Ref<ShaderModuleBase> shaderModule;
        EXPECT_CALL(mDevice, CreateShaderModuleImpl)
            .WillOnce(Return(ByMove(AcquireRef(shaderModuleMock))));
        DAWN_ASSERT_AND_ASSIGN(shaderModule, mDevice.CreateShaderModule(&desc));

        EXPECT_TRUE(shaderModule->IsAlive());
        EXPECT_TRUE(shaderModule->IsCachedReference());
    }
}

TEST_F(DestroyObjectTests, SwapChainExplicit) {
    SwapChainMock swapChainMock(&mDevice);
    EXPECT_CALL(swapChainMock, DestroyImpl).Times(1);

    EXPECT_TRUE(swapChainMock.IsAlive());
    swapChainMock.Destroy();
    EXPECT_FALSE(swapChainMock.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, SwapChainImplicit) {
    SwapChainMock* swapChainMock = new SwapChainMock(&mDevice);
    EXPECT_CALL(*swapChainMock, DestroyImpl).Times(1);
    {
        SwapChainDescriptor desc = {};
        Ref<SwapChainBase> swapChain;
        EXPECT_CALL(mDevice, CreateSwapChainImpl(_))
            .WillOnce(Return(ByMove(AcquireRef(swapChainMock))));
        DAWN_ASSERT_AND_ASSIGN(swapChain, mDevice.CreateSwapChain(nullptr, &desc));

        EXPECT_TRUE(swapChain->IsAlive());
    }
}

TEST_F(DestroyObjectTests, TextureExplicit) {
    {
        TextureMock textureMock(&mDevice, TextureBase::TextureState::OwnedInternal);
        EXPECT_CALL(textureMock, DestroyImpl).Times(1);

        EXPECT_TRUE(textureMock.IsAlive());
        textureMock.Destroy();
        EXPECT_FALSE(textureMock.IsAlive());
    }
    {
        TextureMock textureMock(&mDevice, TextureBase::TextureState::OwnedExternal);
        EXPECT_CALL(textureMock, DestroyImpl).Times(1);

        EXPECT_TRUE(textureMock.IsAlive());
        textureMock.Destroy();
        EXPECT_FALSE(textureMock.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) {
    {
        TextureMock* textureMock =
            new TextureMock(&mDevice, TextureBase::TextureState::OwnedInternal);
        EXPECT_CALL(*textureMock, DestroyImpl).Times(1);
        {
            TextureDescriptor desc = {};
            Ref<TextureBase> texture;
            EXPECT_CALL(mDevice, CreateTextureImpl)
                .WillOnce(Return(ByMove(AcquireRef(textureMock))));
            DAWN_ASSERT_AND_ASSIGN(texture, mDevice.CreateTexture(&desc));

            EXPECT_TRUE(texture->IsAlive());
        }
    }
    {
        TextureMock* textureMock =
            new TextureMock(&mDevice, TextureBase::TextureState::OwnedExternal);
        EXPECT_CALL(*textureMock, DestroyImpl).Times(1);
        {
            TextureDescriptor desc = {};
            Ref<TextureBase> texture;
            EXPECT_CALL(mDevice, CreateTextureImpl)
                .WillOnce(Return(ByMove(AcquireRef(textureMock))));
            DAWN_ASSERT_AND_ASSIGN(texture, mDevice.CreateTexture(&desc));

            EXPECT_TRUE(texture->IsAlive());
        }
    }
}

TEST_F(DestroyObjectTests, TextureViewExplicit) {
    TextureViewMock textureViewMock(GetTexture().Get());
    EXPECT_CALL(textureViewMock, DestroyImpl).Times(1);

    EXPECT_TRUE(textureViewMock.IsAlive());
    textureViewMock.Destroy();
    EXPECT_FALSE(textureViewMock.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) {
    TextureViewMock* textureViewMock = new TextureViewMock(GetTexture().Get());
    EXPECT_CALL(*textureViewMock, DestroyImpl).Times(1);
    {
        TextureViewDescriptor desc = {};
        Ref<TextureViewBase> textureView;
        EXPECT_CALL(mDevice, CreateTextureViewImpl)
            .WillOnce(Return(ByMove(AcquireRef(textureViewMock))));
        DAWN_ASSERT_AND_ASSIGN(textureView, mDevice.CreateTextureView(GetTexture().Get(), &desc));

        EXPECT_TRUE(textureView->IsAlive());
    }
}

// Destroying the objects on the mDevice should result in all created objects being destroyed in
// order.
TEST_F(DestroyObjectTests, DestroyObjects) {
    BindGroupMock* bindGroupMock = new BindGroupMock(&mDevice);
    BindGroupLayoutMock* bindGroupLayoutMock = new BindGroupLayoutMock(&mDevice);
    BufferMock* bufferMock = new BufferMock(&mDevice, BufferBase::BufferState::Unmapped);
    CommandBufferMock* commandBufferMock = new CommandBufferMock(&mDevice);
    ComputePipelineMock* computePipelineMock = new ComputePipelineMock(&mDevice);
    ExternalTextureMock* externalTextureMock = new ExternalTextureMock(&mDevice);
    PipelineLayoutMock* pipelineLayoutMock = new PipelineLayoutMock(&mDevice);
    QuerySetMock* querySetMock = new QuerySetMock(&mDevice);
    RenderPipelineMock* renderPipelineMock = new RenderPipelineMock(&mDevice);
    SamplerMock* samplerMock = new SamplerMock(&mDevice);
    ShaderModuleMock* shaderModuleMock = new ShaderModuleMock(&mDevice);
    SwapChainMock* swapChainMock = new SwapChainMock(&mDevice);
    TextureMock* textureMock = new TextureMock(&mDevice, TextureBase::TextureState::OwnedInternal);
    TextureViewMock* textureViewMock = new TextureViewMock(GetTexture().Get());
    {
        InSequence seq;
        EXPECT_CALL(*commandBufferMock, DestroyImpl).Times(1);
        EXPECT_CALL(*renderPipelineMock, DestroyImpl).Times(1);
        EXPECT_CALL(*computePipelineMock, DestroyImpl).Times(1);
        EXPECT_CALL(*pipelineLayoutMock, DestroyImpl).Times(1);
        EXPECT_CALL(*swapChainMock, DestroyImpl).Times(1);
        EXPECT_CALL(*bindGroupMock, DestroyImpl).Times(1);
        EXPECT_CALL(*bindGroupLayoutMock, DestroyImpl).Times(1);
        EXPECT_CALL(*shaderModuleMock, DestroyImpl).Times(1);
        EXPECT_CALL(*externalTextureMock, DestroyImpl).Times(1);
        EXPECT_CALL(*textureViewMock, DestroyImpl).Times(1);
        EXPECT_CALL(*textureMock, DestroyImpl).Times(1);
        EXPECT_CALL(*querySetMock, DestroyImpl).Times(1);
        EXPECT_CALL(*samplerMock, DestroyImpl).Times(1);
        EXPECT_CALL(*bufferMock, DestroyImpl).Times(1);
    }

    Ref<BindGroupBase> bindGroup;
    {
        BindGroupDescriptor desc = {};
        EXPECT_CALL(mDevice, CreateBindGroupImpl)
            .WillOnce(Return(ByMove(AcquireRef(bindGroupMock))));
        DAWN_ASSERT_AND_ASSIGN(bindGroup, mDevice.CreateBindGroup(&desc));
        EXPECT_TRUE(bindGroup->IsAlive());
    }

    Ref<BindGroupLayoutBase> bindGroupLayout;
    {
        BindGroupLayoutDescriptor desc = {};
        EXPECT_CALL(mDevice, CreateBindGroupLayoutImpl)
            .WillOnce(Return(ByMove(AcquireRef(bindGroupLayoutMock))));
        DAWN_ASSERT_AND_ASSIGN(bindGroupLayout, mDevice.CreateBindGroupLayout(&desc));
        EXPECT_TRUE(bindGroupLayout->IsAlive());
        EXPECT_TRUE(bindGroupLayout->IsCachedReference());
    }

    Ref<BufferBase> buffer;
    {
        BufferDescriptor desc = {};
        EXPECT_CALL(mDevice, CreateBufferImpl).WillOnce(Return(ByMove(AcquireRef(bufferMock))));
        DAWN_ASSERT_AND_ASSIGN(buffer, mDevice.CreateBuffer(&desc));
        EXPECT_TRUE(buffer->IsAlive());
    }

    Ref<CommandBufferBase> commandBuffer;
    {
        CommandBufferDescriptor desc = {};
        EXPECT_CALL(mDevice, CreateCommandBuffer)
            .WillOnce(Return(ByMove(AcquireRef(commandBufferMock))));
        DAWN_ASSERT_AND_ASSIGN(commandBuffer, mDevice.CreateCommandBuffer(nullptr, &desc));
        EXPECT_TRUE(commandBuffer->IsAlive());
    }

    Ref<ComputePipelineBase> computePipeline;
    {
        // Compute pipelines usually set their hash values at construction, but the mock does
        // not, so we set it here.
        constexpr size_t hash = 0x12345;
        computePipelineMock->SetContentHash(hash);
        ON_CALL(*computePipelineMock, ComputeContentHash).WillByDefault(Return(hash));

        // Compute pipelines are initialized during their creation via the device.
        EXPECT_CALL(*computePipelineMock, Initialize).Times(1);

        ComputePipelineDescriptor desc = {};
        desc.layout = GetPipelineLayout().Get();
        desc.compute.module = GetComputeShaderModule().Get();
        EXPECT_CALL(mDevice, CreateUninitializedComputePipelineImpl)
            .WillOnce(Return(ByMove(AcquireRef(computePipelineMock))));
        DAWN_ASSERT_AND_ASSIGN(computePipeline, mDevice.CreateComputePipeline(&desc));
        EXPECT_TRUE(computePipeline->IsAlive());
        EXPECT_TRUE(computePipeline->IsCachedReference());
    }

    Ref<ExternalTextureBase> externalTexture;
    {
        ExternalTextureDescriptor desc = {};
        EXPECT_CALL(mDevice, CreateExternalTextureImpl)
            .WillOnce(Return(ByMove(AcquireRef(externalTextureMock))));
        DAWN_ASSERT_AND_ASSIGN(externalTexture, mDevice.CreateExternalTextureImpl(&desc));
        EXPECT_TRUE(externalTexture->IsAlive());
    }

    Ref<PipelineLayoutBase> pipelineLayout;
    {
        PipelineLayoutDescriptor desc = {};
        EXPECT_CALL(mDevice, CreatePipelineLayoutImpl)
            .WillOnce(Return(ByMove(AcquireRef(pipelineLayoutMock))));
        DAWN_ASSERT_AND_ASSIGN(pipelineLayout, mDevice.CreatePipelineLayout(&desc));
        EXPECT_TRUE(pipelineLayout->IsAlive());
        EXPECT_TRUE(pipelineLayout->IsCachedReference());
    }

    Ref<QuerySetBase> querySet;
    {
        QuerySetDescriptor desc = {};
        EXPECT_CALL(mDevice, CreateQuerySetImpl).WillOnce(Return(ByMove(AcquireRef(querySetMock))));
        DAWN_ASSERT_AND_ASSIGN(querySet, mDevice.CreateQuerySet(&desc));
        EXPECT_TRUE(querySet->IsAlive());
    }

    Ref<RenderPipelineBase> renderPipeline;
    {
        // Render pipelines usually set their hash values at construction, but the mock does
        // not, so we set it here.
        constexpr size_t hash = 0x12345;
        renderPipelineMock->SetContentHash(hash);
        ON_CALL(*renderPipelineMock, ComputeContentHash).WillByDefault(Return(hash));

        // Render pipelines are initialized during their creation via the device.
        EXPECT_CALL(*renderPipelineMock, Initialize).Times(1);

        RenderPipelineDescriptor desc = {};
        desc.layout = GetPipelineLayout().Get();
        desc.vertex.module = GetVertexShaderModule().Get();
        EXPECT_CALL(mDevice, CreateUninitializedRenderPipelineImpl)
            .WillOnce(Return(ByMove(AcquireRef(renderPipelineMock))));
        DAWN_ASSERT_AND_ASSIGN(renderPipeline, mDevice.CreateRenderPipeline(&desc));
        EXPECT_TRUE(renderPipeline->IsAlive());
        EXPECT_TRUE(renderPipeline->IsCachedReference());
    }

    Ref<SamplerBase> sampler;
    {
        SamplerDescriptor desc = {};
        EXPECT_CALL(mDevice, CreateSamplerImpl).WillOnce(Return(ByMove(AcquireRef(samplerMock))));
        DAWN_ASSERT_AND_ASSIGN(sampler, mDevice.CreateSampler(&desc));
        EXPECT_TRUE(sampler->IsAlive());
        EXPECT_TRUE(sampler->IsCachedReference());
    }

    Ref<ShaderModuleBase> shaderModule;
    {
        ShaderModuleWGSLDescriptor wgslDesc;
        wgslDesc.source = R"(
                @compute @workgroup_size(1) fn main() {
                }
            )";
        ShaderModuleDescriptor desc = {};
        desc.nextInChain = &wgslDesc;

        EXPECT_CALL(mDevice, CreateShaderModuleImpl)
            .WillOnce(Return(ByMove(AcquireRef(shaderModuleMock))));
        DAWN_ASSERT_AND_ASSIGN(shaderModule, mDevice.CreateShaderModule(&desc));
        EXPECT_TRUE(shaderModule->IsAlive());
        EXPECT_TRUE(shaderModule->IsCachedReference());
    }

    Ref<SwapChainBase> swapChain;
    {
        SwapChainDescriptor desc = {};
        EXPECT_CALL(mDevice, CreateSwapChainImpl(_))
            .WillOnce(Return(ByMove(AcquireRef(swapChainMock))));
        DAWN_ASSERT_AND_ASSIGN(swapChain, mDevice.CreateSwapChain(nullptr, &desc));
        EXPECT_TRUE(swapChain->IsAlive());
    }

    Ref<TextureBase> texture;
    {
        TextureDescriptor desc = {};
        EXPECT_CALL(mDevice, CreateTextureImpl).WillOnce(Return(ByMove(AcquireRef(textureMock))));
        DAWN_ASSERT_AND_ASSIGN(texture, mDevice.CreateTexture(&desc));
        EXPECT_TRUE(texture->IsAlive());
    }

    Ref<TextureViewBase> textureView;
    {
        TextureViewDescriptor desc = {};
        EXPECT_CALL(mDevice, CreateTextureViewImpl)
            .WillOnce(Return(ByMove(AcquireRef(textureViewMock))));
        DAWN_ASSERT_AND_ASSIGN(textureView, mDevice.CreateTextureView(GetTexture().Get(), &desc));
        EXPECT_TRUE(textureView->IsAlive());
    }

    mDevice.DestroyObjects();
    EXPECT_FALSE(bindGroup->IsAlive());
    EXPECT_FALSE(bindGroupLayout->IsAlive());
    EXPECT_FALSE(buffer->IsAlive());
    EXPECT_FALSE(commandBuffer->IsAlive());
    EXPECT_FALSE(computePipeline->IsAlive());
    EXPECT_FALSE(externalTexture->IsAlive());
    EXPECT_FALSE(pipelineLayout->IsAlive());
    EXPECT_FALSE(querySet->IsAlive());
    EXPECT_FALSE(renderPipeline->IsAlive());
    EXPECT_FALSE(sampler->IsAlive());
    EXPECT_FALSE(shaderModule->IsAlive());
    EXPECT_FALSE(swapChain->IsAlive());
    EXPECT_FALSE(texture->IsAlive());
    EXPECT_FALSE(textureView->IsAlive());
}

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) vec4<f32> {
            return vec4<f32>(0.0, 0.0, 0.0, 0.0);
        }
    )";

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

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) {
    utils::BasicRenderPass pass = utils::CreateBasicRenderPass(device, 1, 1);

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

    utils::ComboRenderPipelineDescriptor pipelineDesc;
    pipelineDesc.cTargets[0].writeMask = wgpu::ColorWriteMask::None;
    pipelineDesc.vertex.module = utils::CreateShaderModule(device, kVertexShader.data());
    pipelineDesc.vertex.entryPoint = "main";
    pipelineDesc.cFragment.module = utils::CreateShaderModule(device, kFragmentShader.data());
    pipelineDesc.cFragment.entryPoint = "main";
    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 = utils::CreateShaderModule(device, kComputeShader.data());
    pipelineDesc.compute.entryPoint = "main";
    computeEncoder.SetPipeline(device.CreateComputePipeline(&pipelineDesc));

    device.Destroy();
}

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