// 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();
}

// DawnDeviceDescriptor

DawnDeviceDescriptor::DawnDeviceDescriptor() = default;

DawnDeviceDescriptor::~DawnDeviceDescriptor() = default;

// 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();
}

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);
}

uint64_t Instance::GetDeviceCountForTesting() const {
    return mImpl->GetDeviceCountForTesting();
}

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;
}

bool CheckIsErrorForTesting(void* objectHandle) {
    return reinterpret_cast<ErrorMonad*>(objectHandle)->IsError();
}

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
