// Copyright 2019 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 DAWNWIRE_CLIENT_BUFFER_H_
#define DAWNWIRE_CLIENT_BUFFER_H_

#include <dawn/webgpu.h>

#include "dawn_wire/WireClient.h"
#include "dawn_wire/client/ObjectBase.h"
#include "dawn_wire/client/RequestTracker.h"

namespace dawn_wire { namespace client {

    class Device;

    class Buffer final : public ObjectBase {
      public:
        using ObjectBase::ObjectBase;

        static WGPUBuffer Create(Device* device, const WGPUBufferDescriptor* descriptor);
        static WGPUBuffer CreateError(Device* device);

        ~Buffer();

        bool OnMapAsyncCallback(uint64_t requestSerial,
                                uint32_t status,
                                uint64_t readDataUpdateInfoLength,
                                const uint8_t* readDataUpdateInfo);
        void MapAsync(WGPUMapModeFlags mode,
                      size_t offset,
                      size_t size,
                      WGPUBufferMapCallback callback,
                      void* userdata);
        void* GetMappedRange(size_t offset, size_t size);
        const void* GetConstMappedRange(size_t offset, size_t size);
        void Unmap();

        void Destroy();

      private:
        void CancelCallbacksForDisconnect() override;
        void ClearAllCallbacks(WGPUBufferMapAsyncStatus status);

        bool IsMappedForReading() const;
        bool IsMappedForWriting() const;
        bool CheckGetMappedRangeOffsetSize(size_t offset, size_t size) const;

        void FreeMappedData();

        Device* mDevice;

        enum class MapRequestType { None, Read, Write };

        enum class MapState {
            Unmapped,
            MappedForRead,
            MappedForWrite,
            MappedAtCreation,
        };

        // We want to defer all the validation to the server, which means we could have multiple
        // map request in flight at a single time and need to track them separately.
        // On well-behaved applications, only one request should exist at a single time.
        struct MapRequestData {
            WGPUBufferMapCallback callback = nullptr;
            void* userdata = nullptr;
            size_t offset = 0;
            size_t size = 0;

            // When the buffer is destroyed or unmapped too early, the unmappedBeforeX status takes
            // precedence over the success value returned from the server. However Error statuses
            // from the server take precedence over the client-side status.
            WGPUBufferMapAsyncStatus clientStatus = WGPUBufferMapAsyncStatus_Success;

            MapRequestType type = MapRequestType::None;
        };
        RequestTracker<MapRequestData> mRequests;
        uint64_t mSize = 0;

        // Only one mapped pointer can be active at a time because Unmap clears all the in-flight
        // requests.
        // TODO(enga): Use a tagged pointer to save space.
        std::unique_ptr<MemoryTransferService::ReadHandle> mReadHandle = nullptr;
        std::unique_ptr<MemoryTransferService::WriteHandle> mWriteHandle = nullptr;
        MapState mMapState = MapState::Unmapped;
        bool mDestructWriteHandleOnUnmap = false;

        void* mMappedData = nullptr;
        size_t mMapOffset = 0;
        size_t mMapSize = 0;

        std::weak_ptr<bool> mDeviceIsAlive;
    };

}}  // namespace dawn_wire::client

#endif  // DAWNWIRE_CLIENT_BUFFER_H_
