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

#include <initializer_list>
#include <unordered_set>
#include <vector>

#include "dawn/common/Constants.h"
#include "dawn/common/StringViewUtils.h"
#include "dawn/tests/MockCallback.h"
#include "dawn/tests/StringViewMatchers.h"
#include "dawn/tests/unittests/wire/WireFutureTest.h"
#include "dawn/tests/unittests/wire/WireTest.h"
#include "dawn/wire/WireClient.h"
#include "dawn/wire/WireServer.h"
#include "webgpu/webgpu_cpp.h"

namespace dawn::wire {
namespace {

using testing::_;
using testing::EmptySizedString;
using testing::InvokeWithoutArgs;
using testing::IsNull;
using testing::NonEmptySizedString;
using testing::NotNull;
using testing::Return;
using testing::SizedString;
using testing::StrEq;
using testing::WithArg;

class WireInstanceBasicTest : public WireTest {};

// Test that an Instance can be reserved and injected into the wire.
TEST_F(WireInstanceBasicTest, ReserveAndInject) {
    auto reserved = GetWireClient()->ReserveInstance();
    wgpu::Instance instance = wgpu::Instance::Acquire(reserved.instance);

    WGPUInstance apiInstance = api.GetNewInstance();
    EXPECT_CALL(api, InstanceAddRef(apiInstance));
    EXPECT_TRUE(GetWireServer()->InjectInstance(apiInstance, reserved.handle));

    instance = nullptr;

    EXPECT_CALL(api, InstanceRelease(apiInstance));
    FlushClient();
}

using WireInstanceTestBase = WireFutureTest<wgpu::RequestAdapterCallback<void>*>;
class WireInstanceTests : public WireInstanceTestBase {
  protected:
    void RequestAdapter(wgpu::RequestAdapterOptions const* options) {
        this->mFutureIDs.push_back(
            instance
                .RequestAdapter(options, this->GetParam().callbackMode, this->mMockCb.Callback())
                .id);
    }
};

DAWN_INSTANTIATE_WIRE_FUTURE_TEST_P(WireInstanceTests);

// Test that RequestAdapterOptions are passed from the client to the server.
TEST_P(WireInstanceTests, RequestAdapterPassesOptions) {
    for (auto powerPreference :
         {wgpu::PowerPreference::LowPower, wgpu::PowerPreference::HighPerformance}) {
        wgpu::RequestAdapterOptions options = {};
        options.powerPreference = powerPreference;

        RequestAdapter(&options);

        EXPECT_CALL(api, OnInstanceRequestAdapter(apiInstance, NotNull(), _))
            .WillOnce(WithArg<1>([&](const WGPURequestAdapterOptions* apiOptions) {
                EXPECT_EQ(apiOptions->powerPreference,
                          static_cast<WGPUPowerPreference>(options.powerPreference));
                EXPECT_EQ(apiOptions->forceFallbackAdapter, options.forceFallbackAdapter);
                api.CallInstanceRequestAdapterCallback(apiInstance, WGPURequestAdapterStatus_Error,
                                                       nullptr, kEmptyOutputStringView);
            }));

        FlushClient();
        FlushFutures();
        ExpectWireCallbacksWhen([&](auto& mockCb) {
            EXPECT_CALL(mockCb, Call).Times(1);

            FlushCallbacks();
        });
    }
}

// Test that RequestAdapter forwards the adapter information to the client.
TEST_P(WireInstanceTests, RequestAdapterSuccess) {
    wgpu::RequestAdapterOptions options = {};
    RequestAdapter(&options);

    WGPUAdapterInfo fakeInfo = {};
    fakeInfo.vendor = ToOutputStringView("fake-vendor");
    fakeInfo.architecture = ToOutputStringView("fake-architecture");
    fakeInfo.device = ToOutputStringView("fake-device");
    fakeInfo.description = ToOutputStringView("fake-description");
    fakeInfo.backendType = WGPUBackendType_D3D12;
    fakeInfo.adapterType = WGPUAdapterType_IntegratedGPU;
    fakeInfo.vendorID = 0x134;
    fakeInfo.deviceID = 0x918;
    fakeInfo.subgroupMinSize = kDefaultSubgroupMinSize;
    fakeInfo.subgroupMaxSize = kDefaultSubgroupMaxSize;

    wgpu::Limits fakeLimits = {};
    fakeLimits.maxTextureDimension1D = 433;
    fakeLimits.maxVertexAttributes = 1243;

    std::initializer_list<WGPUFeatureName> fakeFeaturesList = {
        WGPUFeatureName_Depth32FloatStencil8,
        WGPUFeatureName_TextureCompressionBC,
    };
    WGPUSupportedFeatures fakeFeatures = {fakeFeaturesList.size(), std::data(fakeFeaturesList)};

    // Expect the server to receive the message. Then, mock a fake reply.
    WGPUAdapter apiAdapter = api.GetNewAdapter();
    EXPECT_CALL(api, OnInstanceRequestAdapter(apiInstance, NotNull(), _))
        .WillOnce(InvokeWithoutArgs([&] {
            EXPECT_CALL(api, AdapterHasFeature(apiAdapter, _)).WillRepeatedly(Return(false));

            EXPECT_CALL(api, AdapterGetInfo(apiAdapter, NotNull()))
                .WillOnce(WithArg<1>([&](WGPUAdapterInfo* info) {
                    *info = fakeInfo;
                    return WGPUStatus_Success;
                }));

            EXPECT_CALL(api, AdapterGetLimits(apiAdapter, NotNull()))
                .WillOnce(WithArg<1>([&](WGPULimits* limits) {
                    *reinterpret_cast<wgpu::Limits*>(limits) = fakeLimits;
                    return WGPUStatus_Success;
                }));

            EXPECT_CALL(api, AdapterGetFeatures(apiAdapter, NotNull()))
                .WillOnce(
                    WithArg<1>([&](WGPUSupportedFeatures* features) { *features = fakeFeatures; }));

            api.CallInstanceRequestAdapterCallback(apiInstance, WGPURequestAdapterStatus_Success,
                                                   apiAdapter, kEmptyOutputStringView);
        }));

    FlushClient();
    FlushFutures();

    // Expect the callback in the client and all the adapter information to match.
    ExpectWireCallbacksWhen([&](auto& mockCb) {
        EXPECT_CALL(mockCb,
                    Call(wgpu::RequestAdapterStatus::Success, NotNull(), EmptySizedString()))
            .WillOnce(WithArg<1>([&](wgpu::Adapter adapter) {
                WGPUAdapterInfo info = {};
                adapter.GetInfo(reinterpret_cast<wgpu::AdapterInfo*>(&info));
                EXPECT_NE(info.vendor.length, WGPU_STRLEN);
                EXPECT_EQ(info.vendor, fakeInfo.vendor);
                EXPECT_NE(info.architecture.length, WGPU_STRLEN);
                EXPECT_EQ(info.architecture, fakeInfo.architecture);
                EXPECT_NE(info.device.length, WGPU_STRLEN);
                EXPECT_EQ(info.device, fakeInfo.device);
                EXPECT_NE(info.description.length, WGPU_STRLEN);
                EXPECT_EQ(info.description, fakeInfo.description);
                EXPECT_EQ(info.backendType, fakeInfo.backendType);
                EXPECT_EQ(info.adapterType, fakeInfo.adapterType);
                EXPECT_EQ(info.vendorID, fakeInfo.vendorID);
                EXPECT_EQ(info.deviceID, fakeInfo.deviceID);
                EXPECT_EQ(info.subgroupMinSize, fakeInfo.subgroupMinSize);
                EXPECT_EQ(info.subgroupMaxSize, fakeInfo.subgroupMaxSize);

                wgpu::Limits limits = {};
                EXPECT_EQ(adapter.GetLimits(&limits), wgpu::Status::Success);
                EXPECT_EQ(limits.maxTextureDimension1D, fakeLimits.maxTextureDimension1D);
                EXPECT_EQ(limits.maxVertexAttributes, fakeLimits.maxVertexAttributes);

                WGPUSupportedFeatures features = {};
                adapter.GetFeatures(reinterpret_cast<wgpu::SupportedFeatures*>(&features));

                std::vector<WGPUFeatureName> featuresList(
                    features.features, features.features + features.featureCount);
                ASSERT_EQ(featuresList.size(), fakeFeaturesList.size());
                std::unordered_set<WGPUFeatureName> featureSet(fakeFeaturesList);
                for (WGPUFeatureName feature : featuresList) {
                    EXPECT_EQ(featureSet.erase(feature), 1u);
                }
            }));

        FlushCallbacks();
    });
}

// Test that RequestAdapter forwards all chained properties to the client.
TEST_P(WireInstanceTests, RequestAdapterPassesChainedProperties) {
    wgpu::RequestAdapterOptions options = {};
    RequestAdapter(&options);

    WGPUMemoryHeapInfo fakeHeapInfo[3] = {
        {WGPUHeapProperty_DeviceLocal, 64},
        {WGPUHeapProperty_DeviceLocal | WGPUHeapProperty_HostVisible, 136},
        {WGPUHeapProperty_HostCached | WGPUHeapProperty_HostVisible, 460},
    };

    WGPUAdapterPropertiesMemoryHeaps fakeMemoryHeapProperties = {};
    fakeMemoryHeapProperties.chain.sType = WGPUSType_AdapterPropertiesMemoryHeaps;
    fakeMemoryHeapProperties.heapCount = 3;
    fakeMemoryHeapProperties.heapInfo = fakeHeapInfo;

    WGPUAdapterPropertiesD3D fakeD3DProperties = {};
    fakeD3DProperties.chain.sType = WGPUSType_AdapterPropertiesD3D;
    fakeD3DProperties.shaderModel = 61;

    WGPUAdapterPropertiesVk fakeVkProperties = {};
    fakeVkProperties.chain.sType = WGPUSType_AdapterPropertiesVk;
    fakeVkProperties.driverVersion = 0x801F6000;

    WGPUSubgroupMatrixConfig fakeMatrixConfigs[3] = {
        {WGPUSubgroupMatrixComponentType_F32, WGPUSubgroupMatrixComponentType_F32, 8, 4, 2},
        {WGPUSubgroupMatrixComponentType_U32, WGPUSubgroupMatrixComponentType_I32, 4, 8, 16},
        {WGPUSubgroupMatrixComponentType_F16, WGPUSubgroupMatrixComponentType_F32, 2, 16, 4},
    };

    WGPUAdapterPropertiesSubgroupMatrixConfigs fakeSubgroupMatrixConfigs = {};
    fakeSubgroupMatrixConfigs.chain.sType = WGPUSType_AdapterPropertiesSubgroupMatrixConfigs;
    fakeSubgroupMatrixConfigs.configCount = 3;
    fakeSubgroupMatrixConfigs.configs = fakeMatrixConfigs;

    WGPUDawnAdapterPropertiesPowerPreference fakePowerProperties = {};
    fakePowerProperties.chain.sType = WGPUSType_DawnAdapterPropertiesPowerPreference;
    fakePowerProperties.powerPreference = WGPUPowerPreference::WGPUPowerPreference_LowPower;

    WGPUAdapterPropertiesExplicitComputeSubgroupSizeConfigs fakeExplicitComputeSubgroupSizeConfigs =
        {};
    fakeExplicitComputeSubgroupSizeConfigs.chain.sType =
        WGPUSType_AdapterPropertiesExplicitComputeSubgroupSizeConfigs;
    fakeExplicitComputeSubgroupSizeConfigs.minExplicitComputeSubgroupSize = 8;
    fakeExplicitComputeSubgroupSizeConfigs.maxExplicitComputeSubgroupSize = 32;

    std::initializer_list<WGPUFeatureName> fakeFeaturesList = {
        WGPUFeatureName_AdapterPropertiesMemoryHeaps,
        WGPUFeatureName_AdapterPropertiesD3D,
        WGPUFeatureName_AdapterPropertiesVk,
        WGPUFeatureName_ChromiumExperimentalSubgroupMatrix,
        WGPUFeatureName_ChromiumExperimentalSubgroupSizeControl,
    };
    WGPUSupportedFeatures fakeFeatures = {fakeFeaturesList.size(), std::data(fakeFeaturesList)};

    // Expect the server to receive the message. Then, mock a fake reply.
    WGPUAdapter apiAdapter = api.GetNewAdapter();
    EXPECT_CALL(api, OnInstanceRequestAdapter(apiInstance, NotNull(), _))
        .WillOnce(InvokeWithoutArgs([&] {
            EXPECT_CALL(api, AdapterGetLimits(apiAdapter, NotNull())).Times(1);
            EXPECT_CALL(api, AdapterGetFeatures(apiAdapter, NotNull()))
                .WillOnce(
                    WithArg<1>([&](WGPUSupportedFeatures* features) { *features = fakeFeatures; }));

            for (WGPUFeatureName feature : fakeFeaturesList) {
                EXPECT_CALL(api, AdapterHasFeature(apiAdapter, feature)).WillOnce(Return(true));
            }
            EXPECT_CALL(api, AdapterGetInfo(apiAdapter, NotNull()))
                .WillOnce(WithArg<1>([&](WGPUAdapterInfo* info) {
                    WGPUChainedStruct* chain = info->nextInChain;
                    while (chain != nullptr) {
                        auto* next = chain->next;
                        switch (chain->sType) {
                            case WGPUSType_AdapterPropertiesMemoryHeaps:
                                *reinterpret_cast<WGPUAdapterPropertiesMemoryHeaps*>(chain) =
                                    fakeMemoryHeapProperties;
                                break;
                            case WGPUSType_AdapterPropertiesD3D:
                                *reinterpret_cast<WGPUAdapterPropertiesD3D*>(chain) =
                                    fakeD3DProperties;
                                break;
                            case WGPUSType_AdapterPropertiesVk:
                                *reinterpret_cast<WGPUAdapterPropertiesVk*>(chain) =
                                    fakeVkProperties;
                                break;
                            case WGPUSType_AdapterPropertiesSubgroupMatrixConfigs:
                                *reinterpret_cast<WGPUAdapterPropertiesSubgroupMatrixConfigs*>(
                                    chain) = fakeSubgroupMatrixConfigs;
                                break;
                            case WGPUSType_DawnAdapterPropertiesPowerPreference:
                                *reinterpret_cast<WGPUDawnAdapterPropertiesPowerPreference*>(
                                    chain) = fakePowerProperties;
                                break;
                            case WGPUSType_AdapterPropertiesExplicitComputeSubgroupSizeConfigs:
                                *reinterpret_cast<
                                    WGPUAdapterPropertiesExplicitComputeSubgroupSizeConfigs*>(
                                    chain) = fakeExplicitComputeSubgroupSizeConfigs;
                                break;
                            default:
                                ADD_FAILURE() << "Unexpected chain";
                                return WGPUStatus_Error;
                        }
                        // Update next pointer back to the original since it would be overwritten
                        // in the switch statement
                        chain->next = next;
                        chain = next;
                    }
                    return WGPUStatus_Success;
                }));

            api.CallInstanceRequestAdapterCallback(apiInstance, WGPURequestAdapterStatus_Success,
                                                   apiAdapter, kEmptyOutputStringView);
        }));

    FlushClient();
    FlushFutures();

    // Expect the callback in the client and the adapter information to match.
    ExpectWireCallbacksWhen([&](auto& mockCb) {
        EXPECT_CALL(mockCb,
                    Call(wgpu::RequestAdapterStatus::Success, NotNull(), EmptySizedString()))
            .WillOnce(WithArg<1>([&](wgpu::Adapter adapter) {
                // Request info without a chained struct.
                // It should be nullptr.
                WGPUAdapterInfo info = {};
                adapter.GetInfo(reinterpret_cast<wgpu::AdapterInfo*>(&info));
                EXPECT_EQ(info.nextInChain, nullptr);

                // Request the memory heap properties.
                WGPUAdapterPropertiesMemoryHeaps memoryHeapProperties = {};
                memoryHeapProperties.chain.sType = WGPUSType_AdapterPropertiesMemoryHeaps;
                info.nextInChain = &memoryHeapProperties.chain;
                adapter.GetInfo(reinterpret_cast<wgpu::AdapterInfo*>(&info));

                // Expect everything matches the fake properties returned by the server.
                EXPECT_EQ(memoryHeapProperties.heapCount, fakeMemoryHeapProperties.heapCount);
                for (size_t i = 0; i < fakeMemoryHeapProperties.heapCount; ++i) {
                    EXPECT_EQ(memoryHeapProperties.heapInfo[i].properties,
                              fakeMemoryHeapProperties.heapInfo[i].properties);
                    EXPECT_EQ(memoryHeapProperties.heapInfo[i].size,
                              fakeMemoryHeapProperties.heapInfo[i].size);
                }

                // Get the D3D properties.
                WGPUAdapterPropertiesD3D d3dProperties = {};
                d3dProperties.chain.sType = WGPUSType_AdapterPropertiesD3D;
                info.nextInChain = &d3dProperties.chain;
                adapter.GetInfo(reinterpret_cast<wgpu::AdapterInfo*>(&info));
                // Expect them to match.
                EXPECT_EQ(d3dProperties.shaderModel, fakeD3DProperties.shaderModel);

                // Get the Vulkan properties.
                WGPUAdapterPropertiesVk vkProperties = {};
                vkProperties.chain.sType = WGPUSType_AdapterPropertiesVk;
                info.nextInChain = &vkProperties.chain;
                adapter.GetInfo(reinterpret_cast<wgpu::AdapterInfo*>(&info));
                // Expect them to match.
                EXPECT_EQ(vkProperties.driverVersion, fakeVkProperties.driverVersion);

                // Get the subgroup matrix properties.
                WGPUAdapterPropertiesSubgroupMatrixConfigs subgroupMatrixConfigs = {};
                subgroupMatrixConfigs.chain.sType =
                    WGPUSType_AdapterPropertiesSubgroupMatrixConfigs;
                info.nextInChain = &subgroupMatrixConfigs.chain;
                adapter.GetInfo(reinterpret_cast<wgpu::AdapterInfo*>(&info));

                // Expect everything matches the fake properties returned by the server.
                EXPECT_EQ(subgroupMatrixConfigs.configCount, fakeSubgroupMatrixConfigs.configCount);
                for (size_t i = 0; i < fakeSubgroupMatrixConfigs.configCount; ++i) {
                    EXPECT_EQ(subgroupMatrixConfigs.configs[i].componentType,
                              fakeSubgroupMatrixConfigs.configs[i].componentType);
                    EXPECT_EQ(subgroupMatrixConfigs.configs[i].resultComponentType,
                              fakeSubgroupMatrixConfigs.configs[i].resultComponentType);
                    EXPECT_EQ(subgroupMatrixConfigs.configs[i].M,
                              fakeSubgroupMatrixConfigs.configs[i].M);
                    EXPECT_EQ(subgroupMatrixConfigs.configs[i].N,
                              fakeSubgroupMatrixConfigs.configs[i].N);
                    EXPECT_EQ(subgroupMatrixConfigs.configs[i].K,
                              fakeSubgroupMatrixConfigs.configs[i].K);
                }

                // Get the power properties.
                WGPUDawnAdapterPropertiesPowerPreference powerProperties = {};
                powerProperties.chain.sType = WGPUSType_DawnAdapterPropertiesPowerPreference;
                info.nextInChain = &powerProperties.chain;
                adapter.GetInfo(reinterpret_cast<wgpu::AdapterInfo*>(&info));
                // Expect them to match.
                EXPECT_EQ(powerProperties.powerPreference, fakePowerProperties.powerPreference);

                // Get the explicit compute subgroup size properties
                WGPUAdapterPropertiesExplicitComputeSubgroupSizeConfigs subgroupSizeConfigs = {};
                subgroupSizeConfigs.chain.sType =
                    WGPUSType_AdapterPropertiesExplicitComputeSubgroupSizeConfigs;
                info.nextInChain = &subgroupSizeConfigs.chain;
                adapter.GetInfo(reinterpret_cast<wgpu::AdapterInfo*>(&info));
                // Expect them to match
                EXPECT_EQ(subgroupSizeConfigs.minExplicitComputeSubgroupSize,
                          fakeExplicitComputeSubgroupSizeConfigs.minExplicitComputeSubgroupSize);
                EXPECT_EQ(subgroupSizeConfigs.maxExplicitComputeSubgroupSize,
                          fakeExplicitComputeSubgroupSizeConfigs.maxExplicitComputeSubgroupSize);
            }));

        FlushCallbacks();
    });
}

// Test that features returned by the implementation that aren't supported in the wire are not
// exposed.
TEST_P(WireInstanceTests, RequestAdapterWireLacksFeatureSupport) {
    wgpu::RequestAdapterOptions options = {};
    RequestAdapter(&options);

    std::initializer_list<WGPUFeatureName> fakeFeaturesList = {
        WGPUFeatureName_Depth32FloatStencil8,
        // Default feature is an undefined feature.
        {},
    };
    WGPUSupportedFeatures fakeFeatures = {fakeFeaturesList.size(), std::data(fakeFeaturesList)};

    // Expect the server to receive the message. Then, mock a fake reply.
    WGPUAdapter apiAdapter = api.GetNewAdapter();
    EXPECT_CALL(api, OnInstanceRequestAdapter(apiInstance, NotNull(), _))
        .WillOnce(InvokeWithoutArgs([&] {
            EXPECT_CALL(api, AdapterHasFeature(apiAdapter, _)).WillRepeatedly(Return(false));
            EXPECT_CALL(api, AdapterGetInfo(apiAdapter, NotNull())).Times(1);
            EXPECT_CALL(api, AdapterGetLimits(apiAdapter, NotNull())).Times(1);

            EXPECT_CALL(api, AdapterGetFeatures(apiAdapter, NotNull()))
                .WillOnce(
                    WithArg<1>([&](WGPUSupportedFeatures* features) { *features = fakeFeatures; }));

            api.CallInstanceRequestAdapterCallback(apiInstance, WGPURequestAdapterStatus_Success,
                                                   apiAdapter, kEmptyOutputStringView);
        }));

    FlushClient();
    FlushFutures();

    // Expect the callback in the client and all the adapter information to match.
    ExpectWireCallbacksWhen([&](auto& mockCb) {
        EXPECT_CALL(mockCb,
                    Call(wgpu::RequestAdapterStatus::Success, NotNull(), EmptySizedString()))
            .WillOnce(WithArg<1>([&](wgpu::Adapter adapter) {
                WGPUSupportedFeatures features = {};
                adapter.GetFeatures(reinterpret_cast<wgpu::SupportedFeatures*>(&features));
                ASSERT_EQ(features.featureCount, 1u);
                EXPECT_EQ(*features.features, WGPUFeatureName_Depth32FloatStencil8);
            }));

        FlushCallbacks();
    });
}

// Test that RequestAdapter errors forward to the client.
TEST_P(WireInstanceTests, RequestAdapterError) {
    wgpu::RequestAdapterOptions options = {};
    RequestAdapter(&options);

    // Expect the server to receive the message. Then, mock an error.
    EXPECT_CALL(api, OnInstanceRequestAdapter(apiInstance, NotNull(), _))
        .WillOnce(InvokeWithoutArgs([&] {
            api.CallInstanceRequestAdapterCallback(apiInstance, WGPURequestAdapterStatus_Error,
                                                   nullptr, ToOutputStringView("Some error"));
        }));

    FlushClient();
    FlushFutures();

    // Expect the callback in the client.
    ExpectWireCallbacksWhen([&](auto& mockCb) {
        EXPECT_CALL(mockCb,
                    Call(wgpu::RequestAdapterStatus::Error, IsNull(), SizedString("Some error")))
            .Times(1);

        FlushCallbacks();
    });
}

// Test that RequestAdapter receives unknown status if the instance is deleted before the callback
// happens.
TEST_P(WireInstanceTests, RequestAdapterInstanceDestroyedBeforeCallback) {
    // For spontaneous, dropping the instance does not immediately call the callback because it is
    // allowed to resolve later.
    DAWN_SKIP_TEST_IF(IsSpontaneous());

    wgpu::RequestAdapterOptions options = {};
    RequestAdapter(&options);

    ExpectWireCallbacksWhen([&](auto& mockCb) {
        EXPECT_CALL(mockCb, Call(wgpu::RequestAdapterStatus::CallbackCancelled, IsNull(),
                                 NonEmptySizedString()))
            .Times(1);

        instance = nullptr;
    });
}

// Test that RequestAdapter receives unknown status if the wire is disconnected
// before the callback happens.
TEST_P(WireInstanceTests, RequestAdapterWireDisconnectBeforeCallback) {
    wgpu::RequestAdapterOptions options = {};
    RequestAdapter(&options);

    ExpectWireCallbacksWhen([&](auto& mockCb) {
        EXPECT_CALL(mockCb, Call(wgpu::RequestAdapterStatus::CallbackCancelled, IsNull(),
                                 NonEmptySizedString()))
            .Times(1);

        GetWireClient()->Disconnect();
    });
}

}  // anonymous namespace
}  // namespace dawn::wire
