// Copyright 2017 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.

#ifndef SRC_DAWN_TESTS_DAWNTEST_H_
#define SRC_DAWN_TESTS_DAWNTEST_H_

#include <memory>
#include <queue>
#include <string>
#include <unordered_map>
#include <utility>
#include <vector>

#include "dawn/common/Log.h"
#include "dawn/common/Platform.h"
#include "dawn/common/Preprocessor.h"
#include "dawn/dawn_proc_table.h"
#include "dawn/native/DawnNative.h"
#include "dawn/platform/DawnPlatform.h"
#include "dawn/tests/AdapterTestConfig.h"
#include "dawn/tests/MockCallback.h"
#include "dawn/tests/ParamGenerator.h"
#include "dawn/tests/ToggleParser.h"
#include "dawn/utils/ScopedAutoreleasePool.h"
#include "dawn/utils/TestUtils.h"
#include "dawn/utils/TextureUtils.h"
#include "dawn/webgpu_cpp.h"
#include "dawn/webgpu_cpp_print.h"
#include "gmock/gmock.h"
#include "gtest/gtest.h"

// Getting data back from Dawn is done in an async manners so all expectations are "deferred"
// until the end of the test. Also expectations use a copy to a MapRead buffer to get the data
// so resources should have the CopySrc allowed usage bit if you want to add expectations on
// them.

// AddBufferExpectation is defined in DawnTestBase as protected function. This ensures the macro can
// only be used in derivd class of DawnTestBase. Use "this" pointer to ensure the macro works with
// CRTP.
#define EXPECT_BUFFER(buffer, offset, size, expectation) \
    this->AddBufferExpectation(__FILE__, __LINE__, buffer, offset, size, expectation)

#define EXPECT_BUFFER_U8_EQ(expected, buffer, offset) \
    EXPECT_BUFFER(buffer, offset, sizeof(uint8_t), new ::detail::ExpectEq<uint8_t>(expected))

#define EXPECT_BUFFER_U8_RANGE_EQ(expected, buffer, offset, count) \
    EXPECT_BUFFER(buffer, offset, sizeof(uint8_t) * (count),       \
                  new ::detail::ExpectEq<uint8_t>(expected, count))

#define EXPECT_BUFFER_U16_EQ(expected, buffer, offset) \
    EXPECT_BUFFER(buffer, offset, sizeof(uint16_t), new ::detail::ExpectEq<uint16_t>(expected))

#define EXPECT_BUFFER_U16_RANGE_EQ(expected, buffer, offset, count) \
    EXPECT_BUFFER(buffer, offset, sizeof(uint16_t) * (count),       \
                  new ::detail::ExpectEq<uint16_t>(expected, count))

#define EXPECT_BUFFER_U32_EQ(expected, buffer, offset) \
    EXPECT_BUFFER(buffer, offset, sizeof(uint32_t), new ::detail::ExpectEq<uint32_t>(expected))

#define EXPECT_BUFFER_U32_RANGE_EQ(expected, buffer, offset, count) \
    EXPECT_BUFFER(buffer, offset, sizeof(uint32_t) * (count),       \
                  new ::detail::ExpectEq<uint32_t>(expected, count))

#define EXPECT_BUFFER_U64_EQ(expected, buffer, offset) \
    EXPECT_BUFFER(buffer, offset, sizeof(uint64_t), new ::detail::ExpectEq<uint64_t>(expected))

#define EXPECT_BUFFER_U64_RANGE_EQ(expected, buffer, offset, count) \
    EXPECT_BUFFER(buffer, offset, sizeof(uint64_t) * (count),       \
                  new ::detail::ExpectEq<uint64_t>(expected, count))

#define EXPECT_BUFFER_FLOAT_EQ(expected, buffer, offset) \
    EXPECT_BUFFER(buffer, offset, sizeof(float), new ::detail::ExpectEq<float>(expected))

#define EXPECT_BUFFER_FLOAT_RANGE_EQ(expected, buffer, offset, count) \
    EXPECT_BUFFER(buffer, offset, sizeof(float) * (count),            \
                  new ::detail::ExpectEq<float>(expected, count))

// Test a pixel of the mip level 0 of a 2D texture.
#define EXPECT_PIXEL_RGBA8_EQ(expected, texture, x, y) \
    AddTextureExpectation(__FILE__, __LINE__, expected, texture, {x, y})

#define EXPECT_PIXEL_FLOAT_EQ(expected, texture, x, y) \
    AddTextureExpectation(__FILE__, __LINE__, expected, texture, {x, y})

