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

#include "common/Alloc.h"
#include "common/Assert.h"
#include "dawn_wire/WireClient.h"
#include "dawn_wire/client/Client.h"

#include <cstring>

namespace dawn_wire { namespace client {

    class InlineMemoryTransferService : public MemoryTransferService {
        class ReadHandleImpl : public ReadHandle {
          public:
            explicit ReadHandleImpl(std::unique_ptr<uint8_t[]> stagingData, size_t size)
                : mStagingData(std::move(stagingData)), mSize(size) {
            }

            ~ReadHandleImpl() override = default;

            size_t SerializeCreateSize() override {
                return 0;
            }

            void SerializeCreate(void*) override {
            }

            const void* GetData() override {
                return mStagingData.get();
            }

            bool DeserializeDataUpdate(const void* deserializePointer,
                                       size_t deserializeSize,
                                       size_t offset,
                                       size_t size) override {
                if (deserializeSize != size || deserializePointer == nullptr) {
                    return false;
                }

                if (offset > mSize || size > mSize - offset) {
                    return false;
                }

                void* start = static_cast<uint8_t*>(mStagingData.get()) + offset;
                memcpy(start, deserializePointer, size);
                return true;
            }

          private:
            std::unique_ptr<uint8_t[]> mStagingData;
            size_t mSize;
        };

        class WriteHandleImpl : public WriteHandle {
          public:
            explicit WriteHandleImpl(std::unique_ptr<uint8_t[]> stagingData, size_t size)
                : mStagingData(std::move(stagingData)), mSize(size) {
            }

            ~WriteHandleImpl() override = default;

            size_t SerializeCreateSize() override {
                return 0;
            }

            void SerializeCreate(void*) override {
            }

            void* GetData() override {
                return mStagingData.get();
            }

            size_t SizeOfSerializeDataUpdate(size_t offset, size_t size) override {
                ASSERT(offset <= mSize);
                ASSERT(size <= mSize - offset);
                return size;
            }

            void SerializeDataUpdate(void* serializePointer, size_t offset, size_t size) override {
                ASSERT(mStagingData != nullptr);
                ASSERT(serializePointer != nullptr);
                ASSERT(offset <= mSize);
                ASSERT(size <= mSize - offset);
                memcpy(serializePointer, static_cast<uint8_t*>(mStagingData.get()) + offset, size);
            }

          private:
            std::unique_ptr<uint8_t[]> mStagingData;
            size_t mSize;
        };

      public:
        InlineMemoryTransferService() {
        }
        ~InlineMemoryTransferService() override = default;

        ReadHandle* CreateReadHandle(size_t size) override {
            auto stagingData = std::unique_ptr<uint8_t[]>(AllocNoThrow<uint8_t>(size));
            if (stagingData) {
                return new ReadHandleImpl(std::move(stagingData), size);
            }
            return nullptr;
        }

        WriteHandle* CreateWriteHandle(size_t size) override {
            auto stagingData = std::unique_ptr<uint8_t[]>(AllocNoThrow<uint8_t>(size));
            if (stagingData) {
                memset(stagingData.get(), 0, size);
                return new WriteHandleImpl(std::move(stagingData), size);
            }
            return nullptr;
        }
    };

    std::unique_ptr<MemoryTransferService> CreateInlineMemoryTransferService() {
        return std::make_unique<InlineMemoryTransferService>();
    }

}}  //  namespace dawn_wire::client
