// 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/Instance.h"

#include <utility>

#include "dawn/common/Assert.h"
#include "dawn/common/GPUInfo.h"
#include "dawn/common/Log.h"
#include "dawn/common/SystemUtils.h"
#include "dawn/native/ChainUtils_autogen.h"
#include "dawn/native/ErrorData.h"
#include "dawn/native/Surface.h"
#include "dawn/native/ValidationUtils_autogen.h"
#include "dawn/platform/DawnPlatform.h"

// For SwiftShader fallback
#if defined(DAWN_ENABLE_BACKEND_VULKAN)
#include "dawn/native/VulkanBackend.h"
#endif  // defined(DAWN_ENABLE_BACKEND_VULKAN)

#if defined(DAWN_USE_X11)
#include "dawn/native/XlibXcbFunctions.h"
#endif  // defined(DAWN_USE_X11)

#include <optional>

namespace dawn::native {

// Forward definitions of each backend's "Connect" function that creates new BackendConnection.
// Conditionally compiled declarations are used to avoid using static constructors instead.
#if defined(DAWN_ENABLE_BACKEND_D3D12)
namespace d3d12 {
BackendConnection* Connect(InstanceBase* instance);
}
#endif  // defined(DAWN_ENABLE_BACKEND_D3D12)
#if defined(DAWN_ENABLE_BACKEND_METAL)
namespace metal {
BackendConnection* Connect(InstanceBase* instance);
}
#endif  // defined(DAWN_ENABLE_BACKEND_METAL)
#if defined(DAWN_ENABLE_BACKEND_NULL)
namespace null {
BackendConnection* Connect(InstanceBase* instance);
}
#endif  // defined(DAWN_ENABLE_BACKEND_NULL)
#if defined(DAWN_ENABLE_BACKEND_OPENGL)
namespace opengl {
BackendConnection* Connect(InstanceBase* instance, wgpu::BackendType backendType);
}
#endif  // defined(DAWN_ENABLE_BACKEND_OPENGL)
#if defined(DAWN_ENABLE_BACKEND_VULKAN)
namespace vulkan {
BackendConnection* Connect(InstanceBase* instance);
}
#endif  // defined(DAWN_ENABLE_BACKEND_VULKAN)

namespace {

BackendsBitset GetEnabledBackends() {
    BackendsBitset enabledBackends;
#if defined(DAWN_ENABLE_BACKEND_NULL)
    enabledBackends.set(wgpu::BackendType::Null);
#endif  // defined(DAWN_ENABLE_BACKEND_NULL)
#if defined(DAWN_ENABLE_BACKEND_D3D12)
    enabledBackends.set(wgpu::BackendType::D3D12);
#endif  // defined(DAWN_ENABLE_BACKEND_D3D12)
#if defined(DAWN_ENABLE_BACKEND_METAL)
    enabledBackends.set(wgpu::BackendType::Metal);
#endif  // defined(DAWN_ENABLE_BACKEND_METAL)
#if defined(DAWN_ENABLE_BACKEND_VULKAN)
    enabledBackends.set(wgpu::BackendType::Vulkan);
#endif  // defined(DAWN_ENABLE_BACKEND_VULKAN)
#if defined(DAWN_ENABLE_BACKEND_DESKTOP_GL)
    enabledBackends.set(wgpu::BackendType::OpenGL);
#endif  // defined(DAWN_ENABLE_BACKEND_DESKTOP_GL)
#if defined(DAWN_ENABLE_BACKEND_OPENGLES)
    enabledBackends.set(wgpu::BackendType::OpenGLES);
#endif  // defined(DAWN_ENABLE_BACKEND_OPENGLES)

    return enabledBackends;
}

dawn::platform::CachingInterface* GetCachingInterface(dawn::platform::Platform* platform) {
    if (platform != nullptr) {
        return platform->GetCachingInterface();
    }
    return nullptr;
}

}  // anonymous namespace

InstanceBase* APICreateInstance(const InstanceDescriptor* descriptor) {
    return InstanceBase::Create(descriptor).Detach();
}

// InstanceBase

// static
Ref<InstanceBase> InstanceBase::Create(const InstanceDescriptor* descriptor) {
    Ref<InstanceBase> instance = AcquireRef(new InstanceBase);
    static constexpr InstanceDescriptor kDefaultDesc = {};
    if (descriptor == nullptr) {
        descriptor = &kDefaultDesc;
    }
    if (instance->ConsumedError(instance->Initialize(descriptor))) {
        return nullptr;
    }
    return instance;
}

InstanceBase::InstanceBase() = default;

InstanceBase::~InstanceBase() = default;

void InstanceBase::WillDropLastExternalRef() {
    // InstanceBase uses RefCountedWithExternalCount to break refcycles.
    //
    // InstanceBase holds Refs to AdapterBases it has discovered, which hold Refs back to the
    // InstanceBase.
    // In order to break this cycle and prevent leaks, when the application drops the last external
    // ref and WillDropLastExternalRef is called, the instance clears out any member refs to
    // adapters that hold back-refs to the instance - thus breaking any reference cycles.
    mAdapters.clear();
}

// TODO(crbug.com/dawn/832): make the platform an initialization parameter of the instance.
MaybeError InstanceBase::Initialize(const InstanceDescriptor* descriptor) {
    DAWN_TRY(ValidateSingleSType(descriptor->nextInChain, wgpu::SType::DawnInstanceDescriptor));
    const DawnInstanceDescriptor* dawnDesc = nullptr;
    FindInChain(descriptor->nextInChain, &dawnDesc);
    if (dawnDesc != nullptr) {
        for (uint32_t i = 0; i < dawnDesc->additionalRuntimeSearchPathsCount; ++i) {
            mRuntimeSearchPaths.push_back(dawnDesc->additionalRuntimeSearchPaths[i]);
        }
    }
    // Default paths to search are next to the shared library, next to the executable, and
    // no path (just libvulkan.so).
    if (auto p = GetModuleDirectory()) {
        mRuntimeSearchPaths.push_back(std::move(*p));
    }
    if (auto p = GetExecutableDirectory()) {
        mRuntimeSearchPaths.push_back(std::move(*p));
    }
    mRuntimeSearchPaths.push_back("");

    // Initialize the platform to the default for now.
    mDefaultPlatform = std::make_unique<dawn::platform::Platform>();
    SetPlatform(mDefaultPlatform.get());

    return {};
}

void InstanceBase::APIRequestAdapter(const RequestAdapterOptions* options,
                                     WGPURequestAdapterCallback callback,
                                     void* userdata) {
    static constexpr RequestAdapterOptions kDefaultOptions = {};
    if (options == nullptr) {
        options = &kDefaultOptions;
    }
    auto result = RequestAdapterInternal(options);
    if (result.IsError()) {
        auto err = result.AcquireError();
        std::string msg = err->GetFormattedMessage();
        // TODO(crbug.com/dawn/1122): Call callbacks only on wgpuInstanceProcessEvents
        callback(WGPURequestAdapterStatus_Error, nullptr, msg.c_str(), userdata);
    } else {
        Ref<AdapterBase> adapter = result.AcquireSuccess();
        // TODO(crbug.com/dawn/1122): Call callbacks only on wgpuInstanceProcessEvents
        callback(WGPURequestAdapterStatus_Success, ToAPI(adapter.Detach()), nullptr, userdata);
    }
}

ResultOrError<Ref<AdapterBase>> InstanceBase::RequestAdapterInternal(
    const RequestAdapterOptions* options) {
    ASSERT(options != nullptr);
    if (options->forceFallbackAdapter) {
#if defined(DAWN_ENABLE_BACKEND_VULKAN)
        if (GetEnabledBackends()[wgpu::BackendType::Vulkan]) {
            dawn_native::vulkan::AdapterDiscoveryOptions vulkanOptions;
            vulkanOptions.forceSwiftShader = true;

            MaybeError result = DiscoverAdaptersInternal(&vulkanOptions);
            if (result.IsError()) {
                dawn::WarningLog() << absl::StrFormat(
                    "Skipping Vulkan Swiftshader adapter because initialization failed: %s",
                    result.AcquireError()->GetFormattedMessage());
                return Ref<AdapterBase>(nullptr);
            }
        }
#else
        return Ref<AdapterBase>(nullptr);
#endif  // defined(DAWN_ENABLE_BACKEND_VULKAN)
    } else {
        DiscoverDefaultAdapters();
    }

    wgpu::AdapterType preferredType;
    switch (options->powerPreference) {
        case wgpu::PowerPreference::LowPower:
            preferredType = wgpu::AdapterType::IntegratedGPU;
            break;
        case wgpu::PowerPreference::Undefined:
        case wgpu::PowerPreference::HighPerformance:
            preferredType = wgpu::AdapterType::DiscreteGPU;
            break;
    }

    std::optional<size_t> discreteGPUAdapterIndex;
    std::optional<size_t> integratedGPUAdapterIndex;
    std::optional<size_t> cpuAdapterIndex;
    std::optional<size_t> unknownAdapterIndex;

    for (size_t i = 0; i < mAdapters.size(); ++i) {
        AdapterProperties properties;
        mAdapters[i]->APIGetProperties(&properties);

        if (options->forceFallbackAdapter) {
            if (!gpu_info::IsGoogleSwiftshader(properties.vendorID, properties.deviceID)) {
                continue;
            }
            return mAdapters[i];
        }
        if (properties.adapterType == preferredType) {
            return mAdapters[i];
        }
        switch (properties.adapterType) {
            case wgpu::AdapterType::DiscreteGPU:
                discreteGPUAdapterIndex = i;
                break;
            case wgpu::AdapterType::IntegratedGPU:
                integratedGPUAdapterIndex = i;
                break;
            case wgpu::AdapterType::CPU:
                cpuAdapterIndex = i;
                break;
            case wgpu::AdapterType::Unknown:
                unknownAdapterIndex = i;
                break;
        }
    }

    // For now, we always prefer the discrete GPU
    if (discreteGPUAdapterIndex) {
        return mAdapters[*discreteGPUAdapterIndex];
    }
    if (integratedGPUAdapterIndex) {
        return mAdapters[*integratedGPUAdapterIndex];
    }
    if (cpuAdapterIndex) {
        return mAdapters[*cpuAdapterIndex];
    }
    if (unknownAdapterIndex) {
        return mAdapters[*unknownAdapterIndex];
    }

    return Ref<AdapterBase>(nullptr);
}

void InstanceBase::DiscoverDefaultAdapters() {
    for (wgpu::BackendType b : IterateBitSet(GetEnabledBackends())) {
        EnsureBackendConnection(b);
    }

    if (mDiscoveredDefaultAdapters) {
        return;
    }

    // Query and merge all default adapters for all backends
    for (std::unique_ptr<BackendConnection>& backend : mBackends) {
        std::vector<Ref<AdapterBase>> backendAdapters = backend->DiscoverDefaultAdapters();

        for (Ref<AdapterBase>& adapter : backendAdapters) {
            ASSERT(adapter->GetBackendType() == backend->GetType());
            ASSERT(adapter->GetInstance() == this);
            mAdapters.push_back(std::move(adapter));
        }
    }

    mDiscoveredDefaultAdapters = true;
}

// This is just a wrapper around the real logic that uses Error.h error handling.
bool InstanceBase::DiscoverAdapters(const AdapterDiscoveryOptionsBase* options) {
    MaybeError result = DiscoverAdaptersInternal(options);

    if (result.IsError()) {
        dawn::WarningLog() << absl::StrFormat(
            "Skipping %s adapter because initialization failed: %s", FromAPI(options->backendType),
            result.AcquireError()->GetFormattedMessage());
        return false;
    }

    return true;
}

const ToggleInfo* InstanceBase::GetToggleInfo(const char* toggleName) {
    return mTogglesInfo.GetToggleInfo(toggleName);
}

Toggle InstanceBase::ToggleNameToEnum(const char* toggleName) {
    return mTogglesInfo.ToggleNameToEnum(toggleName);
}

const FeatureInfo* InstanceBase::GetFeatureInfo(wgpu::FeatureName feature) {
    return mFeaturesInfo.GetFeatureInfo(feature);
}

const std::vector<Ref<AdapterBase>>& InstanceBase::GetAdapters() const {
    return mAdapters;
}

void InstanceBase::EnsureBackendConnection(wgpu::BackendType backendType) {
    if (mBackendsConnected[backendType]) {
        return;
    }

    auto Register = [this](BackendConnection* connection, wgpu::BackendType expectedType) {
        if (connection != nullptr) {
            ASSERT(connection->GetType() == expectedType);
            ASSERT(connection->GetInstance() == this);
            mBackends.push_back(std::unique_ptr<BackendConnection>(connection));
        }
    };

    switch (backendType) {
#if defined(DAWN_ENABLE_BACKEND_NULL)
        case wgpu::BackendType::Null:
            Register(null::Connect(this), wgpu::BackendType::Null);
            break;
#endif  // defined(DAWN_ENABLE_BACKEND_NULL)

#if defined(DAWN_ENABLE_BACKEND_D3D12)
        case wgpu::BackendType::D3D12:
            Register(d3d12::Connect(this), wgpu::BackendType::D3D12);
            break;
#endif  // defined(DAWN_ENABLE_BACKEND_D3D12)

#if defined(DAWN_ENABLE_BACKEND_METAL)
        case wgpu::BackendType::Metal:
            Register(metal::Connect(this), wgpu::BackendType::Metal);
            break;
#endif  // defined(DAWN_ENABLE_BACKEND_METAL)

#if defined(DAWN_ENABLE_BACKEND_VULKAN)
        case wgpu::BackendType::Vulkan:
            Register(vulkan::Connect(this), wgpu::BackendType::Vulkan);
            break;
#endif  // defined(DAWN_ENABLE_BACKEND_VULKAN)

#if defined(DAWN_ENABLE_BACKEND_DESKTOP_GL)
        case wgpu::BackendType::OpenGL:
            Register(opengl::Connect(this, wgpu::BackendType::OpenGL), wgpu::BackendType::OpenGL);
            break;
#endif  // defined(DAWN_ENABLE_BACKEND_DESKTOP_GL)

#if defined(DAWN_ENABLE_BACKEND_OPENGLES)
        case wgpu::BackendType::OpenGLES:
            Register(opengl::Connect(this, wgpu::BackendType::OpenGLES),
                     wgpu::BackendType::OpenGLES);
            break;
#endif  // defined(DAWN_ENABLE_BACKEND_OPENGLES)

        default:
            UNREACHABLE();
    }

    mBackendsConnected.set(backendType);
}

MaybeError InstanceBase::DiscoverAdaptersInternal(const AdapterDiscoveryOptionsBase* options) {
    wgpu::BackendType backendType = static_cast<wgpu::BackendType>(options->backendType);
    DAWN_TRY(ValidateBackendType(backendType));

    if (!GetEnabledBackends()[backendType]) {
        return DAWN_VALIDATION_ERROR("%s not supported.", backendType);
    }

    EnsureBackendConnection(backendType);

    bool foundBackend = false;
    for (std::unique_ptr<BackendConnection>& backend : mBackends) {
        if (backend->GetType() != backendType) {
            continue;
        }
        foundBackend = true;

        std::vector<Ref<AdapterBase>> newAdapters;
        DAWN_TRY_ASSIGN(newAdapters, backend->DiscoverAdapters(options));

        for (Ref<AdapterBase>& adapter : newAdapters) {
            ASSERT(adapter->GetBackendType() == backend->GetType());
            ASSERT(adapter->GetInstance() == this);
            mAdapters.push_back(std::move(adapter));
        }
    }

    DAWN_INVALID_IF(!foundBackend, "%s not available.", backendType);
    return {};
}

bool InstanceBase::ConsumedError(MaybeError maybeError) {
    if (maybeError.IsError()) {
        ConsumeError(maybeError.AcquireError());
        return true;
    }
    return false;
}

bool InstanceBase::IsBackendValidationEnabled() const {
    return mBackendValidationLevel != BackendValidationLevel::Disabled;
}

void InstanceBase::SetBackendValidationLevel(BackendValidationLevel level) {
    mBackendValidationLevel = level;
}

BackendValidationLevel InstanceBase::GetBackendValidationLevel() const {
    return mBackendValidationLevel;
}

void InstanceBase::EnableBeginCaptureOnStartup(bool beginCaptureOnStartup) {
    mBeginCaptureOnStartup = beginCaptureOnStartup;
}

bool InstanceBase::IsBeginCaptureOnStartupEnabled() const {
    return mBeginCaptureOnStartup;
}

void InstanceBase::SetPlatform(dawn::platform::Platform* platform) {
    if (platform == nullptr) {
        mPlatform = mDefaultPlatform.get();
    } else {
        mPlatform = platform;
    }
    mBlobCache = std::make_unique<BlobCache>(GetCachingInterface(platform));
}

void InstanceBase::SetPlatformForTesting(dawn::platform::Platform* platform) {
    SetPlatform(platform);
}

dawn::platform::Platform* InstanceBase::GetPlatform() {
    return mPlatform;
}

BlobCache* InstanceBase::GetBlobCache() {
    return mBlobCache.get();
}

uint64_t InstanceBase::GetDeviceCountForTesting() const {
    return mDeviceCountForTesting.load();
}

void InstanceBase::IncrementDeviceCountForTesting() {
    mDeviceCountForTesting++;
}

void InstanceBase::DecrementDeviceCountForTesting() {
    mDeviceCountForTesting--;
}

const std::vector<std::string>& InstanceBase::GetRuntimeSearchPaths() const {
    return mRuntimeSearchPaths;
}

void InstanceBase::ConsumeError(std::unique_ptr<ErrorData> error) {
    ASSERT(error != nullptr);
    dawn::ErrorLog() << error->GetFormattedMessage();
}

const XlibXcbFunctions* InstanceBase::GetOrCreateXlibXcbFunctions() {
#if defined(DAWN_USE_X11)
    if (mXlibXcbFunctions == nullptr) {
        mXlibXcbFunctions = std::make_unique<XlibXcbFunctions>();
    }
    return mXlibXcbFunctions.get();
#else
    UNREACHABLE();
#endif  // defined(DAWN_USE_X11)
}

Surface* InstanceBase::APICreateSurface(const SurfaceDescriptor* descriptor) {
    if (ConsumedError(ValidateSurfaceDescriptor(this, descriptor))) {
        return Surface::MakeError(this);
    }

    return new Surface(this, descriptor);
}

}  // namespace dawn::native