#define EXPECT_PIXEL_FLOAT16_EQ(expected, texture, x, y) \
    AddTextureExpectation<float, uint16_t>(__FILE__, __LINE__, expected, texture, {x, y})

#define EXPECT_PIXEL_RGBA8_BETWEEN(color0, color1, texture, x, y) \
    AddTextureBetweenColorsExpectation(__FILE__, __LINE__, color0, color1, texture, x, y)

#define EXPECT_TEXTURE_EQ(...) AddTextureExpectation(__FILE__, __LINE__, __VA_ARGS__)

#define EXPECT_TEXTURE_FLOAT16_EQ(...) \
    AddTextureExpectation<float, uint16_t>(__FILE__, __LINE__, __VA_ARGS__)

#define ASSERT_DEVICE_ERROR_MSG_ON(device, statement, matcher)                    \
    FlushWire();                                                                  \
    EXPECT_CALL(mDeviceErrorCallback,                                             \
                Call(testing::Ne(WGPUErrorType_NoError), matcher, device.Get())); \
    statement;                                                                    \
    FlushWire();                                                                  \
    testing::Mock::VerifyAndClearExpectations(&mDeviceErrorCallback);             \
    do {                                                                          \
    } while (0)

#define ASSERT_DEVICE_ERROR_MSG(statement, matcher) \
    ASSERT_DEVICE_ERROR_MSG_ON(this->device, statement, matcher)

#define ASSERT_DEVICE_ERROR_ON(device, statement) \
    ASSERT_DEVICE_ERROR_MSG_ON(device, statement, testing::_)

#define ASSERT_DEVICE_ERROR(statement) ASSERT_DEVICE_ERROR_MSG(statement, testing::_)

struct GLFWwindow;

namespace utils {
class PlatformDebugLogger;
class TerribleCommandBuffer;
class WireHelper;
}  // namespace utils

namespace detail {
class Expectation;
class CustomTextureExpectation;

template <typename T>
class ExpectConstant;
template <typename T, typename U = T>
class ExpectEq;
template <typename T>
class ExpectBetweenColors;
}  // namespace detail

namespace dawn::wire {
class CommandHandler;
class WireClient;
class WireServer;
}  // namespace dawn::wire

void InitDawnEnd2EndTestEnvironment(int argc, char** argv);

class DawnTestEnvironment : public testing::Environment {
  public:
    DawnTestEnvironment(int argc, char** argv);
    ~DawnTestEnvironment() override;

    static void SetEnvironment(DawnTestEnvironment* env);

    std::vector<AdapterTestParam> GetAvailableAdapterTestParamsForBackends(
        const BackendTestConfig* params,
        size_t numParams);

    void SetUp() override;
    void TearDown() override;

    bool UsesWire() const;
    dawn::native::BackendValidationLevel GetBackendValidationLevel() const;
    dawn::native::Instance* GetInstance() const;
    bool HasVendorIdFilter() const;
    uint32_t GetVendorIdFilter() const;
    bool HasBackendTypeFilter() const;
    wgpu::BackendType GetBackendTypeFilter() const;
    const char* GetWireTraceDir() const;

    const std::vector<std::string>& GetEnabledToggles() const;
    const std::vector<std::string>& GetDisabledToggles() const;

    bool RunSuppressedTests() const;

  protected:
    std::unique_ptr<dawn::native::Instance> mInstance;

  private:
    void ParseArgs(int argc, char** argv);
    std::unique_ptr<dawn::native::Instance> CreateInstanceAndDiscoverAdapters();
    void SelectPreferredAdapterProperties(const dawn::native::Instance* instance);
    void PrintTestConfigurationAndAdapterInfo(dawn::native::Instance* instance) const;

    bool mUseWire = false;
    dawn::native::BackendValidationLevel mBackendValidationLevel =
        dawn::native::BackendValidationLevel::Disabled;
    std::string mANGLEBackend;
    bool mBeginCaptureOnStartup = false;
    bool mHasVendorIdFilter = false;
    uint32_t mVendorIdFilter = 0;
    bool mHasBackendTypeFilter = false;
    wgpu::BackendType mBackendTypeFilter;
    std::string mWireTraceDir;
    bool mRunSuppressedTests = false;

    ToggleParser mToggleParser;

    std::vector<wgpu::AdapterType> mDevicePreferences;
    std::vector<TestAdapterProperties> mAdapterProperties;

    std::unique_ptr<utils::PlatformDebugLogger> mPlatformDebugLogger;
};

class DawnTestBase {
    friend class DawnPerfTestBase;

