// 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 TESTS_DAWNTEST_H_
#define TESTS_DAWNTEST_H_

#include "common/Log.h"
#include "common/Platform.h"
#include "common/Preprocessor.h"
#include "dawn/dawn_proc_table.h"
#include "dawn/webgpu_cpp.h"
#include "dawn/webgpu_cpp_print.h"
#include "dawn_native/DawnNative.h"
#include "tests/ParamGenerator.h"
#include "tests/ToggleParser.h"
#include "utils/ScopedAutoreleasePool.h"

#include <dawn_platform/DawnPlatform.h>
#include <gtest/gtest.h>

#include <memory>
#include <unordered_map>
#include <vector>

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

#define EXPECT_BUFFER(buffer, offset, size, expectation) \
    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__)

// Should only be used to test validation of function that can't be tested by regular validation
// tests;
#define ASSERT_DEVICE_ERROR(statement)                          \
    StartExpectDeviceError();                                   \
    statement;                                                  \
    FlushWire();                                                \
    if (!EndExpectDeviceError()) {                              \
        FAIL() << "Expected device error in:\n " << #statement; \
    }                                                           \
    do {                                                        \
    } while (0)

struct RGBA8 {
    constexpr RGBA8() : RGBA8(0, 0, 0, 0) {
    }
    constexpr RGBA8(uint8_t r, uint8_t g, uint8_t b, uint8_t a) : r(r), g(g), b(b), a(a) {
    }
    bool operator==(const RGBA8& other) const;
    bool operator!=(const RGBA8& other) const;
    bool operator<=(const RGBA8& other) const;
    bool operator>=(const RGBA8& other) const;

    uint8_t r, g, b, a;

    static const RGBA8 kZero;
    static const RGBA8 kBlack;
    static const RGBA8 kRed;
    static const RGBA8 kGreen;
    static const RGBA8 kBlue;
    static const RGBA8 kYellow;
    static const RGBA8 kWhite;
};
std::ostream& operator<<(std::ostream& stream, const RGBA8& color);

struct BackendTestConfig {
    BackendTestConfig(wgpu::BackendType backendType,
                      std::initializer_list<const char*> forceEnabledWorkarounds = {},
                      std::initializer_list<const char*> forceDisabledWorkarounds = {});

    wgpu::BackendType backendType;

    std::vector<const char*> forceEnabledWorkarounds;
    std::vector<const char*> forceDisabledWorkarounds;
};

struct TestAdapterProperties : wgpu::AdapterProperties {
    TestAdapterProperties(const wgpu::AdapterProperties& properties, bool selected);
    std::string adapterName;
    bool selected;

  private:
    // This may be temporary, so it is copied into |adapterName| and made private.
    using wgpu::AdapterProperties::name;
};

struct AdapterTestParam {
    AdapterTestParam(const BackendTestConfig& config,
                     const TestAdapterProperties& adapterProperties);

    TestAdapterProperties adapterProperties;
    std::vector<const char*> forceEnabledWorkarounds;
    std::vector<const char*> forceDisabledWorkarounds;
};

std::ostream& operator<<(std::ostream& os, const AdapterTestParam& param);

BackendTestConfig D3D12Backend(std::initializer_list<const char*> forceEnabledWorkarounds = {},
                               std::initializer_list<const char*> forceDisabledWorkarounds = {});

BackendTestConfig MetalBackend(std::initializer_list<const char*> forceEnabledWorkarounds = {},
                               std::initializer_list<const char*> forceDisabledWorkarounds = {});

BackendTestConfig NullBackend(std::initializer_list<const char*> forceEnabledWorkarounds = {},
                              std::initializer_list<const char*> forceDisabledWorkarounds = {});

BackendTestConfig OpenGLBackend(std::initializer_list<const char*> forceEnabledWorkarounds = {},
                                std::initializer_list<const char*> forceDisabledWorkarounds = {});

BackendTestConfig OpenGLESBackend(std::initializer_list<const char*> forceEnabledWorkarounds = {},
                                  std::initializer_list<const char*> forceDisabledWorkarounds = {});

BackendTestConfig VulkanBackend(std::initializer_list<const char*> forceEnabledWorkarounds = {},
                                std::initializer_list<const char*> forceDisabledWorkarounds = {});

struct GLFWwindow;

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

namespace detail {
    class Expectation;
    class CustomTextureExpectation;

    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;
    GLFWwindow* GetOpenGLWindow() const;
    GLFWwindow* GetOpenGLESWindow() 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;
    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<dawn_native::DeviceType> mDevicePreferences;
    std::vector<TestAdapterProperties> mAdapterProperties;

    std::unique_ptr<utils::PlatformDebugLogger> mPlatformDebugLogger;
    GLFWwindow* mOpenGLWindow;
    GLFWwindow* mOpenGLESWindow;
};

class DawnTestBase {
    friend class DawnPerfTestBase;

  public:
    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 IsARM() const;
    bool IsImgTec() const;
    bool IsIntel() const;
    bool IsNvidia() const;
    bool IsQualcomm() const;
    bool IsSwiftshader() const;
    bool IsANGLE() const;
    bool IsWARP() const;

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

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

    bool IsDXC() const;

    bool IsAsan() const;

    bool HasToggleEnabled(const char* workaround) const;

    void StartExpectDeviceError();
    bool EndExpectDeviceError();

    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 {
        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;
    };

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

    DawnProcTable backendProcs = {};
    WGPUDevice backendDevice = nullptr;

    size_t mLastWarningCount = 0;

    // 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);

    // T - expected value Type
    // U - actual value Type (defaults = T)
    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) {
        return AddTextureExpectationImpl(
            file, line,
            new detail::ExpectEq<T, U>(expectedData,
                                       extent.width * extent.height * extent.depthOrArrayLayers),
            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) {
        return AddTextureExpectationImpl(file, line, 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) {
        return AddTextureExpectationImpl(file, line, 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) {
        return AddTextureExpectationImpl(
            file, line, 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();
    void FlushWire();
    void WaitForAllOperations();

    bool SupportsFeatures(const std::vector<const char*>& features);

    // 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<const char*> GetRequiredFeatures();

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

    const wgpu::AdapterProperties& GetAdapterProperties() const;

    // TODO(crbug.com/dawn/689): Use limits returned from the wire
    // This is implemented here because tests need to always query
    // the |backendDevice| since limits are not implemented in the wire.
    wgpu::SupportedLimits GetSupportedLimits();

  private:
    utils::ScopedAutoreleasePool mObjCAutoreleasePool;
    AdapterTestParam mParam;
    std::unique_ptr<utils::WireHelper> mWireHelper;

    // Tracking for validation errors
    static void OnDeviceError(WGPUErrorType type, const char* message, void* userdata);
    static void OnDeviceLost(WGPUDeviceLostReason reason, const char* message, void* userdata);
    bool mExpectError = false;
    bool mError = false;

    std::ostringstream& AddTextureExpectationImpl(const char* file,
                                                  int line,
                                                  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::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::Buffer buffer;
        size_t slot;
        uint64_t offset;
    };
    ReadbackReservation ReserveReadback(uint64_t readbackSize);

    struct DeferredExpectation {
        const char* file;
        int line;
        size_t readbackSlot;
        uint64_t readbackOffset;
        uint64_t size;
        uint32_t rowBytes;
        uint32_t bytesPerRow;
        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;

    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, C}, {1, 2, 3})
// MyTestFixture must extend DawnTestWithParam<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/master/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;                                                                                  \
    }

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;
    };

    // 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:
        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<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<RGBA8>;

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

}  // namespace detail

#endif  // TESTS_DAWNTEST_H_
