// Copyright 2018 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 "dawn/native/DawnNative.h"

#include <vector>

#include "dawn/common/Log.h"
#include "dawn/native/BindGroupLayout.h"
#include "dawn/native/Buffer.h"
#include "dawn/native/Device.h"
#include "dawn/native/Instance.h"
#include "dawn/native/Texture.h"
#include "dawn/platform/DawnPlatform.h"

// Contains the entry-points into dawn_native

namespace dawn::native {

namespace {
struct ComboDeprecatedDawnDeviceDescriptor : DeviceDescriptor {
    explicit ComboDeprecatedDawnDeviceDescriptor(const DawnDeviceDescriptor* deviceDescriptor) {
        dawn::WarningLog() << "DawnDeviceDescriptor is deprecated. Please use "
                              "WGPUDeviceDescriptor instead.";

        DeviceDescriptor* desc = this;

        if (deviceDescriptor != nullptr) {
            desc->nextInChain = &mTogglesDesc;
            mTogglesDesc.forceEnabledToggles = deviceDescriptor->forceEnabledToggles.data();
            mTogglesDesc.forceEnabledTogglesCount = deviceDescriptor->forceEnabledToggles.size();
            mTogglesDesc.forceDisabledToggles = deviceDescriptor->forceDisabledToggles.data();
            mTogglesDesc.forceDisabledTogglesCount = deviceDescriptor->forceDisabledToggles.size();

            desc->requiredLimits =
                reinterpret_cast<const RequiredLimits*>(deviceDescriptor->requiredLimits);

            FeaturesInfo featuresInfo;
            for (const char* featureStr : deviceDescriptor->requiredFeatures) {
                mRequiredFeatures.push_back(featuresInfo.FeatureNameToAPIEnum(featureStr));
            }
            desc->requiredFeatures = mRequiredFeatures.data();
            desc->requiredFeaturesCount = mRequiredFeatures.size();
        }
    }

