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

#include "dawn/dawn_proc.h"
#include "dawn/native/Adapter.h"
#include "dawn/native/DawnNative.h"
#include "dawn/native/Device.h"
#include "dawn/native/Toggles.h"
#include "dawn/native/dawn_platform.h"
#include "dawn/tests/MockCallback.h"
#include "dawn/tests/StringViewMatchers.h"
#include "dawn/utils/SystemUtils.h"
#include "dawn/utils/WGPUHelpers.h"
#include "gtest/gtest.h"

namespace dawn::native {
namespace {

using testing::_;
using testing::Contains;
using testing::EmptySizedString;
using testing::IsNull;
using testing::MockCppCallback;
using testing::NonEmptySizedString;
using testing::StrEq;
using testing::WithArg;

class DeviceCreationTest : public testing::Test {
  protected:
    void SetUp() override {
        dawnProcSetProcs(&GetProcs());

        static constexpr auto kMultipleDevicesPerAdapter =
            wgpu::InstanceFeatureName::MultipleDevicesPerAdapter;
        // Create an instance with default toggles and create an adapter from it.
        wgpu::InstanceDescriptor safeInstanceDesc = {
            .requiredFeatureCount = 1,
            .requiredFeatures = &kMultipleDevicesPerAdapter,
        };
        instance = std::make_unique<Instance>(&safeInstanceDesc);

        wgpu::RequestAdapterOptions options = {};
        options.backendType = wgpu::BackendType::Null;

        // Get the null adapter with default toggles.
        adapter = instance->EnumerateAdapters(&options)[0];

        // Create an instance with toggle AllowUnsafeAPIs enabled, and create an unsafe adapter
        // from it.
        const char* allowUnsafeApisToggle = "allow_unsafe_apis";
        wgpu::DawnTogglesDescriptor unsafeInstanceTogglesDesc = {};
        unsafeInstanceTogglesDesc.enabledToggleCount = 1;
        unsafeInstanceTogglesDesc.enabledToggles = &allowUnsafeApisToggle;
        wgpu::InstanceDescriptor unsafeInstanceDesc = {
            .requiredFeatureCount = 1,
            .requiredFeatures = &kMultipleDevicesPerAdapter,
        };
        unsafeInstanceDesc.nextInChain = &unsafeInstanceTogglesDesc;

        unsafeInstance = std::make_unique<Instance>(&unsafeInstanceDesc);
        unsafeAdapter = unsafeInstance->EnumerateAdapters(&options)[0];

        ASSERT_NE(adapter.Get(), nullptr);
        ASSERT_NE(unsafeAdapter.Get(), nullptr);
    }

    void TearDown() override {
        adapter = nullptr;
        unsafeAdapter = nullptr;
        instance = nullptr;
        unsafeInstance = nullptr;
        dawnProcSetProcs(nullptr);
    }

    static constexpr size_t kTotalFeaturesCount = static_cast<size_t>(kEnumCount<Feature>);

