// Copyright 2017 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 DAWNNATIVE_UTILS_WGPUHELPERS_H_
#define DAWNNATIVE_UTILS_WGPUHELPERS_H_

#include <dawn_native/dawn_platform.h>

#include <array>
#include <initializer_list>
#include <vector>

#include "common/RefCounted.h"
#include "dawn_native/Error.h"

namespace dawn::native::utils {

    ResultOrError<Ref<ShaderModuleBase>> CreateShaderModule(DeviceBase* device, const char* source);

    ResultOrError<Ref<BufferBase>> CreateBufferFromData(DeviceBase* device,
                                                        wgpu::BufferUsage usage,
                                                        const void* data,
                                                        uint64_t size);

    template <typename T>
    ResultOrError<Ref<BufferBase>> CreateBufferFromData(DeviceBase* device,
                                                        wgpu::BufferUsage usage,
                                                        std::initializer_list<T> data) {
        return CreateBufferFromData(device, usage, data.begin(), uint32_t(sizeof(T) * data.size()));
    }

    ResultOrError<Ref<PipelineLayoutBase>> MakeBasicPipelineLayout(
        DeviceBase* device,
        const Ref<BindGroupLayoutBase>& bindGroupLayout);

    // Helpers to make creating bind group layouts look nicer:
    //
    //   utils::MakeBindGroupLayout(device, {
    //       {0, wgpu::ShaderStage::Vertex, wgpu::BufferBindingType::Uniform},
    //       {1, wgpu::ShaderStage::Fragment, wgpu::SamplerBindingType::Filtering},
    //       {3, wgpu::ShaderStage::Fragment, wgpu::TextureSampleType::Float}
    //   });

    struct BindingLayoutEntryInitializationHelper : BindGroupLayoutEntry {
        BindingLayoutEntryInitializationHelper(uint32_t entryBinding,
                                               wgpu::ShaderStage entryVisibility,
                                               wgpu::BufferBindingType bufferType,
                                               bool bufferHasDynamicOffset = false,
                                               uint64_t bufferMinBindingSize = 0);
        BindingLayoutEntryInitializationHelper(uint32_t entryBinding,
                                               wgpu::ShaderStage entryVisibility,
                                               wgpu::SamplerBindingType samplerType);
        BindingLayoutEntryInitializationHelper(
            uint32_t entryBinding,
            wgpu::ShaderStage entryVisibility,
            wgpu::TextureSampleType textureSampleType,
            wgpu::TextureViewDimension viewDimension = wgpu::TextureViewDimension::e2D,
            bool textureMultisampled = false);
        BindingLayoutEntryInitializationHelper(
            uint32_t entryBinding,
            wgpu::ShaderStage entryVisibility,
            wgpu::StorageTextureAccess storageTextureAccess,
            wgpu::TextureFormat format,
            wgpu::TextureViewDimension viewDimension = wgpu::TextureViewDimension::e2D);

        BindingLayoutEntryInitializationHelper(const BindGroupLayoutEntry& entry);
    };

    ResultOrError<Ref<BindGroupLayoutBase>> MakeBindGroupLayout(
        DeviceBase* device,
        std::initializer_list<BindingLayoutEntryInitializationHelper> entriesInitializer,
        bool allowInternalBinding = false);

    // Helpers to make creating bind groups look nicer:
    //
    //   utils::MakeBindGroup(device, layout, {
    //       {0, mySampler},
    //       {1, myBuffer, offset, size},
    //       {3, myTextureView}
    //   });

    // Structure with one constructor per-type of bindings, so that the initializer_list accepts
    // bindings with the right type and no extra information.
    struct BindingInitializationHelper {
        BindingInitializationHelper(uint32_t binding, const Ref<SamplerBase>& sampler);
        BindingInitializationHelper(uint32_t binding, const Ref<TextureViewBase>& textureView);
        BindingInitializationHelper(uint32_t binding,
                                    const Ref<BufferBase>& buffer,
                                    uint64_t offset = 0,
                                    uint64_t size = wgpu::kWholeSize);
        ~BindingInitializationHelper();

        BindGroupEntry GetAsBinding() const;

        uint32_t binding;
        Ref<SamplerBase> sampler;
        Ref<TextureViewBase> textureView;
        Ref<BufferBase> buffer;
        uint64_t offset = 0;
        uint64_t size = 0;
    };

    ResultOrError<Ref<BindGroupBase>> MakeBindGroup(
        DeviceBase* device,
        const Ref<BindGroupLayoutBase>& layout,
        std::initializer_list<BindingInitializationHelper> entriesInitializer);

    const char* GetLabelForTrace(const char* label);

}  // namespace dawn::native::utils

#endif  // DAWNNATIVE_UTILS_WGPUHELPERS_H_