  public:
    explicit DawnTestBase(const AdapterTestParam& param);
    virtual ~DawnTestBase();

    void SetUp();
    void TearDown();

    bool IsD3D12() const;
    bool IsMetal() const;
    bool IsNull() const;
    bool IsOpenGL() const;
    bool IsOpenGLES() const;
    bool IsVulkan() const;

    bool IsAMD() const;
    bool IsApple() const;
    bool IsARM() const;
    bool IsImgTec() const;
    bool IsIntel() const;
    bool IsNvidia() const;
    bool IsQualcomm() const;
    bool IsSwiftshader() const;
    bool IsANGLE() const;
    bool IsANGLESwiftShader() const;
    bool IsWARP() const;

    bool IsIntelGen12() const;

    bool IsWindows() const;
    bool IsLinux() const;
    bool IsMacOS(int32_t majorVersion = -1, int32_t minorVersion = -1) const;
    bool IsAndroid() const;

    bool UsesWire() const;
    bool IsBackendValidationEnabled() const;
    bool IsFullBackendValidationEnabled() const;
    bool RunSuppressedTests() const;

    bool IsDXC() const;

    bool IsAsan() const;

    bool HasToggleEnabled(const char* workaround) const;

    void DestroyDevice(wgpu::Device device = nullptr);
    void LoseDeviceForTesting(wgpu::Device device = nullptr);

    bool HasVendorIdFilter() const;
    uint32_t GetVendorIdFilter() const;

    bool HasBackendTypeFilter() const;
    wgpu::BackendType GetBackendTypeFilter() const;

    wgpu::Instance GetInstance() const;
    dawn::native::Adapter GetAdapter() const;

    virtual std::unique_ptr<dawn::platform::Platform> CreateTestPlatform();

    struct PrintToStringParamName {
        explicit PrintToStringParamName(const char* test);
        std::string SanitizeParamName(std::string paramName, size_t index) const;

        template <class ParamType>
        std::string operator()(const ::testing::TestParamInfo<ParamType>& info) const {
            return SanitizeParamName(::testing::PrintToStringParamName()(info), info.index);
        }

        std::string mTest;
    };

    // Resolve all the deferred expectations in mDeferredExpectations now to avoid letting
    // mDeferredExpectations get too big.
    void ResolveDeferredExpectationsNow();

  protected:
    wgpu::Device device;
    wgpu::Queue queue;

    DawnProcTable backendProcs = {};
    WGPUDevice backendDevice = nullptr;

    size_t mLastWarningCount = 0;

    // Mock callbacks tracking errors and destruction. These are strict mocks because any errors or
    // device loss that aren't expected should result in test failures and not just some warnings
    // printed to stdout.
    testing::StrictMock<testing::MockCallback<WGPUErrorCallback>> mDeviceErrorCallback;
    testing::StrictMock<testing::MockCallback<WGPUDeviceLostCallback>> mDeviceLostCallback;

    // Helper methods to implement the EXPECT_ macros
    std::ostringstream& AddBufferExpectation(const char* file,
                                             int line,
                                             const wgpu::Buffer& buffer,
                                             uint64_t offset,
                                             uint64_t size,
                                             detail::Expectation* expectation);

    template <typename T, typename U = T>
    std::ostringstream& AddTextureExpectation(const char* file,
                                              int line,
                                              const T* expectedData,
                                              const wgpu::Texture& texture,
                                              wgpu::Origin3D origin,
                                              wgpu::Extent3D extent,
                                              wgpu::TextureFormat format,
                                              T tolerance = 0,
                                              uint32_t level = 0,
                                              wgpu::TextureAspect aspect = wgpu::TextureAspect::All,
                                              uint32_t bytesPerRow = 0) {
        // No device passed explicitly. Default it, and forward the rest of the args.
        return AddTextureExpectation<T, U>(file, line, this->device, expectedData, texture, origin,
                                           extent, format, tolerance, level, aspect, bytesPerRow);
    }