    std::unique_ptr<Instance> instance;
    std::unique_ptr<Instance> unsafeInstance;
    Adapter adapter;
    Adapter unsafeAdapter;
};

// Test successful call to CreateDevice with no descriptor
TEST_F(DeviceCreationTest, CreateDeviceNoDescriptorSuccess) {
    wgpu::Device device = adapter.CreateDevice();
    EXPECT_NE(device, nullptr);
}

// Test successful call to CreateDevice with descriptor.
TEST_F(DeviceCreationTest, CreateDeviceSuccess) {
    wgpu::DeviceDescriptor desc = {};
    wgpu::Device device = adapter.CreateDevice(&desc);
    EXPECT_NE(device, nullptr);
}

// Test successful call to CreateDevice with allocator descriptor.
TEST_F(DeviceCreationTest, CreateDeviceWithAllocatorSuccess) {
    wgpu::DawnDeviceAllocatorControl allocationDesc = {};
    allocationDesc.allocatorHeapBlockSize = 4 * 1024;

    wgpu::DeviceDescriptor desc = {};
    wgpu::FeatureName feature = wgpu::FeatureName::DawnDeviceAllocatorControl;
    desc.requiredFeatures = &feature;
    desc.requiredFeatureCount = 1;
    desc.nextInChain = &allocationDesc;

    wgpu::Device device = unsafeAdapter.CreateDevice(&desc);
    EXPECT_NE(device, nullptr);
}

// Test failed call to CreateDevice with allocator descriptor. This is using an adapter that does
// not have DawnDeviceAllocatorControl feature enabled.
TEST_F(DeviceCreationTest, CreateDeviceWithAllocatorFailedMissingFeature) {
    wgpu::DawnDeviceAllocatorControl allocationDesc = {};
    allocationDesc.allocatorHeapBlockSize = 4 * 1024;

    wgpu::DeviceDescriptor desc = {};
    desc.nextInChain = &allocationDesc;

    wgpu::Device device = adapter.CreateDevice(&desc);
    EXPECT_EQ(device, nullptr);
}

// Test failed call to CreateDevice with allocator descriptor. The heap block size provided is not a
// power of two.
TEST_F(DeviceCreationTest, CreateDeviceWithAllocatorFailedHeapBlockSize) {
    wgpu::DawnDeviceAllocatorControl allocationDesc = {};
    allocationDesc.allocatorHeapBlockSize = 4 * 1024 + 1;

    wgpu::DeviceDescriptor desc = {};
    wgpu::FeatureName feature = wgpu::FeatureName::DawnDeviceAllocatorControl;
    desc.requiredFeatures = &feature;
    desc.requiredFeatureCount = 1;
    desc.nextInChain = &allocationDesc;

    wgpu::Device device = unsafeAdapter.CreateDevice(&desc);
    EXPECT_EQ(device, nullptr);
}

// Test successful call to CreateDevice with toggle descriptor.
TEST_F(DeviceCreationTest, CreateDeviceWithTogglesSuccess) {
    wgpu::DeviceDescriptor desc = {};
    wgpu::DawnTogglesDescriptor deviceTogglesDesc = {};
    desc.nextInChain = &deviceTogglesDesc;

    const char* toggle = "skip_validation";
    deviceTogglesDesc.enabledToggles = &toggle;
    deviceTogglesDesc.enabledToggleCount = 1;

    wgpu::Device device = adapter.CreateDevice(&desc);
    EXPECT_NE(device, nullptr);

    auto toggles = GetTogglesUsed(device.Get());
    EXPECT_THAT(toggles, Contains(StrEq(toggle)));
}

// Test experimental features are guarded by DisallowUnsafeApis adapter toggle, it is inherited from
// instance but can be overriden by device toggles.
TEST_F(DeviceCreationTest, CreateDeviceRequiringExperimentalFeatures) {
    // Ensure that unsafe apis are disallowed on safe adapter.
    ASSERT_FALSE(FromAPI(adapter.Get())->GetTogglesState().IsEnabled(Toggle::AllowUnsafeAPIs));
    // Ensure that unsafe apis are allowed unsafe adapter(s).
    ASSERT_TRUE(FromAPI(unsafeAdapter.Get())->GetTogglesState().IsEnabled(Toggle::AllowUnsafeAPIs));

    for (size_t i = 0; i < kTotalFeaturesCount; i++) {
        Feature feature = static_cast<Feature>(i);
        wgpu::FeatureName featureName = ToAPI(feature);

        // Only test experimental features.
        if (kFeatureNameAndInfoList[feature].featureState == FeatureInfo::FeatureState::Stable) {
            continue;
        }

        // wgpu::FeatureName::CoreFeaturesAndLimits is required implicitly in core mode
        static constexpr uint32_t kDefaultExpectedFeatureCount = 1u;

        wgpu::DeviceDescriptor deviceDescriptor;
        deviceDescriptor.requiredFeatures = &featureName;
        deviceDescriptor.requiredFeatureCount = 1;

        // Test creating device on default adapter would fail.
        {
            wgpu::Device device = adapter.CreateDevice(&deviceDescriptor);
            EXPECT_EQ(device, nullptr);
        }

        // Test creating device on the adapter with AllowUnsafeApis toggle enabled would succeed.
        {
            deviceDescriptor.nextInChain = nullptr;

            wgpu::Device device = unsafeAdapter.CreateDevice(&deviceDescriptor);
            EXPECT_NE(device, nullptr);

            wgpu::SupportedFeatures supportedFeatures;
            device.GetFeatures(&supportedFeatures);
            uint32_t expectedFeatureCount = kDefaultExpectedFeatureCount +
                                            utils::FeatureAndImplicitlyEnabled(featureName).size();

            ASSERT_EQ(expectedFeatureCount, supportedFeatures.featureCount);

            bool foundFeatureName = false;
            for (uint32_t fi = 0; fi < supportedFeatures.featureCount; ++fi) {
                if (featureName == supportedFeatures.features[fi]) {
                    foundFeatureName = true;
                    break;
                }
            }
            EXPECT_TRUE(foundFeatureName);
        }

        // Test creating device with AllowUnsafeApis enabled in device toggle descriptor will
        // success on both adapter, as device toggles will override the inherited adapter toggles.
        {
            const char* const enableToggles[] = {"allow_unsafe_apis"};
            wgpu::DawnTogglesDescriptor deviceTogglesDesc;
            deviceTogglesDesc.enabledToggles = enableToggles;
            deviceTogglesDesc.enabledToggleCount = 1;
            deviceDescriptor.nextInChain = &deviceTogglesDesc;

            // Test on adapter with AllowUnsafeApis disabled.
            {
                wgpu::Device device = adapter.CreateDevice(&deviceDescriptor);
                EXPECT_NE(device, nullptr);

                wgpu::SupportedFeatures supportedFeatures;
                device.GetFeatures(&supportedFeatures);
                uint32_t expectedFeatureCount =
                    kDefaultExpectedFeatureCount +
                    utils::FeatureAndImplicitlyEnabled(featureName).size();

                ASSERT_EQ(expectedFeatureCount, supportedFeatures.featureCount);

                bool foundFeatureName = false;
                for (uint32_t fi = 0; fi < supportedFeatures.featureCount; ++fi) {
                    if (featureName == supportedFeatures.features[fi]) {
                        foundFeatureName = true;
                        break;
                    }
                }
                EXPECT_TRUE(foundFeatureName);
            }

            // Test on adapter with AllowUnsafeApis disabled.
            {
                wgpu::Device device = unsafeAdapter.CreateDevice(&deviceDescriptor);
                EXPECT_NE(device, nullptr);

                wgpu::SupportedFeatures supportedFeatures;
                device.GetFeatures(&supportedFeatures);
                uint32_t expectedFeatureCount =
                    kDefaultExpectedFeatureCount +
                    utils::FeatureAndImplicitlyEnabled(featureName).size();

                ASSERT_EQ(expectedFeatureCount, supportedFeatures.featureCount);

                bool foundFeatureName = false;
                for (uint32_t fi = 0; fi < supportedFeatures.featureCount; ++fi) {
                    if (featureName == supportedFeatures.features[fi]) {
                        foundFeatureName = true;
                        break;
                    }
                }
                EXPECT_TRUE(foundFeatureName);
            }
        }

        // Test creating device with AllowUnsafeApis disabled in device toggle descriptor will fail
        // on both adapter, as device toggles will override the inherited adapter toggles.
        {
            const char* const disableToggles[] = {"allow_unsafe_apis"};
            wgpu::DawnTogglesDescriptor deviceToggleDesc;
            deviceToggleDesc.disabledToggles = disableToggles;
            deviceToggleDesc.disabledToggleCount = 1;
            deviceDescriptor.nextInChain = &deviceToggleDesc;

            // Test on adapter with DisallowUnsafeApis enabled.
            {
                wgpu::Device device = adapter.CreateDevice(&deviceDescriptor);
                EXPECT_EQ(device, nullptr);
            }

            // Test on adapter with DisallowUnsafeApis disabled.
            {
                wgpu::Device device = unsafeAdapter.CreateDevice(&deviceDescriptor);
                EXPECT_EQ(device, nullptr);
            }
        }
    }
}

TEST_F(DeviceCreationTest, CreateDeviceWithCacheSuccess) {
    // Default device descriptor should have the same cache key as a device descriptor with a
    // default cache descriptor.
    {
        wgpu::DeviceDescriptor desc = {};
        wgpu::Device device1 = adapter.CreateDevice(&desc);
        EXPECT_NE(device1, nullptr);

        wgpu::DawnCacheDeviceDescriptor cacheDesc = {};
        desc.nextInChain = &cacheDesc;
        wgpu::Device device2 = adapter.CreateDevice(&desc);

        EXPECT_EQ(FromAPI(device1.Get())->GetCacheKey(), FromAPI(device2.Get())->GetCacheKey());
    }
    // Default device descriptor should not have the same cache key as a device descriptor with
    // a non-default cache descriptor.
    {
        wgpu::DeviceDescriptor desc = {};
        wgpu::Device device1 = adapter.CreateDevice(&desc);
        EXPECT_NE(device1, nullptr);

        wgpu::DawnCacheDeviceDescriptor cacheDesc = {};
        desc.nextInChain = &cacheDesc;
        const char* isolationKey = "isolation key";
        cacheDesc.isolationKey = isolationKey;
        wgpu::Device device2 = adapter.CreateDevice(&desc);
        EXPECT_NE(device2, nullptr);

        EXPECT_NE(FromAPI(device1.Get())->GetCacheKey(), FromAPI(device2.Get())->GetCacheKey());
    }
    // Two non-default cache descriptors should not have the same cache key.
    {
        wgpu::DawnCacheDeviceDescriptor cacheDesc = {};
        const char* isolationKey1 = "isolation key 1";
        const char* isolationKey2 = "isolation key 2";
        wgpu::DeviceDescriptor desc = {};
        desc.nextInChain = &cacheDesc;

        cacheDesc.isolationKey = isolationKey1;
        wgpu::Device device1 = adapter.CreateDevice(&desc);
        EXPECT_NE(device1, nullptr);

        cacheDesc.isolationKey = isolationKey2;
        wgpu::Device device2 = adapter.CreateDevice(&desc);
        EXPECT_NE(device2, nullptr);

        EXPECT_NE(FromAPI(device1.Get())->GetCacheKey(), FromAPI(device2.Get())->GetCacheKey());
    }
}

// Test failed call to CreateDevice when adapter has been consumed because instance has not the
// MultipleDevicesPerAdapter feature.
TEST_F(DeviceCreationTest, AdapterIsConsumedWithoutMultipleDevicesPerAdapterFeature) {
    auto instance = std::make_unique<Instance>();

    wgpu::RequestAdapterOptions options = {};
    options.backendType = wgpu::BackendType::Null;

    auto adapter = instance->EnumerateAdapters(&options)[0];

    wgpu::Device device1 = adapter.CreateDevice();
    EXPECT_NE(device1, nullptr);

    wgpu::Device device2 = adapter.CreateDevice();
    EXPECT_EQ(device2, nullptr);
}

// Test failed call to CreateDevice when adapter has been explicitly asked to be consumed.
TEST_F(DeviceCreationTest, AdapterIsConsumedWithConsumeAdapterDescriptor) {
    wgpu::DawnConsumeAdapterDescriptor consumeAdapterDesc = {};
    consumeAdapterDesc.consumeAdapter = true;
    wgpu::DeviceDescriptor desc = {};
    desc.nextInChain = &consumeAdapterDesc;
    wgpu::Device device1 = adapter.CreateDevice(&desc);
    EXPECT_NE(device1, nullptr);

    desc.nextInChain = nullptr;
    wgpu::Device device2 = adapter.CreateDevice(&desc);
    EXPECT_EQ(device2, nullptr);
}

class DeviceCreationFutureTest : public DeviceCreationTest,
                                 public ::testing::WithParamInterface<wgpu::CallbackMode> {
  protected:
    void RequestDevice(const wgpu::DeviceDescriptor* descriptor) {
        wgpu::Adapter wgpuAdapter(adapter.Get());
        wgpu::Future future = wgpuAdapter.RequestDevice(descriptor, GetParam(), mMockCb.Callback());
        wgpu::Instance wgpuInstance(instance->Get());
        switch (GetParam()) {
            case wgpu::CallbackMode::WaitAnyOnly: {
                // Callback should complete as soon as poll once.
                EXPECT_EQ(wgpuInstance.WaitAny(future, 0), wgpu::WaitStatus::Success);
                break;
            }
            case wgpu::CallbackMode::AllowSpontaneous:
                // Callback should already be called.
                break;
            case wgpu::CallbackMode::AllowProcessEvents:
                wgpuInstance.ProcessEvents();
                break;
        }
    }

    MockCppCallback<wgpu::RequestDeviceCallback<void>*> mMockCb;
};

INSTANTIATE_TEST_SUITE_P(,
                         DeviceCreationFutureTest,
                         ::testing::ValuesIn(std::initializer_list<wgpu::CallbackMode>{
                             wgpu::CallbackMode::WaitAnyOnly,
                             wgpu::CallbackMode::AllowProcessEvents,
                             wgpu::CallbackMode::AllowSpontaneous}));

// Test successful call to RequestDevice with descriptor
TEST_P(DeviceCreationFutureTest, RequestDeviceSuccess) {
    wgpu::Device device;
    EXPECT_CALL(mMockCb, Call(wgpu::RequestDeviceStatus::Success, _, EmptySizedString()))
        .WillOnce(WithArg<1>([&](wgpu::Device result) { device = std::move(result); }));

    wgpu::DeviceDescriptor desc = {};
    RequestDevice(&desc);
    EXPECT_NE(device, nullptr);
}

// Test successful call to RequestDevice with a null descriptor
TEST_P(DeviceCreationFutureTest, RequestDeviceNullDescriptorSuccess) {
    wgpu::Device device;
    EXPECT_CALL(mMockCb, Call(wgpu::RequestDeviceStatus::Success, _, EmptySizedString()))
        .WillOnce(WithArg<1>([&](wgpu::Device result) { device = std::move(result); }));

    RequestDevice(nullptr);
    EXPECT_NE(device, nullptr);
}

// Test failing call to RequestDevice with invalid feature
TEST_P(DeviceCreationFutureTest, RequestDeviceFailure) {
    wgpu::Device device;
    EXPECT_CALL(mMockCb, Call(wgpu::RequestDeviceStatus::Error, IsNull(), NonEmptySizedString()))
        .WillOnce(WithArg<1>([&](wgpu::Device result) { device = std::move(result); }));

    wgpu::DeviceDescriptor desc = {};
    wgpu::FeatureName invalidFeature = static_cast<wgpu::FeatureName>(WGPUFeatureName_Force32);
    desc.requiredFeatures = &invalidFeature;
    desc.requiredFeatureCount = 1;
    RequestDevice(&desc);
}

}  // anonymous namespace
}  // namespace dawn::native