    DawnTogglesDeviceDescriptor mTogglesDesc = {};
    std::vector<wgpu::FeatureName> mRequiredFeatures = {};
};
}  // namespace

const DawnProcTable& GetProcsAutogen();

const DawnProcTable& GetProcs() {
    return GetProcsAutogen();
}

std::vector<const char*> GetTogglesUsed(WGPUDevice device) {
    return FromAPI(device)->GetTogglesUsed();
}

// Adapter

Adapter::Adapter() = default;

Adapter::Adapter(AdapterBase* impl) : mImpl(impl) {
    if (mImpl != nullptr) {
        mImpl->Reference();
    }
}

Adapter::~Adapter() {
    if (mImpl != nullptr) {
        mImpl->Release();
    }
    mImpl = nullptr;
}

Adapter::Adapter(const Adapter& other) : Adapter(other.mImpl) {}

Adapter& Adapter::operator=(const Adapter& other) {
    if (this != &other) {
        if (mImpl) {
            mImpl->Release();
        }
        mImpl = other.mImpl;
        if (mImpl) {
            mImpl->Reference();
        }
    }
    return *this;
}

void Adapter::GetProperties(wgpu::AdapterProperties* properties) const {
    GetProperties(reinterpret_cast<WGPUAdapterProperties*>(properties));
}

void Adapter::GetProperties(WGPUAdapterProperties* properties) const {
    mImpl->APIGetProperties(FromAPI(properties));
}

WGPUAdapter Adapter::Get() const {
    return ToAPI(mImpl);
}

std::vector<const char*> Adapter::GetSupportedFeatures() const {
    FeaturesSet supportedFeaturesSet = mImpl->GetSupportedFeatures();
    return supportedFeaturesSet.GetEnabledFeatureNames();
}

WGPUDeviceProperties Adapter::GetAdapterProperties() const {
    return mImpl->GetAdapterProperties();
}

bool Adapter::GetLimits(WGPUSupportedLimits* limits) const {
    return mImpl->GetLimits(FromAPI(limits));
}

void Adapter::SetUseTieredLimits(bool useTieredLimits) {
    mImpl->SetUseTieredLimits(useTieredLimits);
}

bool Adapter::SupportsExternalImages() const {
    return mImpl->SupportsExternalImages();
}

Adapter::operator bool() const {
    return mImpl != nullptr;
}

WGPUDevice Adapter::CreateDevice(const DawnDeviceDescriptor* deviceDescriptor) {
    ComboDeprecatedDawnDeviceDescriptor desc(deviceDescriptor);
    return ToAPI(mImpl->APICreateDevice(&desc));
}

WGPUDevice Adapter::CreateDevice(const wgpu::DeviceDescriptor* deviceDescriptor) {
    return CreateDevice(reinterpret_cast<const WGPUDeviceDescriptor*>(deviceDescriptor));
}

WGPUDevice Adapter::CreateDevice(const WGPUDeviceDescriptor* deviceDescriptor) {
    return ToAPI(mImpl->APICreateDevice(FromAPI(deviceDescriptor)));
}

void Adapter::RequestDevice(const DawnDeviceDescriptor* descriptor,
                            WGPURequestDeviceCallback callback,
                            void* userdata) {
    ComboDeprecatedDawnDeviceDescriptor desc(descriptor);
    mImpl->APIRequestDevice(&desc, callback, userdata);
}

void Adapter::RequestDevice(const wgpu::DeviceDescriptor* descriptor,
                            WGPURequestDeviceCallback callback,
                            void* userdata) {
    mImpl->APIRequestDevice(reinterpret_cast<const DeviceDescriptor*>(descriptor), callback,
                            userdata);
}

void Adapter::RequestDevice(const WGPUDeviceDescriptor* descriptor,
                            WGPURequestDeviceCallback callback,
                            void* userdata) {
    mImpl->APIRequestDevice(reinterpret_cast<const DeviceDescriptor*>(descriptor), callback,
                            userdata);
}

void Adapter::ResetInternalDeviceForTesting() {
    mImpl->ResetInternalDeviceForTesting();
}

// AdapterDiscoverOptionsBase

AdapterDiscoveryOptionsBase::AdapterDiscoveryOptionsBase(WGPUBackendType type)
    : backendType(type) {}

// Instance

Instance::Instance(const WGPUInstanceDescriptor* desc)
    : mImpl(APICreateInstance(reinterpret_cast<const InstanceDescriptor*>(desc))) {}

Instance::~Instance() {
    if (mImpl != nullptr) {
        mImpl->Release();
        mImpl = nullptr;
    }
}

void Instance::DiscoverDefaultAdapters() {
    mImpl->DiscoverDefaultAdapters();
}

bool Instance::DiscoverAdapters(const AdapterDiscoveryOptionsBase* options) {
    return mImpl->DiscoverAdapters(options);
}

std::vector<Adapter> Instance::GetAdapters() const {
    // Adapters are owned by mImpl so it is safe to return non RAII pointers to them
    std::vector<Adapter> adapters;
    for (const Ref<AdapterBase>& adapter : mImpl->GetAdapters()) {
        adapters.push_back(Adapter(adapter.Get()));
    }
    return adapters;
}

const ToggleInfo* Instance::GetToggleInfo(const char* toggleName) {
    return mImpl->GetToggleInfo(toggleName);
}

const FeatureInfo* Instance::GetFeatureInfo(WGPUFeatureName feature) {
    return mImpl->GetFeatureInfo(static_cast<wgpu::FeatureName>(feature));
}

void Instance::EnableBackendValidation(bool enableBackendValidation) {
    if (enableBackendValidation) {
        mImpl->SetBackendValidationLevel(BackendValidationLevel::Full);
    }
}

void Instance::SetBackendValidationLevel(BackendValidationLevel level) {
    mImpl->SetBackendValidationLevel(level);
}

void Instance::EnableBeginCaptureOnStartup(bool beginCaptureOnStartup) {
    mImpl->EnableBeginCaptureOnStartup(beginCaptureOnStartup);
}

// TODO(dawn:1374) Deprecate this once it is passed via the descriptor.
void Instance::SetPlatform(dawn::platform::Platform* platform) {
    mImpl->SetPlatform(platform);
}

WGPUInstance Instance::Get() const {
    return ToAPI(mImpl);
}

size_t GetLazyClearCountForTesting(WGPUDevice device) {
    return FromAPI(device)->GetLazyClearCountForTesting();
}

size_t GetDeprecationWarningCountForTesting(WGPUDevice device) {
    return FromAPI(device)->GetDeprecationWarningCountForTesting();
}

bool IsTextureSubresourceInitialized(WGPUTexture texture,
                                     uint32_t baseMipLevel,
                                     uint32_t levelCount,
                                     uint32_t baseArrayLayer,
                                     uint32_t layerCount,
                                     WGPUTextureAspect cAspect) {
    TextureBase* textureBase = FromAPI(texture);

    Aspect aspect =
        ConvertAspect(textureBase->GetFormat(), static_cast<wgpu::TextureAspect>(cAspect));
    SubresourceRange range(aspect, {baseArrayLayer, layerCount}, {baseMipLevel, levelCount});
    return textureBase->IsSubresourceContentInitialized(range);
}

std::vector<const char*> GetProcMapNamesForTestingInternal();

std::vector<const char*> GetProcMapNamesForTesting() {
    return GetProcMapNamesForTestingInternal();
}

DAWN_NATIVE_EXPORT bool DeviceTick(WGPUDevice device) {
    return FromAPI(device)->APITick();
}

// ExternalImageDescriptor

ExternalImageDescriptor::ExternalImageDescriptor(ExternalImageType type) : mType(type) {}

ExternalImageType ExternalImageDescriptor::GetType() const {
    return mType;
}

// ExternalImageExportInfo

ExternalImageExportInfo::ExternalImageExportInfo(ExternalImageType type) : mType(type) {}

ExternalImageType ExternalImageExportInfo::GetType() const {
    return mType;
}

const char* GetObjectLabelForTesting(void* objectHandle) {
    ApiObjectBase* object = reinterpret_cast<ApiObjectBase*>(objectHandle);
    return object->GetLabel().c_str();
}

uint64_t GetAllocatedSizeForTesting(WGPUBuffer buffer) {
    return FromAPI(buffer)->GetAllocatedSize();
}

bool BindGroupLayoutBindingsEqualForTesting(WGPUBindGroupLayout a, WGPUBindGroupLayout b) {
    bool excludePipelineCompatibiltyToken = true;
    return FromAPI(a)->IsLayoutEqual(FromAPI(b), excludePipelineCompatibiltyToken);
}

}  // namespace dawn::native
