// 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 <unordered_set>
#include <utility>
#include <vector>

#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::WithArg;

using WireAdapterTestBase = WireFutureTest<wgpu::RequestDeviceCallback<void>*>;
class WireAdapterTests : public WireAdapterTestBase {
  protected:
    void RequestDevice(const wgpu::DeviceDescriptor* descriptor) {
        this->mFutureIDs.push_back(
            adapter
                .RequestDevice(descriptor, this->GetParam().callbackMode, this->mMockCb.Callback())
                .id);
    }
};
DAWN_INSTANTIATE_WIRE_FUTURE_TEST_P(WireAdapterTests);

// Test that an empty DeviceDescriptor is passed from the client to the server.
TEST_P(WireAdapterTests, RequestDeviceEmptyDescriptor) {
    wgpu::DeviceDescriptor desc = {};
    RequestDevice(&desc);

    EXPECT_CALL(api, OnAdapterRequestDevice(apiAdapter, NotNull(), _))
        .WillOnce(WithArg<1>([&](const WGPUDeviceDescriptor* apiDesc) {
            EXPECT_EQ(apiDesc->label.data, nullptr);
            EXPECT_EQ(apiDesc->requiredFeatureCount, 0u);
            EXPECT_EQ(apiDesc->requiredLimits, nullptr);

            // Call the callback so the test doesn't wait indefinitely.
            api.CallAdapterRequestDeviceCallback(apiAdapter, WGPURequestDeviceStatus_Error, nullptr,
                                                 kEmptyOutputStringView);
        }));
    FlushClient();
    FlushFutures();
    ExpectWireCallbacksWhen([&](auto& mockCb) {
        EXPECT_CALL(mockCb, Call).Times(1);

        FlushCallbacks();
    });
}

// Test that a null DeviceDescriptor is passed from the client to the server as an empty one.
TEST_P(WireAdapterTests, RequestDeviceNullDescriptor) {
    RequestDevice(nullptr);

    EXPECT_CALL(api, OnAdapterRequestDevice(apiAdapter, NotNull(), _))
        .WillOnce(WithArg<1>([&](const WGPUDeviceDescriptor* apiDesc) {
            EXPECT_EQ(apiDesc->label.data, nullptr);
            EXPECT_EQ(apiDesc->requiredFeatureCount, 0u);
            EXPECT_EQ(apiDesc->requiredLimits, nullptr);

            // Call the callback so the test doesn't wait indefinitely.
            api.CallAdapterRequestDeviceCallback(apiAdapter, WGPURequestDeviceStatus_Error, nullptr,
                                                 kEmptyOutputStringView);
        }));
    FlushClient();
    FlushFutures();
    ExpectWireCallbacksWhen([&](auto& mockCb) {
        EXPECT_CALL(mockCb, Call).Times(1);

        FlushCallbacks();
    });
}

// Test that the DeviceDescriptor is not allowed to pass callbacks from the client to
// the server.
TEST_P(WireAdapterTests, RequestDeviceCallbackPointers) {
    wgpu::DeviceDescriptor desc = {};
    desc.SetDeviceLostCallback(
        wgpu::CallbackMode::AllowSpontaneous,
        [](const wgpu::Device&, wgpu::DeviceLostReason, wgpu::StringView) {});
    desc.SetUncapturedErrorCallback([](const wgpu::Device&, wgpu::ErrorType, wgpu::StringView) {});
    RequestDevice(&desc);

    EXPECT_CALL(api, OnAdapterRequestDevice(apiAdapter, NotNull(), _))
        .WillOnce(WithArg<1>([&](const WGPUDeviceDescriptor* apiDesc) {
            EXPECT_STREQ(apiDesc->label.data, desc.label.data);

            // The callback should not be passed through to the server, and it should be overridden.
            WGPUDeviceDescriptor& inputDesc = *reinterpret_cast<WGPUDeviceDescriptor*>(&desc);
            ASSERT_NE(apiDesc->deviceLostCallbackInfo.callback,
                      inputDesc.deviceLostCallbackInfo.callback);
            ASSERT_NE(apiDesc->deviceLostCallbackInfo.callback, nullptr);
            ASSERT_NE(apiDesc->uncapturedErrorCallbackInfo.callback,
                      inputDesc.uncapturedErrorCallbackInfo.callback);
            ASSERT_NE(apiDesc->uncapturedErrorCallbackInfo.callback, nullptr);

            // Call the callback so the test doesn't wait indefinitely.
            api.CallAdapterRequestDeviceCallback(apiAdapter, WGPURequestDeviceStatus_Error, nullptr,
                                                 kEmptyOutputStringView);
        }));
    FlushClient();
    FlushFutures();
    ExpectWireCallbacksWhen([&](auto& mockCb) {
        EXPECT_CALL(mockCb, Call).Times(1);

        FlushCallbacks();
    });
}

