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

#include "tests/MockCallback.h"
#include "tests/unittests/wire/WireTest.h"

#include "dawn_wire/WireClient.h"
#include "dawn_wire/WireServer.h"

#include <webgpu/webgpu_cpp.h>
#include <unordered_set>
#include <vector>

namespace {

    using namespace testing;
    using namespace dawn::wire;

    class WireInstanceBasicTest : public WireTest {};
    class WireInstanceTests : public WireTest {
      protected:
        void SetUp() override {
            WireTest::SetUp();

            auto reservation = GetWireClient()->ReserveInstance();
            instance = wgpu::Instance::Acquire(reservation.instance);

            apiInstance = api.GetNewInstance();
            EXPECT_CALL(api, InstanceReference(apiInstance));
            EXPECT_TRUE(GetWireServer()->InjectInstance(apiInstance, reservation.id,
                                                        reservation.generation));
        }

        void TearDown() override {
            instance = nullptr;
            WireTest::TearDown();
        }

        wgpu::Instance instance;
        WGPUInstance apiInstance;
    };

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

        WGPUInstance apiInstance = api.GetNewInstance();
        EXPECT_CALL(api, InstanceReference(apiInstance));
        EXPECT_TRUE(
            GetWireServer()->InjectInstance(apiInstance, reservation.id, reservation.generation));

        instance = nullptr;

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