    // T - expected value Type
    // U - actual value Type (defaults = T)
    template <typename T, typename U = T>
    std::ostringstream& AddTextureExpectation(const char* file,
                                              int line,
                                              wgpu::Device targetDevice,
                                              const T* expectedData,
                                              const wgpu::Texture& texture,
                                              wgpu::Origin3D origin,
                                              wgpu::Extent3D extent,
                                              wgpu::TextureFormat format,
                                              T tolerance = 0,
                                              uint32_t level = 0,
                                              wgpu::TextureAspect aspect = wgpu::TextureAspect::All,
                                              uint32_t bytesPerRow = 0) {
        uint32_t texelBlockSize = utils::GetTexelBlockSizeInBytes(format);
        uint32_t texelComponentCount = utils::GetWGSLRenderableColorTextureComponentCount(format);

        return AddTextureExpectationImpl(
            file, line, std::move(targetDevice),
            new detail::ExpectEq<T, U>(
                expectedData,
                texelComponentCount * extent.width * extent.height * extent.depthOrArrayLayers,
                tolerance),
            texture, origin, extent, level, aspect, texelBlockSize, bytesPerRow);
    }

    template <typename T, typename U = T>
    std::ostringstream& AddTextureExpectation(const char* file,
                                              int line,
                                              const T* expectedData,
                                              const wgpu::Texture& texture,
                                              wgpu::Origin3D origin,
                                              wgpu::Extent3D extent,
                                              uint32_t level = 0,
                                              wgpu::TextureAspect aspect = wgpu::TextureAspect::All,
                                              uint32_t bytesPerRow = 0,
                                              T tolerance = {}) {
        // No device passed explicitly. Default it, and forward the rest of the args.
        return AddTextureExpectation<T, U>(file, line, this->device, expectedData, texture, origin,
                                           extent, level, aspect, bytesPerRow, tolerance);
    }

    template <typename T, typename U = T>
    std::ostringstream& AddTextureExpectation(const char* file,
                                              int line,
                                              wgpu::Device targetDevice,
                                              const T* expectedData,
                                              const wgpu::Texture& texture,
                                              wgpu::Origin3D origin,
                                              wgpu::Extent3D extent,
                                              uint32_t level = 0,
                                              wgpu::TextureAspect aspect = wgpu::TextureAspect::All,
                                              uint32_t bytesPerRow = 0,
                                              T tolerance = {}) {
        return AddTextureExpectationImpl(
            file, line, std::move(targetDevice),
            new detail::ExpectEq<T, U>(
                expectedData, extent.width * extent.height * extent.depthOrArrayLayers, tolerance),
            texture, origin, extent, level, aspect, sizeof(U), bytesPerRow);
    }

    template <typename T, typename U = T>
    std::ostringstream& AddTextureExpectation(const char* file,
                                              int line,
                                              const T& expectedData,
                                              const wgpu::Texture& texture,
                                              wgpu::Origin3D origin,
                                              uint32_t level = 0,
                                              wgpu::TextureAspect aspect = wgpu::TextureAspect::All,
                                              uint32_t bytesPerRow = 0) {
        // No device passed explicitly. Default it, and forward the rest of the args.
        return AddTextureExpectation<T, U>(file, line, this->device, expectedData, texture, origin,
                                           level, aspect, bytesPerRow);
    }

    template <typename T, typename U = T>
    std::ostringstream& AddTextureExpectation(const char* file,
                                              int line,
                                              wgpu::Device targetDevice,
                                              const T& expectedData,
                                              const wgpu::Texture& texture,
                                              wgpu::Origin3D origin,
                                              uint32_t level = 0,
                                              wgpu::TextureAspect aspect = wgpu::TextureAspect::All,
                                              uint32_t bytesPerRow = 0) {
        return AddTextureExpectationImpl(file, line, std::move(targetDevice),
                                         new detail::ExpectEq<T, U>(expectedData), texture, origin,
                                         {1, 1}, level, aspect, sizeof(U), bytesPerRow);
    }

    template <typename E,
              typename = typename std::enable_if<
                  std::is_base_of<detail::CustomTextureExpectation, E>::value>::type>
    std::ostringstream& AddTextureExpectation(const char* file,
                                              int line,
                                              E* expectation,
                                              const wgpu::Texture& texture,
                                              wgpu::Origin3D origin,
                                              wgpu::Extent3D extent,
                                              uint32_t level = 0,
                                              wgpu::TextureAspect aspect = wgpu::TextureAspect::All,
                                              uint32_t bytesPerRow = 0) {
        // No device passed explicitly. Default it, and forward the rest of the args.
        return AddTextureExpectation(file, line, this->device, expectation, texture, origin, extent,
                                     level, aspect, bytesPerRow);
    }

