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