    // Test that RequestAdapterOptions are passed from the client to the server.
    TEST_F(WireInstanceTests, RequestAdapterPassesOptions) {
        MockCallback<WGPURequestAdapterCallback> cb;
        auto* userdata = cb.MakeUserdata(this);

        for (wgpu::PowerPreference powerPreference :
             {wgpu::PowerPreference::LowPower, wgpu::PowerPreference::HighPerformance}) {
            wgpu::RequestAdapterOptions options = {};
            options.powerPreference = powerPreference;

            instance.RequestAdapter(&options, cb.Callback(), userdata);

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

        // Delete the instance now, or it'll call the mock callback after it's deleted.
        instance = nullptr;
    }

    // Test that RequestAdapter forwards the adapter information to the client.
    TEST_F(WireInstanceTests, RequestAdapterSuccess) {
        wgpu::RequestAdapterOptions options = {};
        MockCallback<WGPURequestAdapterCallback> cb;
        auto* userdata = cb.MakeUserdata(this);
        instance.RequestAdapter(&options, cb.Callback(), userdata);

        wgpu::AdapterProperties fakeProperties = {};
        fakeProperties.vendorID = 0x134;
        fakeProperties.deviceID = 0x918;
        fakeProperties.name = "fake adapter";
        fakeProperties.driverDescription = "hello world";
        fakeProperties.backendType = wgpu::BackendType::D3D12;
        fakeProperties.adapterType = wgpu::AdapterType::IntegratedGPU;

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

        std::initializer_list<wgpu::FeatureName> fakeFeatures = {
            wgpu::FeatureName::Depth32FloatStencil8,
            wgpu::FeatureName::TextureCompressionBC,
        };

        // Expect the server to receive the message. Then, mock a fake reply.
        WGPUAdapter apiAdapter = api.GetNewAdapter();
        EXPECT_CALL(api, OnInstanceRequestAdapter(apiInstance, NotNull(), NotNull(), NotNull()))
            .WillOnce(InvokeWithoutArgs([&]() {
                EXPECT_CALL(api, AdapterGetProperties(apiAdapter, NotNull()))
                    .WillOnce(SetArgPointee<1>(
                        *reinterpret_cast<WGPUAdapterProperties*>(&fakeProperties)));

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

                EXPECT_CALL(api, AdapterEnumerateFeatures(apiAdapter, nullptr))
                    .WillOnce(Return(fakeFeatures.size()));

                EXPECT_CALL(api, AdapterEnumerateFeatures(apiAdapter, NotNull()))
                    .WillOnce(WithArg<1>(Invoke([&](WGPUFeatureName* features) {
                        for (wgpu::FeatureName feature : fakeFeatures) {
                            *(features++) = static_cast<WGPUFeatureName>(feature);
                        }
                        return fakeFeatures.size();
                    })));
                api.CallInstanceRequestAdapterCallback(
                    apiInstance, WGPURequestAdapterStatus_Success, apiAdapter, nullptr);
            }));
        FlushClient();

        // Expect the callback in the client and all the adapter information to match.
        EXPECT_CALL(cb, Call(WGPURequestAdapterStatus_Success, NotNull(), nullptr, this))
            .WillOnce(WithArg<1>(Invoke([&](WGPUAdapter cAdapter) {
                wgpu::Adapter adapter = wgpu::Adapter::Acquire(cAdapter);

                wgpu::AdapterProperties properties;
                adapter.GetProperties(&properties);
                EXPECT_EQ(properties.vendorID, fakeProperties.vendorID);
                EXPECT_EQ(properties.deviceID, fakeProperties.deviceID);
                EXPECT_STREQ(properties.name, fakeProperties.name);
                EXPECT_STREQ(properties.driverDescription, fakeProperties.driverDescription);
                EXPECT_EQ(properties.backendType, fakeProperties.backendType);
                EXPECT_EQ(properties.adapterType, fakeProperties.adapterType);

                wgpu::SupportedLimits limits;
                EXPECT_TRUE(adapter.GetLimits(&limits));
                EXPECT_EQ(limits.limits.maxTextureDimension1D,
                          fakeLimits.limits.maxTextureDimension1D);
                EXPECT_EQ(limits.limits.maxVertexAttributes, fakeLimits.limits.maxVertexAttributes);

                std::vector<wgpu::FeatureName> features;
                features.resize(adapter.EnumerateFeatures(nullptr));
                ASSERT_EQ(features.size(), fakeFeatures.size());
                EXPECT_EQ(adapter.EnumerateFeatures(&features[0]), features.size());

                std::unordered_set<wgpu::FeatureName> featureSet(fakeFeatures);
                for (wgpu::FeatureName feature : features) {
                    EXPECT_EQ(featureSet.erase(feature), 1u);
                }
            })));
        FlushServer();
    }

    // Test that features returned by the implementation that aren't supported
    // in the wire are not exposed.
    TEST_F(WireInstanceTests, RequestAdapterWireLacksFeatureSupport) {
        wgpu::RequestAdapterOptions options = {};
        MockCallback<WGPURequestAdapterCallback> cb;
        auto* userdata = cb.MakeUserdata(this);
        instance.RequestAdapter(&options, cb.Callback(), userdata);

        std::initializer_list<wgpu::FeatureName> fakeFeatures = {
            wgpu::FeatureName::Depth24UnormStencil8,
            // Some value that is not a valid feature
            static_cast<wgpu::FeatureName>(-2),
        };

        // Expect the server to receive the message. Then, mock a fake reply.
        WGPUAdapter apiAdapter = api.GetNewAdapter();
        EXPECT_CALL(api, OnInstanceRequestAdapter(apiInstance, NotNull(), NotNull(), NotNull()))
            .WillOnce(InvokeWithoutArgs([&]() {
                EXPECT_CALL(api, AdapterGetProperties(apiAdapter, NotNull()))
                    .WillOnce(WithArg<1>(Invoke([&](WGPUAdapterProperties* properties) {
                        *properties = {};
                        properties->name = "";
                        properties->driverDescription = "";
                    })));

                EXPECT_CALL(api, AdapterGetLimits(apiAdapter, NotNull()))
                    .WillOnce(WithArg<1>(Invoke([&](WGPUSupportedLimits* limits) {
                        *limits = {};
                        return true;
                    })));

                EXPECT_CALL(api, AdapterEnumerateFeatures(apiAdapter, nullptr))
                    .WillOnce(Return(fakeFeatures.size()));

                EXPECT_CALL(api, AdapterEnumerateFeatures(apiAdapter, NotNull()))
                    .WillOnce(WithArg<1>(Invoke([&](WGPUFeatureName* features) {
                        for (wgpu::FeatureName feature : fakeFeatures) {
                            *(features++) = static_cast<WGPUFeatureName>(feature);
                        }
                        return fakeFeatures.size();
                    })));
                api.CallInstanceRequestAdapterCallback(
                    apiInstance, WGPURequestAdapterStatus_Success, apiAdapter, nullptr);
            }));
        FlushClient();

        // Expect the callback in the client and all the adapter information to match.
        EXPECT_CALL(cb, Call(WGPURequestAdapterStatus_Success, NotNull(), nullptr, this))
            .WillOnce(WithArg<1>(Invoke([&](WGPUAdapter cAdapter) {
                wgpu::Adapter adapter = wgpu::Adapter::Acquire(cAdapter);

                wgpu::FeatureName feature;
                ASSERT_EQ(adapter.EnumerateFeatures(nullptr), 1u);
                adapter.EnumerateFeatures(&feature);

                EXPECT_EQ(feature, wgpu::FeatureName::Depth24UnormStencil8);
            })));
        FlushServer();
    }

    // Test that RequestAdapter errors forward to the client.
    TEST_F(WireInstanceTests, RequestAdapterError) {
        wgpu::RequestAdapterOptions options = {};
        MockCallback<WGPURequestAdapterCallback> cb;
        auto* userdata = cb.MakeUserdata(this);
        instance.RequestAdapter(&options, cb.Callback(), userdata);

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

        // Expect the callback in the client.
        EXPECT_CALL(cb, Call(WGPURequestAdapterStatus_Error, nullptr, StrEq("Some error"), this))
            .Times(1);
        FlushServer();
    }

    // Test that RequestAdapter receives unknown status if the instance is deleted
    // before the callback happens.
    TEST_F(WireInstanceTests, RequestAdapterInstanceDestroyedBeforeCallback) {
        wgpu::RequestAdapterOptions options = {};
        MockCallback<WGPURequestAdapterCallback> cb;
        auto* userdata = cb.MakeUserdata(this);
        instance.RequestAdapter(&options, cb.Callback(), userdata);

        EXPECT_CALL(cb, Call(WGPURequestAdapterStatus_Unknown, nullptr, NotNull(), this)).Times(1);
        instance = nullptr;
    }

    // Test that RequestAdapter receives unknown status if the wire is disconnected
    // before the callback happens.
    TEST_F(WireInstanceTests, RequestAdapterWireDisconnectBeforeCallback) {
        wgpu::RequestAdapterOptions options = {};
        MockCallback<WGPURequestAdapterCallback> cb;
        auto* userdata = cb.MakeUserdata(this);
        instance.RequestAdapter(&options, cb.Callback(), userdata);

        EXPECT_CALL(cb, Call(WGPURequestAdapterStatus_Unknown, nullptr, NotNull(), this)).Times(1);
        GetWireClient()->Disconnect();
    }

}  // anonymous namespace