    template <typename E,
              typename = typename std::enable_if<
                  std::is_base_of<detail::CustomTextureExpectation, E>::value>::type>
    std::ostringstream& AddTextureExpectation(const char* file,
                                              int line,
                                              wgpu::Device targetDevice,
                                              E* expectation,
                                              const wgpu::Texture& texture,
                                              wgpu::Origin3D origin,
                                              wgpu::Extent3D extent,
                                              uint32_t level = 0,
                                              wgpu::TextureAspect aspect = wgpu::TextureAspect::All,
                                              uint32_t bytesPerRow = 0) {
        return AddTextureExpectationImpl(file, line, std::move(targetDevice), expectation, texture,
                                         origin, extent, level, aspect, expectation->DataSize(),
                                         bytesPerRow);
    }

    template <typename T>
    std::ostringstream& AddTextureBetweenColorsExpectation(
        const char* file,
        int line,
        const T& color0,
        const T& color1,
        const wgpu::Texture& texture,
        uint32_t x,
        uint32_t y,
        uint32_t level = 0,
        wgpu::TextureAspect aspect = wgpu::TextureAspect::All,
        uint32_t bytesPerRow = 0) {
        // No device passed explicitly. Default it, and forward the rest of the args.
        return AddTextureBetweenColorsExpectation(file, line, this->device, color0, color1, texture,
                                                  x, y, level, aspect, bytesPerRow);
    }

    template <typename T>
    std::ostringstream& AddTextureBetweenColorsExpectation(
        const char* file,
        int line,
        const wgpu::Device& targetDevice,
        const T& color0,
        const T& color1,
        const wgpu::Texture& texture,
        uint32_t x,
        uint32_t y,
        uint32_t level = 0,
        wgpu::TextureAspect aspect = wgpu::TextureAspect::All,
        uint32_t bytesPerRow = 0) {
        return AddTextureExpectationImpl(
            file, line, std::move(targetDevice), new detail::ExpectBetweenColors<T>(color0, color1),
            texture, {x, y}, {1, 1}, level, aspect, sizeof(T), bytesPerRow);
    }

    std::ostringstream& ExpectSampledFloatData(wgpu::Texture texture,
                                               uint32_t width,
                                               uint32_t height,
                                               uint32_t componentCount,
                                               uint32_t arrayLayer,
                                               uint32_t mipLevel,
                                               detail::Expectation* expectation);

    std::ostringstream& ExpectMultisampledFloatData(wgpu::Texture texture,
                                                    uint32_t width,
                                                    uint32_t height,
                                                    uint32_t componentCount,
                                                    uint32_t sampleCount,
                                                    uint32_t arrayLayer,
                                                    uint32_t mipLevel,
                                                    detail::Expectation* expectation);

    std::ostringstream& ExpectSampledDepthData(wgpu::Texture depthTexture,
                                               uint32_t width,
                                               uint32_t height,
                                               uint32_t arrayLayer,
                                               uint32_t mipLevel,
                                               detail::Expectation* expectation);

    // Check depth by uploading expected data to a sampled texture, writing it out as a depth
    // attachment, and then using the "equals" depth test to check the contents are the same.
    // Check stencil by rendering a full screen quad and using the "equals" stencil test with
    // a stencil reference value. Note that checking stencil checks that the entire stencil
    // buffer is equal to the expected stencil value.
    std::ostringstream& ExpectAttachmentDepthStencilTestData(wgpu::Texture texture,
                                                             wgpu::TextureFormat format,
                                                             uint32_t width,
                                                             uint32_t height,
                                                             uint32_t arrayLayer,
                                                             uint32_t mipLevel,
                                                             std::vector<float> expectedDepth,
                                                             uint8_t* expectedStencil);

    std::ostringstream& ExpectAttachmentDepthTestData(wgpu::Texture texture,
                                                      wgpu::TextureFormat format,
                                                      uint32_t width,
                                                      uint32_t height,
                                                      uint32_t arrayLayer,
                                                      uint32_t mipLevel,
                                                      std::vector<float> expectedDepth) {
        return ExpectAttachmentDepthStencilTestData(texture, format, width, height, arrayLayer,
                                                    mipLevel, std::move(expectedDepth), nullptr);
    }

    std::ostringstream& ExpectAttachmentStencilTestData(wgpu::Texture texture,
                                                        wgpu::TextureFormat format,
                                                        uint32_t width,
                                                        uint32_t height,
                                                        uint32_t arrayLayer,
                                                        uint32_t mipLevel,
                                                        uint8_t expectedStencil) {
        return ExpectAttachmentDepthStencilTestData(texture, format, width, height, arrayLayer,
                                                    mipLevel, {}, &expectedStencil);
    }

    void WaitABit(wgpu::Device = nullptr);
    void FlushWire();
    void WaitForAllOperations();

    bool SupportsFeatures(const std::vector<wgpu::FeatureName>& features);

