// 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_WIRESERVER_H_
#define DAWNWIRE_WIRESERVER_H_

#include <memory>

#include "dawn_wire/Wire.h"

struct DawnProcTable;

namespace dawn_wire {

    namespace server {
        class Server;
        class MemoryTransferService;
    }  // namespace server

    struct DAWN_WIRE_EXPORT WireServerDescriptor {
        const DawnProcTable* procs;
        CommandSerializer* serializer;
        server::MemoryTransferService* memoryTransferService = nullptr;
    };

    class DAWN_WIRE_EXPORT WireServer : public CommandHandler {
      public:
        WireServer(const WireServerDescriptor& descriptor);
        ~WireServer() override;

        const volatile char* HandleCommands(const volatile char* commands,
                                            size_t size) override final;

        bool InjectTexture(WGPUTexture texture,
                           uint32_t id,
                           uint32_t generation,
                           uint32_t deviceId,
                           uint32_t deviceGeneration);
        bool InjectSwapChain(WGPUSwapChain swapchain,
                             uint32_t id,
                             uint32_t generation,
                             uint32_t deviceId,
                             uint32_t deviceGeneration);

        bool InjectDevice(WGPUDevice device, uint32_t id, uint32_t generation);

        // Look up a device by (id, generation) pair. Returns nullptr if the generation
        // has expired or the id is not found.
        // The Wire does not have destroy hooks to allow an embedder to observe when an object
        // has been destroyed, but in Chrome, we need to know the list of live devices so we
        // can call device.Tick() on all of them periodically to ensure progress on asynchronous
        // work is made. Getting this list can be done by tracking the (id, generation) of
        // previously injected devices, and observing if GetDevice(id, generation) returns non-null.
        WGPUDevice GetDevice(uint32_t id, uint32_t generation);

      private:
        std::unique_ptr<server::Server> mImpl;
    };

    namespace server {
        class DAWN_WIRE_EXPORT MemoryTransferService {
          public:
            MemoryTransferService();
            virtual ~MemoryTransferService();

            class ReadHandle;
            class WriteHandle;

            // Deserialize data to create Read/Write handles. These handles are for the client
            // to Read/Write data.
            virtual bool DeserializeReadHandle(const void* deserializePointer,
                                               size_t deserializeSize,
                                               ReadHandle** readHandle) = 0;
            virtual bool DeserializeWriteHandle(const void* deserializePointer,
                                                size_t deserializeSize,
                                                WriteHandle** writeHandle) = 0;

            class DAWN_WIRE_EXPORT ReadHandle {
              public:
                ReadHandle();
                virtual ~ReadHandle();

                // Return the size of the command serialized if
                // SerializeDataUpdate is called with the same offset/size args
                // TODO(dawn:773): change to pure virtual after update on chromium side.
                virtual size_t SizeOfSerializeDataUpdate(size_t offset, size_t size) {
                    return 0;
                }

                // Gets called when a MapReadCallback resolves.
                // Serialize the data update for the range (offset, offset + size) into
                // |serializePointer| to the client There could be nothing to be serialized (if
                // using shared memory)
                // TODO(dawn:773): change to pure virtual after update on chromium side.
                virtual void SerializeDataUpdate(const void* data,
                                                 size_t offset,
                                                 size_t size,
                                                 void* serializePointer) {
                }

                // TODO(dawn:773): remove after update on chromium side.
                virtual size_t SerializeInitialDataSize(const void* data, size_t dataLength) {
                    return 0;
                }

                // TODO(dawn:773): remove after update on chromium side.
                virtual void SerializeInitialData(const void* data,
                                                  size_t dataLength,
                                                  void* serializePointer) {
                }

              private:
                ReadHandle(const ReadHandle&) = delete;
                ReadHandle& operator=(const ReadHandle&) = delete;
            };

            class DAWN_WIRE_EXPORT WriteHandle {
              public:
                WriteHandle();
                virtual ~WriteHandle();

                // Set the target for writes from the client. DeserializeFlush should copy data
                // into the target.
                // TODO(dawn:773): only set backing buffer pointer data
                void SetTarget(void* data, size_t dataLength);

                // TODO(dawn:773): remove after update on chromium side.
                virtual bool DeserializeFlush(const void* deserializePointer,
                                              size_t deserializeSize) {
                    return false;
                }

                // This function takes in the serialized result of
                // client::MemoryTransferService::WriteHandle::SerializeDataUpdate.
                virtual bool DeserializeDataUpdate(const void* deserializePointer,
                                                   size_t deserializeSize,
                                                   size_t offset,
                                                   size_t size) {
                    return false;
                }

              protected:
                void* mTargetData = nullptr;
                // TODO(dawn:773): only set backing buffer pointer data
                size_t mDataLength = 0;

              private:
                WriteHandle(const WriteHandle&) = delete;
                WriteHandle& operator=(const WriteHandle&) = delete;
            };

          private:
            MemoryTransferService(const MemoryTransferService&) = delete;
            MemoryTransferService& operator=(const MemoryTransferService&) = delete;
        };
    }  // namespace server

}  // namespace dawn_wire

#endif  // DAWNWIRE_WIRESERVER_H_
