// Copyright (C) 2018 The Android Open Source Project
//
// 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 "VulkanStreamGuest.h"

namespace goldfish_vk {

VulkanStreamGuest::VulkanStreamGuest(IOStream *stream): mStream(stream) {
    unsetHandleMapping();
    mFeatureBits = ResourceTracker::get()->getStreamFeatures();
}

VulkanStreamGuest::~VulkanStreamGuest() = default;

bool VulkanStreamGuest::valid() {
    return true;
}

void VulkanStreamGuest::alloc(void** ptrAddr, size_t bytes) {
    if (!bytes) {
        *ptrAddr = nullptr;
        return;
    }
    
    *ptrAddr = mPool.alloc(bytes);
}

void VulkanStreamGuest::loadStringInPlace(char** forOutput) {
    size_t len = getBe32();

    alloc((void**)forOutput, len + 1);

    memset(*forOutput, 0x0, len + 1);

    if (len > 0) read(*forOutput, len);
}

void VulkanStreamGuest::loadStringArrayInPlace(char*** forOutput) {
    size_t count = getBe32();

    if (!count) {
        *forOutput = nullptr;
        return;
    }

    alloc((void**)forOutput, count * sizeof(char*));

    char **stringsForOutput = *forOutput;

    for (size_t i = 0; i < count; i++) {
        loadStringInPlace(stringsForOutput + i);
    }
}

void VulkanStreamGuest::loadStringInPlaceWithStreamPtr(char** forOutput, uint8_t** streamPtr) {
    uint32_t len;
    memcpy(&len, *streamPtr, sizeof(uint32_t));
    *streamPtr += sizeof(uint32_t);
    android::base::Stream::fromBe32((uint8_t*)&len);

    alloc((void**)forOutput, len + 1);

    memset(*forOutput, 0x0, len + 1);

    if (len > 0) {
        memcpy(*forOutput, *streamPtr, len);
        *streamPtr += len;
    }
}

void VulkanStreamGuest::loadStringArrayInPlaceWithStreamPtr(char*** forOutput, uint8_t** streamPtr) {
 uint32_t count;
    memcpy(&count, *streamPtr, sizeof(uint32_t));
    *streamPtr += sizeof(uint32_t);
    android::base::Stream::fromBe32((uint8_t*)&count);
    if (!count) {
        *forOutput = nullptr;
        return;
    }

    alloc((void**)forOutput, count * sizeof(char*));

    char **stringsForOutput = *forOutput;

    for (size_t i = 0; i < count; i++) {
        loadStringInPlaceWithStreamPtr(stringsForOutput + i, streamPtr);
    }
}


ssize_t VulkanStreamGuest::read(void *buffer, size_t size) {
    if (!mStream->readback(buffer, size)) {
        ALOGE("FATAL: Could not read back %zu bytes", size);
        abort();
    }
    return size;
}

ssize_t VulkanStreamGuest::write(const void *buffer, size_t size) {
    uint8_t* streamBuf = (uint8_t*)mStream->alloc(size);
    memcpy(streamBuf, buffer, size);
    return size;
}

void VulkanStreamGuest::writeLarge(const void* buffer, size_t size) {
    mStream->writeFullyAsync(buffer, size);
}

void VulkanStreamGuest::clearPool() {
    mPool.freeAll();
}

void VulkanStreamGuest::setHandleMapping(VulkanHandleMapping* mapping) {
    mCurrentHandleMapping = mapping;
}

void VulkanStreamGuest::unsetHandleMapping() {
    mCurrentHandleMapping = &mDefaultHandleMapping;
}

VulkanHandleMapping* VulkanStreamGuest::handleMapping() const {
    return mCurrentHandleMapping;
}

void VulkanStreamGuest::flush() {
    AEMU_SCOPED_TRACE("VulkanStreamGuest device write");
    mStream->flush();
}

uint32_t VulkanStreamGuest::getFeatureBits() const {
    return mFeatureBits;
}

void VulkanStreamGuest::incStreamRef() {
    mStream->incRef();
}

bool VulkanStreamGuest::decStreamRef() {
    return mStream->decRef();
}

uint8_t* VulkanStreamGuest::reserve(size_t size) {
    return (uint8_t*)mStream->alloc(size);
}

VulkanCountingStream::VulkanCountingStream() : VulkanStreamGuest(nullptr) { }
VulkanCountingStream::~VulkanCountingStream() = default;

ssize_t VulkanCountingStream::read(void*, size_t size) {
    m_read += size;
    return size;
}

ssize_t VulkanCountingStream::write(const void*, size_t size) {
    m_written += size;
    return size;
}

void VulkanCountingStream::rewind() {
    m_written = 0;
    m_read = 0;
}

} // namespace goldfish_vk