    // Exposed device creation helper for tests to use when needing more than 1 device.
    wgpu::Device CreateDevice(std::string isolationKey = "");

    // Called in SetUp() to get the features required to be enabled in the tests. The tests must
    // check if the required features are supported by the adapter in this function and guarantee
    // the returned features are all supported by the adapter. The tests may provide different
    // code path to handle the situation when not all features are supported.
    virtual std::vector<wgpu::FeatureName> GetRequiredFeatures();

    virtual wgpu::RequiredLimits GetRequiredLimits(const wgpu::SupportedLimits&);

    const wgpu::AdapterProperties& GetAdapterProperties() const;

    wgpu::SupportedLimits GetAdapterLimits();
    wgpu::SupportedLimits GetSupportedLimits();

  private:
    utils::ScopedAutoreleasePool mObjCAutoreleasePool;
    AdapterTestParam mParam;
    std::unique_ptr<utils::WireHelper> mWireHelper;
    wgpu::Instance mInstance;
    wgpu::Adapter mAdapter;

    // Isolation keys are not exposed to the wire client. Device creation in the tests from
    // the client first push the key into this queue, which is then consumed by the server.
    std::queue<std::string> mNextIsolationKeyQueue;

    // Internal device creation function for default device creation with some optional overrides.
    WGPUDevice CreateDeviceImpl(std::string isolationKey);

    std::ostringstream& AddTextureExpectationImpl(const char* file,
                                                  int line,
                                                  wgpu::Device targetDevice,
                                                  detail::Expectation* expectation,
                                                  const wgpu::Texture& texture,
                                                  wgpu::Origin3D origin,
                                                  wgpu::Extent3D extent,
                                                  uint32_t level,
                                                  wgpu::TextureAspect aspect,
                                                  uint32_t dataSize,
                                                  uint32_t bytesPerRow);

    std::ostringstream& ExpectSampledFloatDataImpl(wgpu::TextureView textureView,
                                                   const char* wgslTextureType,
                                                   uint32_t width,
                                                   uint32_t height,
                                                   uint32_t componentCount,
                                                   uint32_t sampleCount,
                                                   detail::Expectation* expectation);

    // MapRead buffers used to get data for the expectations
    struct ReadbackSlot {
        wgpu::Device device;
        wgpu::Buffer buffer;
        uint64_t bufferSize;
        const void* mappedData = nullptr;
    };
    std::vector<ReadbackSlot> mReadbackSlots;

    // Maps all the buffers and fill ReadbackSlot::mappedData
    void MapSlotsSynchronously();
    static void SlotMapCallback(WGPUBufferMapAsyncStatus status, void* userdata);
    size_t mNumPendingMapOperations = 0;

    // Reserve space where the data for an expectation can be copied
    struct ReadbackReservation {
        wgpu::Device device;
        wgpu::Buffer buffer;
        size_t slot;
        uint64_t offset;
    };
    ReadbackReservation ReserveReadback(wgpu::Device targetDevice, uint64_t readbackSize);

    struct DeferredExpectation {
        const char* file;
        int line;
        size_t readbackSlot;
        uint64_t readbackOffset;
        uint64_t size;
        uint32_t rowBytes = 0;
        uint32_t bytesPerRow = 0;
        std::unique_ptr<detail::Expectation> expectation;
        // https://gcc.gnu.org/bugzilla/show_bug.cgi?id=54316
        // Use unique_ptr because of missing move/copy constructors on std::basic_ostringstream
        std::unique_ptr<std::ostringstream> message;
    };
    std::vector<DeferredExpectation> mDeferredExpectations;

    // Assuming the data is mapped, checks all expectations
    void ResolveExpectations();

    dawn::native::Adapter mBackendAdapter;
    WGPUDevice mLastCreatedBackendDevice;

    std::unique_ptr<dawn::platform::Platform> mTestPlatform;
};

#define DAWN_SKIP_TEST_IF_BASE(condition, type, reason)   \
    do {                                                  \
        if (condition) {                                  \
            dawn::InfoLog() << "Test " type ": " #reason; \
            GTEST_SKIP();                                 \
            return;                                       \
        }                                                 \
    } while (0)

// Skip a test which requires a feature or a toggle to be present / not present or some WIP
// features.
#define DAWN_TEST_UNSUPPORTED_IF(condition) \
    DAWN_SKIP_TEST_IF_BASE(condition, "unsupported", condition)

