// Copyright 2021 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 DAWN_NODE_BINDING_GPUBUFFER_H_
#define DAWN_NODE_BINDING_GPUBUFFER_H_

#include "dawn/webgpu_cpp.h"
#include "dawn_native/DawnNative.h"
#include "napi.h"
#include "src/dawn_node/binding/AsyncRunner.h"
#include "src/dawn_node/interop/WebGPU.h"

namespace wgpu::binding {

    // GPUBuffer is an implementation of interop::GPUBuffer that wraps a wgpu::Buffer.
    class GPUBuffer final : public interop::GPUBuffer {
      public:
        GPUBuffer(wgpu::Buffer buffer,
                  wgpu::BufferDescriptor desc,
                  wgpu::Device device,
                  std::shared_ptr<AsyncRunner> async);

        // Desc() returns the wgpu::BufferDescriptor used to construct the buffer
        const wgpu::BufferDescriptor& Desc() const {
            return desc_;
        }

        // Implicit cast operator to Dawn GPU object
        inline operator const wgpu::Buffer &() const {
            return buffer_;
        }

        // interop::GPUBuffer interface compliance
        interop::Promise<void> mapAsync(Napi::Env env,
                                        interop::GPUMapModeFlags mode,
                                        interop::GPUSize64 offset,
                                        std::optional<interop::GPUSize64> size) override;
        interop::ArrayBuffer getMappedRange(Napi::Env env,
                                            interop::GPUSize64 offset,
                                            std::optional<interop::GPUSize64> size) override;
        void unmap(Napi::Env) override;
        void destroy(Napi::Env) override;
        std::optional<std::string> getLabel(Napi::Env) override;
        void setLabel(Napi::Env, std::optional<std::string> value) override;

      private:
        struct Mapping {
            uint64_t start;
            uint64_t end;
            inline bool Intersects(uint64_t s, uint64_t e) const {
                return s < end && e > start;
            }
            Napi::Reference<interop::ArrayBuffer> buffer;
        };

        // https://www.w3.org/TR/webgpu/#buffer-interface
        enum class State {
            Unmapped,
            Mapped,
            MappedAtCreation,
            MappingPending,
            Destroyed,
        };

        wgpu::Buffer buffer_;
        wgpu::BufferDescriptor const desc_;
        wgpu::Device const device_;
        std::shared_ptr<AsyncRunner> async_;
        State state_ = State::Unmapped;
        std::vector<Mapping> mapped_;
    };

}  // namespace wgpu::binding

#endif  // DAWN_NODE_BINDING_GPUBUFFER_H_