// Test that RequestDevice forwards the device information to the client.
TEST_P(WireAdapterTests, RequestDeviceSuccess) {
    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)};

    wgpu::DeviceDescriptor desc = {};
    RequestDevice(&desc);

    // Expect the server to receive the message. Then, mock a fake reply.
    WGPUDevice apiDevice = api.GetNewDevice();
    // The backend device should not be known by the wire server.
    EXPECT_FALSE(GetWireServer()->IsDeviceKnown(apiDevice));

    EXPECT_CALL(api, OnAdapterRequestDevice(apiAdapter, NotNull(), _))
        .WillOnce(InvokeWithoutArgs([&] {
            // Set on device creation to forward callbacks to the client.
            EXPECT_CALL(api, OnDeviceSetLoggingCallback(apiDevice, _)).Times(1);

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

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

            // The backend device should still not be known by the wire server since the
            // callback has not been called yet.
            EXPECT_FALSE(GetWireServer()->IsDeviceKnown(apiDevice));
            api.CallAdapterRequestDeviceCallback(apiAdapter, WGPURequestDeviceStatus_Success,
                                                 apiDevice, kEmptyOutputStringView);
            // After the callback is called, the backend device is now known by the server.
            EXPECT_TRUE(GetWireServer()->IsDeviceKnown(apiDevice));
        }));

    FlushClient();
    FlushFutures();

    wgpu::Device device;
    // Expect the callback in the client and all the device information to match.
    ExpectWireCallbacksWhen([&](auto& mockCb) {
        EXPECT_CALL(mockCb, Call(wgpu::RequestDeviceStatus::Success, NotNull(), EmptySizedString()))
            .WillOnce(WithArg<1>([&](wgpu::Device result) {
                device = std::move(result);

                wgpu::AdapterInfo adapterInfo;
                EXPECT_EQ(device.GetAdapterInfo(&adapterInfo), wgpu::Status::Success);
                EXPECT_EQ(adapterInfo.vendor, kEmptyOutputStringView);
                EXPECT_EQ(adapterInfo.architecture, kEmptyOutputStringView);
                EXPECT_EQ(adapterInfo.device, kEmptyOutputStringView);
                EXPECT_EQ(adapterInfo.description, kEmptyOutputStringView);

                wgpu::Limits limits;
                EXPECT_EQ(device.GetLimits(&limits), wgpu::Status::Success);
                EXPECT_EQ(limits.maxTextureDimension1D, fakeLimits.maxTextureDimension1D);
                EXPECT_EQ(limits.maxVertexAttributes, fakeLimits.maxVertexAttributes);

                WGPUSupportedFeatures features = {};
                device.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();
    });

    EXPECT_EQ(device.GetAdapter().Get(), adapter.Get());

    device = nullptr;
    // Cleared when the device is destroyed.
    EXPECT_CALL(api, OnDeviceSetLoggingCallback(apiDevice, _)).Times(1);
    EXPECT_CALL(api, DeviceRelease(apiDevice));

    // Server has not recevied the release yet, so the device should be known.
    EXPECT_TRUE(GetWireServer()->IsDeviceKnown(apiDevice));
    FlushClient();
    // After receiving the release call, the device is no longer known by the server.
    EXPECT_FALSE(GetWireServer()->IsDeviceKnown(apiDevice));
}

// Test that features requested that the implementation supports, but not the
// wire reject the callback.
TEST_P(WireAdapterTests, RequestFeatureUnsupportedByWire) {
    std::initializer_list<WGPUFeatureName> fakeFeaturesList = {
        // Default feature is an undefined feature.
        {},
        WGPUFeatureName_TextureCompressionASTC,
    };
    WGPUSupportedFeatures fakeFeatures = {fakeFeaturesList.size(), std::data(fakeFeaturesList)};

    wgpu::DeviceDescriptor desc = {};
    RequestDevice(&desc);

    // Expect the server to receive the message. Then, mock a fake reply.
    // The reply contains features that the device implementation supports, but the
    // wire does not.
    WGPUDevice apiDevice = api.GetNewDevice();
    EXPECT_CALL(api, OnAdapterRequestDevice(apiAdapter, NotNull(), _))
        .WillOnce(InvokeWithoutArgs([&] {
            EXPECT_CALL(api, DeviceGetFeatures(apiDevice, NotNull()))
                .WillOnce(
                    WithArg<1>([&](WGPUSupportedFeatures* features) { *features = fakeFeatures; }));

            // The device was actually created, but the wire didn't support its features.
            // Expect it to be released.
            EXPECT_CALL(api, DeviceRelease(apiDevice));

            // Fake successful creation. The client still receives a failure due to
            // unsupported features.
            api.CallAdapterRequestDeviceCallback(apiAdapter, WGPURequestDeviceStatus_Success,
                                                 apiDevice, kEmptyOutputStringView);
        }));
    FlushClient();
    FlushFutures();

    // Expect an error callback since the feature is not supported.
    ExpectWireCallbacksWhen([&](auto& mockCb) {
        EXPECT_CALL(mockCb, Call(wgpu::RequestDeviceStatus::Error, IsNull(), NonEmptySizedString()))
            .Times(1);

        FlushCallbacks();
    });
}

// Test that RequestDevice errors forward to the client.
TEST_P(WireAdapterTests, RequestDeviceError) {
    wgpu::DeviceDescriptor desc = {};
    RequestDevice(&desc);

    // Expect the server to receive the message. Then, mock an error.
    EXPECT_CALL(api, OnAdapterRequestDevice(apiAdapter, NotNull(), _))
        .WillOnce(InvokeWithoutArgs([&] {
            api.CallAdapterRequestDeviceCallback(apiAdapter, WGPURequestDeviceStatus_Error, nullptr,
                                                 ToOutputStringView("Request device failed"));
        }));
    FlushClient();
    FlushFutures();

    // Expect the callback in the client.
    ExpectWireCallbacksWhen([&](auto& mockCb) {
        EXPECT_CALL(mockCb, Call(wgpu::RequestDeviceStatus::Error, IsNull(),
                                 SizedString("Request device failed")))
            .Times(1);
        FlushCallbacks();
    });
}

// Test that RequestDevice can complete successfully even if the adapter is deleted
// before the callback happens.
TEST_P(WireAdapterTests, RequestDeviceAdapterDestroyedBeforeCallback) {
    wgpu::DeviceDescriptor desc = {};
    RequestDevice(&desc);
    adapter = nullptr;

    // Mock a reply from the server.
    WGPUDevice apiDevice = api.GetNewDevice();
    EXPECT_CALL(api, OnAdapterRequestDevice(apiAdapter, NotNull(), _))
        .WillOnce(InvokeWithoutArgs([&] {
            // Set on device creation to forward callbacks to the client.
            EXPECT_CALL(api, OnDeviceSetLoggingCallback(apiDevice, _)).Times(1);
            EXPECT_CALL(api, DeviceGetLimits(apiDevice, NotNull())).Times(1);
            EXPECT_CALL(api, DeviceGetFeatures(apiDevice, NotNull())).Times(1);

            api.CallAdapterRequestDeviceCallback(apiAdapter, WGPURequestDeviceStatus_Success,
                                                 apiDevice, kEmptyOutputStringView);
        }));
    FlushClient();
    FlushFutures();

    wgpu::Device device;
    // Expect the callback in the client.
    ExpectWireCallbacksWhen([&](auto& mockCb) {
        EXPECT_CALL(mockCb, Call(wgpu::RequestDeviceStatus::Success, NotNull(), EmptySizedString()))
            .WillOnce(WithArg<1>([&](wgpu::Device result) { device = std::move(result); }));
        FlushCallbacks();
    });

    device = nullptr;
    // Cleared when the device is destroyed.
    EXPECT_CALL(api, OnDeviceSetLoggingCallback(apiDevice, _)).Times(1);
    EXPECT_CALL(api, DeviceRelease(apiDevice));
    FlushClient();
}

// Test that RequestDevice receives unknown status if the wire is disconnected
// before the callback happens.
TEST_P(WireAdapterTests, RequestDeviceWireDisconnectedBeforeCallback) {
    wgpu::DeviceDescriptor desc = {};
    RequestDevice(&desc);

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

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

// Test that a device's wire handle (id and generation) matches between the client and server.
TEST_P(WireAdapterTests, RequestDeviceWireHandle) {
    RequestDevice(nullptr);

    // Expect the server to receive the message. Then, mock a fake reply.
    WGPUDevice apiDevice = api.GetNewDevice();
    EXPECT_CALL(api, OnAdapterRequestDevice(apiAdapter, NotNull(), _))
        .WillOnce(InvokeWithoutArgs([&] {
            // Set on device creation to forward callbacks to the client.
            EXPECT_CALL(api, OnDeviceSetLoggingCallback(apiDevice, _)).Times(1);
            EXPECT_CALL(api, DeviceGetLimits(apiDevice, NotNull())).Times(1);
            EXPECT_CALL(api, DeviceGetFeatures(apiDevice, NotNull())).Times(1);
            api.CallAdapterRequestDeviceCallback(apiAdapter, WGPURequestDeviceStatus_Success,
                                                 apiDevice, kEmptyOutputStringView);
        }));
    FlushClient();
    FlushFutures();

    wgpu::Device device;
    // Expect the callback in the client and the wire handles match.
    ExpectWireCallbacksWhen([&](auto& mockCb) {
        EXPECT_CALL(mockCb, Call(wgpu::RequestDeviceStatus::Success, NotNull(), EmptySizedString()))
            .WillOnce(WithArg<1>([&](wgpu::Device result) {
                device = std::move(result);

                Handle deviceWireHandle = GetWireClient()->GetWireHandle(device.Get());
                WGPUDevice apiDeviceExpected =
                    GetWireServer()->GetDevice(deviceWireHandle.id, deviceWireHandle.generation);
                EXPECT_EQ(apiDevice, apiDeviceExpected);
            }));
        FlushCallbacks();
    });

    device = nullptr;
    // Cleared when the device is destroyed.
    EXPECT_CALL(api, OnDeviceSetLoggingCallback(apiDevice, _)).Times(1);
    EXPECT_CALL(api, DeviceRelease(apiDevice));
    FlushClient();
}

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