// Skip a test when the test failing on a specific HW / backend / OS combination. We can disable
// this macro with the command line parameter "--run-suppressed-tests".
#define DAWN_SUPPRESS_TEST_IF(condition) \
    DAWN_SKIP_TEST_IF_BASE(!RunSuppressedTests() && condition, "suppressed", condition)

#define EXPECT_DEPRECATION_WARNINGS(statement, n)                                 \
    do {                                                                          \
        if (UsesWire()) {                                                         \
            statement;                                                            \
        } else {                                                                  \
            size_t warningsBefore =                                               \
                dawn::native::GetDeprecationWarningCountForTesting(device.Get()); \
            statement;                                                            \
            size_t warningsAfter =                                                \
                dawn::native::GetDeprecationWarningCountForTesting(device.Get()); \
            EXPECT_EQ(mLastWarningCount, warningsBefore);                         \
            if (!HasToggleEnabled("skip_validation")) {                           \
                EXPECT_EQ(warningsAfter, warningsBefore + n);                     \
            }                                                                     \
            mLastWarningCount = warningsAfter;                                    \
        }                                                                         \
    } while (0)
#define EXPECT_DEPRECATION_WARNING(statement) EXPECT_DEPRECATION_WARNINGS(statement, 1)

template <typename Params = AdapterTestParam>
class DawnTestWithParams : public DawnTestBase, public ::testing::TestWithParam<Params> {
  protected:
    DawnTestWithParams();
    ~DawnTestWithParams() override = default;

    void SetUp() override { DawnTestBase::SetUp(); }

    void TearDown() override { DawnTestBase::TearDown(); }
};

template <typename Params>
DawnTestWithParams<Params>::DawnTestWithParams() : DawnTestBase(this->GetParam()) {}

using DawnTest = DawnTestWithParams<>;

