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