/*
* Copyright (C) 2011 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 "ReadBuffer.h"

#include "host-common/logging.h"

#include <algorithm>

#include <assert.h>
#include <string.h>
#include <limits.h>

namespace emugl {

ReadBuffer::ReadBuffer(size_t bufsize) {
    m_size = bufsize;
    m_buf = (unsigned char*)malloc(m_size);
    m_validData = 0;
    m_readPtr = m_buf;
}

ReadBuffer::~ReadBuffer() {
    free(m_buf);
}

void ReadBuffer::setNeededFreeTailSize(size_t size) {
    m_neededFreeTailSize = size;
}

int ReadBuffer::getData(IOStream* stream, size_t minSize) {
    assert(stream);
    assert(minSize > m_validData);

    const size_t minSizeToRead = minSize - m_validData;
    const size_t neededFreeTailThisTime =
        std::max(minSizeToRead,
                 m_neededFreeTailSize);

    size_t maxSizeToRead;
    const size_t freeTailSize = m_buf + m_size - (m_readPtr + m_validData);
    if (freeTailSize >= neededFreeTailThisTime) {
        maxSizeToRead = freeTailSize;
    } else {
        if (freeTailSize + (m_readPtr - m_buf) >= neededFreeTailThisTime) {
            // There's some gap in the beginning, if we move the data over it
            // that's going to be enough.
            memmove(m_buf, m_readPtr, m_validData);
        } else {
            // Not enough space even with moving, reallocate.
            // Note: make sure we can fit at least two of the requested packets
            //  into the new buffer to minimize the reallocations and
            //  memmove()-ing stuff around.
          size_t new_size = std::max(2 * minSizeToRead + m_validData, 2 * m_size);
          if (new_size < m_size) {  // overflow check
                new_size = INT_MAX;
            }

            const auto new_buf = (unsigned char*)malloc(new_size);
            if (!new_buf) {
                ERR("Failed to alloc %zu bytes for ReadBuffer\n", new_size);
                return -1;
            }

            memcpy(new_buf, m_readPtr, m_validData);
            free(m_buf);
            m_buf = new_buf;
            m_size = new_size;
        }
        // We can read more now, let's request it in case all data is ready
        // for reading.
        maxSizeToRead = m_size - m_validData;
        m_readPtr = m_buf;
    }

    // get fresh data into the buffer;
    int readTotal = 0;
    do {
        const size_t readNow = stream->read(m_readPtr + m_validData,
                                            maxSizeToRead - readTotal);

        if (!readNow) {
            if (readTotal > 0) {
                return readTotal;
            } else {
                return -1;
            }
        }
        readTotal += readNow;
        m_validData += readNow;
    } while (readTotal < minSizeToRead);

    return readTotal;
}

void ReadBuffer::consume(size_t amount) {
    assert(amount <= m_validData);
    m_validData -= amount;
    m_readPtr += amount;
}

void ReadBuffer::onSave(android::base::Stream* stream) {
    stream->putBe32(m_size);
    stream->putBe32(m_validData);
    stream->write(m_readPtr, m_validData);
}

void ReadBuffer::onLoad(android::base::Stream* stream) {
    const auto size = stream->getBe32();
    if (size > m_size) {
        m_size = size;
        free(m_buf);
        m_buf = (unsigned char*)malloc(m_size);
    }
    m_readPtr = m_buf;
    m_validData = stream->getBe32();
    assert(m_validData <= m_size);
    stream->read(m_readPtr, m_validData);
}

void ReadBuffer::printStats() {
    printf("ReadBuffer::%s: tail move time %f ms\n", __func__,
            (float)m_tailMoveTimeUs / 1000.0f);
    m_tailMoveTimeUs = 0;
}
}  // namespace emugl