// Instantiate the test once for each backend provided after the first argument. Use it like this:
//     DAWN_INSTANTIATE_TEST(MyTestFixture, MetalBackend, OpenGLBackend)
#define DAWN_INSTANTIATE_TEST(testName, ...)                                            \
    const decltype(DAWN_PP_GET_HEAD(__VA_ARGS__)) testName##params[] = {__VA_ARGS__};   \
    INSTANTIATE_TEST_SUITE_P(                                                           \
        , testName,                                                                     \
        testing::ValuesIn(::detail::GetAvailableAdapterTestParamsForBackends(           \
            testName##params, sizeof(testName##params) / sizeof(testName##params[0]))), \
        DawnTestBase::PrintToStringParamName(#testName));                               \
    GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(testName)

// Instantiate the test once for each backend provided in the first param list.
// The test will be parameterized over the following param lists.
// Use it like this:
//     DAWN_INSTANTIATE_TEST_P(MyTestFixture, {MetalBackend(), OpenGLBackend()}, {A, B}, {1, 2})
// MyTestFixture must extend DawnTestWithParams<Param> where Param is a struct that extends
// AdapterTestParam, and whose constructor looks like:
//     Param(AdapterTestParam, ABorC, 12or3, ..., otherParams... )
//     You must also teach GTest how to print this struct.
//     https://github.com/google/googletest/blob/main/docs/advanced.md#teaching-googletest-how-to-print-your-values
// Macro DAWN_TEST_PARAM_STRUCT can help generate this struct.
#define DAWN_INSTANTIATE_TEST_P(testName, ...)                                                 \
    INSTANTIATE_TEST_SUITE_P(                                                                  \
        , testName, ::testing::ValuesIn(MakeParamGenerator<testName::ParamType>(__VA_ARGS__)), \
        DawnTestBase::PrintToStringParamName(#testName));                                      \
    GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(testName)

// Implementation for DAWN_TEST_PARAM_STRUCT to declare/print struct fields.
#define DAWN_TEST_PARAM_STRUCT_DECL_STRUCT_FIELD(Type) Type DAWN_PP_CONCATENATE(m, Type);
#define DAWN_TEST_PARAM_STRUCT_PRINT_STRUCT_FIELD(Type) \
    o << "; " << #Type << "=" << param.DAWN_PP_CONCATENATE(m, Type);

// Usage: DAWN_TEST_PARAM_STRUCT(Foo, TypeA, TypeB, ...)
// Generate a test param struct called Foo which extends AdapterTestParam and generated
// struct _Dawn_Foo. _Dawn_Foo has members of types TypeA, TypeB, etc. which are named mTypeA,
// mTypeB, etc. in the order they are placed in the macro argument list. Struct Foo should be
// constructed with an AdapterTestParam as the first argument, followed by a list of values
// to initialize the base _Dawn_Foo struct.
// It is recommended to use alias declarations so that stringified types are more readable.
// Example:
//   using MyParam = unsigned int;
//   DAWN_TEST_PARAM_STRUCT(FooParams, MyParam);
#define DAWN_TEST_PARAM_STRUCT(StructName, ...)                                                    \
    struct DAWN_PP_CONCATENATE(_Dawn_, StructName) {                                               \
        DAWN_PP_EXPAND(DAWN_PP_EXPAND(DAWN_PP_FOR_EACH)(DAWN_TEST_PARAM_STRUCT_DECL_STRUCT_FIELD,  \
                                                        __VA_ARGS__))                              \
    };                                                                                             \
    std::ostream& operator<<(std::ostream& o,                                                      \
                             const DAWN_PP_CONCATENATE(_Dawn_, StructName) & param) {              \
        DAWN_PP_EXPAND(DAWN_PP_EXPAND(DAWN_PP_FOR_EACH)(DAWN_TEST_PARAM_STRUCT_PRINT_STRUCT_FIELD, \
                                                        __VA_ARGS__))                              \
        return o;                                                                                  \
    }                                                                                              \
    struct StructName : AdapterTestParam, DAWN_PP_CONCATENATE(_Dawn_, StructName) {                \
        template <typename... Args>                                                                \
        StructName(const AdapterTestParam& param, Args&&... args)                                  \
            : AdapterTestParam(param),                                                             \
              DAWN_PP_CONCATENATE(_Dawn_, StructName){std::forward<Args>(args)...} {}              \
    };                                                                                             \
    std::ostream& operator<<(std::ostream& o, const StructName& param) {                           \
        o << static_cast<const AdapterTestParam&>(param);                                          \
        o << "; " << static_cast<const DAWN_PP_CONCATENATE(_Dawn_, StructName)&>(param);           \
        return o;                                                                                  \
    }                                                                                              \
    static_assert(true, "require semicolon")

namespace detail {
// Helper functions used for DAWN_INSTANTIATE_TEST
std::vector<AdapterTestParam> GetAvailableAdapterTestParamsForBackends(
    const BackendTestConfig* params,
    size_t numParams);

// All classes used to implement the deferred expectations should inherit from this.
class Expectation {
  public:
    virtual ~Expectation() = default;

    // Will be called with the buffer or texture data the expectation should check.
    virtual testing::AssertionResult Check(const void* data, size_t size) = 0;
};

template <typename T>
class ExpectConstant : public Expectation {
  public:
    explicit ExpectConstant(T constant);
    uint32_t DataSize();
    testing::AssertionResult Check(const void* data, size_t size) override;

  private:
    T mConstant;
};

extern template class ExpectConstant<float>;

// Expectation that checks the data is equal to some expected values.
// T - expected value Type
// U - actual value Type (defaults = T)
// This is expanded for float16 mostly where T=float, U=uint16_t
template <typename T, typename U>
class ExpectEq : public Expectation {
  public:
    explicit ExpectEq(T singleValue, T tolerance = {});
    ExpectEq(const T* values, const unsigned int count, T tolerance = {});

    testing::AssertionResult Check(const void* data, size_t size) override;

  private:
    std::vector<T> mExpected;
    T mTolerance;
};
extern template class ExpectEq<uint8_t>;
extern template class ExpectEq<int16_t>;
extern template class ExpectEq<uint32_t>;
extern template class ExpectEq<uint64_t>;
extern template class ExpectEq<utils::RGBA8>;
extern template class ExpectEq<float>;
extern template class ExpectEq<float, uint16_t>;

template <typename T>
class ExpectBetweenColors : public Expectation {
  public:
    // Inclusive for now
    ExpectBetweenColors(T value0, T value1);
    testing::AssertionResult Check(const void* data, size_t size) override;

  private:
    std::vector<T> mLowerColorChannels;
    std::vector<T> mHigherColorChannels;

    // used for printing error
    std::vector<T> mValues0;
    std::vector<T> mValues1;
};
// A color is considered between color0 and color1 when all channel values are within range of
// each counterparts. It doesn't matter which value is higher or lower. Essentially color =
// lerp(color0, color1, t) where t is [0,1]. But I don't want to be too strict here.
extern template class ExpectBetweenColors<utils::RGBA8>;

class CustomTextureExpectation : public Expectation {
  public:
    ~CustomTextureExpectation() override = default;
    virtual uint32_t DataSize() = 0;
};

}  // namespace detail

#endif  // SRC_DAWN_TESTS_DAWNTEST_H_
