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

#ifndef SRC_DAWN_NATIVE_ADAPTER_H_
#define SRC_DAWN_NATIVE_ADAPTER_H_

#include <string>
#include <vector>

#include "dawn/native/DawnNative.h"

#include "dawn/common/GPUInfo.h"
#include "dawn/common/RefCounted.h"
#include "dawn/common/ityp_span.h"
#include "dawn/native/Error.h"
#include "dawn/native/Features.h"
#include "dawn/native/Limits.h"
#include "dawn/native/Toggles.h"
#include "dawn/native/dawn_platform.h"

namespace dawn::native {

class DeviceBase;

class AdapterBase : public RefCounted {
  public:
    AdapterBase(InstanceBase* instance,
                wgpu::BackendType backend,
                const TogglesState& adapterToggles);
    ~AdapterBase() override;

    MaybeError Initialize();

    // WebGPU API
    InstanceBase* APIGetInstance() const;
    bool APIGetLimits(SupportedLimits* limits) const;
    void APIGetProperties(AdapterProperties* properties) const;
    bool APIHasFeature(wgpu::FeatureName feature) const;
    size_t APIEnumerateFeatures(wgpu::FeatureName* features) const;
    void APIRequestDevice(const DeviceDescriptor* descriptor,
                          WGPURequestDeviceCallback callback,
                          void* userdata);
    DeviceBase* APICreateDevice(const DeviceDescriptor* descriptor = nullptr);

    uint32_t GetVendorId() const;
    uint32_t GetDeviceId() const;
    const gpu_info::DriverVersion& GetDriverVersion() const;
    wgpu::BackendType GetBackendType() const;

    // This method differs from APIGetInstance() in that it won't increase the ref count of the
    // instance.
    InstanceBase* GetInstance() const;

    void ResetInternalDeviceForTesting();

    FeaturesSet GetSupportedFeatures() const;
    bool SupportsAllRequiredFeatures(
        const ityp::span<size_t, const wgpu::FeatureName>& features) const;

    bool GetLimits(SupportedLimits* limits) const;

    void SetUseTieredLimits(bool useTieredLimits);

    // Get the actual toggles state of the adapter.
    const TogglesState& GetTogglesState() const;

    virtual bool SupportsExternalImages() const = 0;

  protected:
    uint32_t mVendorId = 0xFFFFFFFF;
    std::string mVendorName;
    std::string mArchitectureName;
    uint32_t mDeviceId = 0xFFFFFFFF;
    std::string mName;
    wgpu::AdapterType mAdapterType = wgpu::AdapterType::Unknown;
    gpu_info::DriverVersion mDriverVersion;
    std::string mDriverDescription;

    // Mark a feature as enabled in mSupportedFeatures.
    void EnableFeature(Feature feature);
    // Check if a feature os supported by this adapter AND suitable with given toggles.
    // TODO(dawn:1495): After implementing adapter toggles, remove this and use adapter toggles
    // instead of device toggles to validate supported features.
    MaybeError ValidateFeatureSupportedWithToggles(wgpu::FeatureName feature,
                                                   const TogglesState& toggles) const;
    // Used for the tests that intend to use an adapter without all features enabled.
    void SetSupportedFeaturesForTesting(const std::vector<wgpu::FeatureName>& requiredFeatures);

  private:
    // Backend-specific force-setting and defaulting device toggles
    virtual void SetupBackendDeviceToggles(TogglesState* deviceToggles) const = 0;

    virtual ResultOrError<Ref<DeviceBase>> CreateDeviceImpl(const DeviceDescriptor* descriptor,
                                                            const TogglesState& deviceToggles) = 0;

    virtual MaybeError InitializeImpl() = 0;

    // Check base WebGPU features and discover supported features.
    virtual void InitializeSupportedFeaturesImpl() = 0;

    // Check base WebGPU limits and populate supported limits.
    virtual MaybeError InitializeSupportedLimitsImpl(CombinedLimits* limits) = 0;

    virtual void InitializeVendorArchitectureImpl();

    virtual MaybeError ValidateFeatureSupportedWithTogglesImpl(
        wgpu::FeatureName feature,
        const TogglesState& toggles) const = 0;

    ResultOrError<Ref<DeviceBase>> CreateDeviceInternal(const DeviceDescriptor* descriptor);

    virtual MaybeError ResetInternalDeviceForTestingImpl();
    Ref<InstanceBase> mInstance;
    wgpu::BackendType mBackend;

    // Adapter toggles state, currently only inherited from instance toggles state.
    TogglesState mTogglesState;

    // Features set that CAN be supported by devices of this adapter. Some features in this set may
    // be guarded by toggles, and creating a device with these features required may result in a
    // validation error if proper toggles are not enabled/disabled.
    FeaturesSet mSupportedFeatures;

    CombinedLimits mLimits;
    bool mUseTieredLimits = false;
};

}  // namespace dawn::native

#endif  // SRC_DAWN_NATIVE_ADAPTER_H_
