// 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 that maxImmediateSize is available iff the adapter has AllowUnsafeAPIs.
TEST_F(DeviceCreationTest, AdapterMaxImmediateSize) {
    wgpu::Limits requiredLimits{.maxImmediateSize = 1};
    wgpu::DeviceDescriptor deviceDesc;
    deviceDesc.requiredLimits = &requiredLimits;

    {
        wgpu::Adapter wgpuAdapter{adapter.Get()};
        wgpu::Limits limits;
        wgpuAdapter.GetLimits(&limits);
        EXPECT_EQ(limits.maxImmediateSize, 0u);

        wgpuAdapter.RequestDevice(
            &deviceDesc, wgpu::CallbackMode::AllowSpontaneous,
            [](wgpu::RequestDeviceStatus status, wgpu::Device device, wgpu::StringView message) {
                EXPECT_EQ(status, wgpu::RequestDeviceStatus::Error);
                EXPECT_EQ(device.Get(), nullptr);
            });
    }

    // The null backend always supports immediates.
    {
        wgpu::Adapter wgpuAdapter{unsafeAdapter.Get()};
        wgpu::Limits limits;
        wgpuAdapter.GetLimits(&limits);
        EXPECT_GT(limits.maxImmediateSize, 0u);
        wgpuAdapter.RequestDevice(
            &deviceDesc, wgpu::CallbackMode::AllowSpontaneous,
            [](wgpu::RequestDeviceStatus status, wgpu::Device device, wgpu::StringView message) {
                EXPECT_EQ(status, wgpu::RequestDeviceStatus::Success);
                EXPECT_NE(device.Get(), nullptr);
            });
    }
}

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