// 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/DawnNative.h"
#include "gtest/gtest.h"
#include "src/dawn/native/Adapter.h"
#include "src/dawn/native/Device.h"
#include "src/dawn/native/Toggles.h"
#include "src/dawn/native/dawn_platform.h"
#include "src/dawn/tests/MockCallback.h"
#include "src/dawn/tests/StringViewMatchers.h"
#include "src/dawn/utils/SystemUtils.h"
#include "src/dawn/utils/WGPUHelpers.h"
#include "src/utils/compiler.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 == DAWN_UNSAFE_TODO(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 == DAWN_UNSAFE_TODO(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 == DAWN_UNSAFE_TODO(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
