/*
 * Copyright (C) 2006-2007 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.
 */

#undef LOG_TAG
#define LOG_TAG "CursorWindow"

#include <utils/Log.h>
#include <binder/CursorWindow.h>
#include <binder/MemoryHeapBase.h>
#include <binder/MemoryBase.h>

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

namespace android {

CursorWindow::CursorWindow(size_t maxSize) :
    mMaxSize(maxSize)
{
}

bool CursorWindow::setMemory(const sp<IMemory>& memory)
{
    mMemory = memory;
    mData = (uint8_t *) memory->pointer();
    if (mData == NULL) {
        return false;
    }
    mHeader = (window_header_t *) mData;

    // Make the window read-only
    ssize_t size = memory->size();
    mSize = size;
    mMaxSize = size;
    mFreeOffset = size;
LOG_WINDOW("Created CursorWindow from existing IMemory: mFreeOffset = %d, numRows = %d, numColumns = %d, mSize = %d, mMaxSize = %d, mData = %p", mFreeOffset, mHeader->numRows, mHeader->numColumns, mSize, mMaxSize, mData);
    return true;
}

bool CursorWindow::initBuffer(bool localOnly)
{
    //TODO Use a non-memory dealer mmap region for localOnly

    sp<MemoryHeapBase> heap;
    heap = new MemoryHeapBase(mMaxSize, 0, "CursorWindow");
    if (heap != NULL) {
        mMemory = new MemoryBase(heap, 0, mMaxSize);
        if (mMemory != NULL) {
            mData = (uint8_t *) mMemory->pointer();
            if (mData) {
                mHeader = (window_header_t *) mData;
                mSize = mMaxSize;

                // Put the window into a clean state
                clear();
            LOG_WINDOW("Created CursorWindow with new MemoryDealer: mFreeOffset = %d, mSize = %d, mMaxSize = %d, mData = %p", mFreeOffset, mSize, mMaxSize, mData);
                return true;                
            }
        } 
        LOGE("CursorWindow heap allocation failed");
        return false;
    } else {
        LOGE("failed to create the CursorWindow heap");
        return false;
    }
}

CursorWindow::~CursorWindow()
{
    // Everything that matters is a smart pointer
}

void CursorWindow::clear()
{
    mHeader->numRows = 0;
    mHeader->numColumns = 0;
    mFreeOffset = sizeof(window_header_t) + ROW_SLOT_CHUNK_SIZE;
    // Mark the first chunk's next 'pointer' as null
    *((uint32_t *)(mData + mFreeOffset - sizeof(uint32_t))) = 0;
}

int32_t CursorWindow::freeSpace()
{
    int32_t freeSpace = mSize - mFreeOffset;
    if (freeSpace < 0) {
        freeSpace = 0;
    }
    return freeSpace;
}

field_slot_t * CursorWindow::allocRow()
{
    // Fill in the row slot
    row_slot_t * rowSlot = allocRowSlot();
    if (rowSlot == NULL) {
        return NULL;
    }

    // Allocate the slots for the field directory
    size_t fieldDirSize = mHeader->numColumns * sizeof(field_slot_t);
    uint32_t fieldDirOffset = alloc(fieldDirSize);
    if (!fieldDirOffset) {
        mHeader->numRows--;
        LOG_WINDOW("The row failed, so back out the new row accounting from allocRowSlot %d", mHeader->numRows);
        return NULL;
    }
    field_slot_t * fieldDir = (field_slot_t *)offsetToPtr(fieldDirOffset);
    memset(fieldDir, 0x0, fieldDirSize);

LOG_WINDOW("Allocated row %u, rowSlot is at offset %u, fieldDir is %d bytes at offset %u\n", (mHeader->numRows - 1), ((uint8_t *)rowSlot) - mData, fieldDirSize, fieldDirOffset);
    rowSlot->offset = fieldDirOffset;

    return fieldDir;
}

uint32_t CursorWindow::alloc(size_t requestedSize, bool aligned)
{
    int32_t size;
    uint32_t padding;
    if (aligned) {
        // 4 byte alignment
        padding = 4 - (mFreeOffset & 0x3);
    } else {
        padding = 0;
    }

    size = requestedSize + padding;

    if (size > freeSpace()) {
        LOGV("need to grow: mSize = %d, size = %d, freeSpace() = %d, numRows = %d", mSize, size,
                freeSpace(), mHeader->numRows);
        // Only grow the window if the first row doesn't fit
        if (mHeader->numRows > 1) {
            LOGV("not growing since there are already %d row(s), max size %d", mHeader->numRows,
                    mMaxSize);
            return 0;
        }

        // Find a new size that will fit the allocation
        int allocated = mSize - freeSpace();
        int newSize = mSize + WINDOW_ALLOCATION_SIZE;
        while (size > (newSize - allocated)) {
            newSize += WINDOW_ALLOCATION_SIZE;
            if (newSize > mMaxSize) {
                LOGE("Attempting to grow window beyond max size (%d)", mMaxSize);
                return 0;
            }
        }
LOG_WINDOW("found size %d", newSize);
        mSize = newSize;
    }

    uint32_t offset = mFreeOffset + padding;
    mFreeOffset += size;
    return offset;
}

row_slot_t * CursorWindow::getRowSlot(int row)
{
    LOG_WINDOW("enter getRowSlot current row num %d, this row %d", mHeader->numRows, row);
    int chunkNum = row / ROW_SLOT_CHUNK_NUM_ROWS;
    int chunkPos = row % ROW_SLOT_CHUNK_NUM_ROWS;
    int chunkPtrOffset = sizeof(window_header_t) + ROW_SLOT_CHUNK_SIZE - sizeof(uint32_t);
    uint8_t * rowChunk = mData + sizeof(window_header_t);
    for (int i = 0; i < chunkNum; i++) {
        rowChunk = offsetToPtr(*((uint32_t *)(mData + chunkPtrOffset)));
        chunkPtrOffset = rowChunk - mData + (ROW_SLOT_CHUNK_NUM_ROWS * sizeof(row_slot_t));
    }
    return (row_slot_t *)(rowChunk + (chunkPos * sizeof(row_slot_t)));
    LOG_WINDOW("exit getRowSlot current row num %d, this row %d", mHeader->numRows, row);    
}

row_slot_t * CursorWindow::allocRowSlot()
{
    int chunkNum = mHeader->numRows / ROW_SLOT_CHUNK_NUM_ROWS;
    int chunkPos = mHeader->numRows % ROW_SLOT_CHUNK_NUM_ROWS;
    int chunkPtrOffset = sizeof(window_header_t) + ROW_SLOT_CHUNK_SIZE - sizeof(uint32_t);
    uint8_t * rowChunk = mData + sizeof(window_header_t);
LOG_WINDOW("Allocating row slot, mHeader->numRows is %d, chunkNum is %d, chunkPos is %d", mHeader->numRows, chunkNum, chunkPos);
    for (int i = 0; i < chunkNum; i++) {
        uint32_t nextChunkOffset = *((uint32_t *)(mData + chunkPtrOffset));
LOG_WINDOW("nextChunkOffset is %d", nextChunkOffset);
        if (nextChunkOffset == 0) {
            // Allocate a new row chunk
            nextChunkOffset = alloc(ROW_SLOT_CHUNK_SIZE, true);
            if (nextChunkOffset == 0) {
                return NULL;
            }
            rowChunk = offsetToPtr(nextChunkOffset);
LOG_WINDOW("allocated new chunk at %d, rowChunk = %p", nextChunkOffset, rowChunk);
            *((uint32_t *)(mData + chunkPtrOffset)) = rowChunk - mData;
            // Mark the new chunk's next 'pointer' as null
            *((uint32_t *)(rowChunk + ROW_SLOT_CHUNK_SIZE - sizeof(uint32_t))) = 0;
        } else {
LOG_WINDOW("follwing 'pointer' to next chunk, offset of next pointer is %d", chunkPtrOffset);
            rowChunk = offsetToPtr(nextChunkOffset);
            chunkPtrOffset = rowChunk - mData + (ROW_SLOT_CHUNK_NUM_ROWS * sizeof(row_slot_t));
        }
    }
    mHeader->numRows++;

    return (row_slot_t *)(rowChunk + (chunkPos * sizeof(row_slot_t)));
}

field_slot_t * CursorWindow::getFieldSlotWithCheck(int row, int column)
{
  if (row < 0 || row >= mHeader->numRows || column < 0 || column >= mHeader->numColumns) {
      LOGE("Failed to read row# %d, column# from a CursorWindow which has %d rows, %d columns.",
              row, column, mHeader->numRows, mHeader->numColumns);
      return NULL;
  }        
  row_slot_t * rowSlot = getRowSlot(row);
  if (!rowSlot) {
      LOGE("Failed to find rowSlot for row %d", row);
      return NULL;
  }
  if (rowSlot->offset == 0 || rowSlot->offset >= mSize) {
      LOGE("Invalid rowSlot, offset = %d", rowSlot->offset);
      return NULL;
  }  
  int fieldDirOffset = rowSlot->offset;
  return ((field_slot_t *)offsetToPtr(fieldDirOffset)) + column;  
}

uint32_t CursorWindow::read_field_slot(int row, int column, field_slot_t * slotOut)
{
    if (row < 0 || row >= mHeader->numRows || column < 0 || column >= mHeader->numColumns) {
        LOGE("Can't read row# %d, col# %d from CursorWindow. Make sure your Cursor is initialized correctly.",
                row, column);
        return -1;
    }        
    row_slot_t * rowSlot = getRowSlot(row);
    if (!rowSlot) {
        LOGE("Failed to find rowSlot for row %d", row);
        return -1;
    }
    if (rowSlot->offset == 0 || rowSlot->offset >= mSize) {
        LOGE("Invalid rowSlot, offset = %d", rowSlot->offset);
        return -1;
    }
LOG_WINDOW("Found field directory for %d,%d at rowSlot %d, offset %d", row, column, (uint8_t *)rowSlot - mData, rowSlot->offset);
    field_slot_t * fieldDir = (field_slot_t *)offsetToPtr(rowSlot->offset);
LOG_WINDOW("Read field_slot_t %d,%d: offset = %d, size = %d, type = %d", row, column, fieldDir[column].data.buffer.offset, fieldDir[column].data.buffer.size, fieldDir[column].type);

    // Copy the data to the out param
    slotOut->data.buffer.offset = fieldDir[column].data.buffer.offset;
    slotOut->data.buffer.size = fieldDir[column].data.buffer.size;
    slotOut->type = fieldDir[column].type;
    return 0;
}

void CursorWindow::copyIn(uint32_t offset, uint8_t const * data, size_t size)
{
    assert(offset + size <= mSize);    
    memcpy(mData + offset, data, size);
}

void CursorWindow::copyIn(uint32_t offset, int64_t data)
{
    assert(offset + sizeof(int64_t) <= mSize);
    memcpy(mData + offset, (uint8_t *)&data, sizeof(int64_t));
}

void CursorWindow::copyIn(uint32_t offset, double data)
{
    assert(offset + sizeof(double) <= mSize);
    memcpy(mData + offset, (uint8_t *)&data, sizeof(double));
}

void CursorWindow::copyOut(uint32_t offset, uint8_t * data, size_t size)
{
    assert(offset + size <= mSize);
    memcpy(data, mData + offset, size);
}

int64_t CursorWindow::copyOutLong(uint32_t offset)
{
    int64_t value;
    assert(offset + sizeof(int64_t) <= mSize);
    memcpy(&value, mData + offset, sizeof(int64_t));
    return value;
}

double CursorWindow::copyOutDouble(uint32_t offset)
{
    double value;
    assert(offset + sizeof(double) <= mSize);
    memcpy(&value, mData + offset, sizeof(double));
    return value;
}

bool CursorWindow::putLong(unsigned int row, unsigned int col, int64_t value)
{
    field_slot_t * fieldSlot = getFieldSlotWithCheck(row, col);
    if (!fieldSlot) {
        return false;
    }

#if WINDOW_STORAGE_INLINE_NUMERICS
    fieldSlot->data.l = value;
#else
    int offset = alloc(sizeof(int64_t));
    if (!offset) {
        return false;
    }

    copyIn(offset, value);

    fieldSlot->data.buffer.offset = offset;
    fieldSlot->data.buffer.size = sizeof(int64_t);
#endif
    fieldSlot->type = FIELD_TYPE_INTEGER;
    return true;
}

bool CursorWindow::putDouble(unsigned int row, unsigned int col, double value)
{
    field_slot_t * fieldSlot = getFieldSlotWithCheck(row, col);
    if (!fieldSlot) {
        return false;
    }

#if WINDOW_STORAGE_INLINE_NUMERICS
    fieldSlot->data.d = value;
#else
    int offset = alloc(sizeof(int64_t));
    if (!offset) {
        return false;
    }

    copyIn(offset, value);

    fieldSlot->data.buffer.offset = offset;
    fieldSlot->data.buffer.size = sizeof(double);
#endif
    fieldSlot->type = FIELD_TYPE_FLOAT;
    return true;
}

bool CursorWindow::putNull(unsigned int row, unsigned int col)
{
    field_slot_t * fieldSlot = getFieldSlotWithCheck(row, col);
    if (!fieldSlot) {
        return false;
    }

    fieldSlot->type = FIELD_TYPE_NULL;
    fieldSlot->data.buffer.offset = 0;
    fieldSlot->data.buffer.size = 0;
    return true;
}

bool CursorWindow::getLong(unsigned int row, unsigned int col, int64_t * valueOut)
{
    field_slot_t * fieldSlot = getFieldSlotWithCheck(row, col);
    if (!fieldSlot || fieldSlot->type != FIELD_TYPE_INTEGER) {
        return false;
    }
    
#if WINDOW_STORAGE_INLINE_NUMERICS
    *valueOut = fieldSlot->data.l;
#else
    *valueOut = copyOutLong(fieldSlot->data.buffer.offset);
#endif
    return true;
}

bool CursorWindow::getDouble(unsigned int row, unsigned int col, double * valueOut)
{
    field_slot_t * fieldSlot = getFieldSlotWithCheck(row, col);
    if (!fieldSlot || fieldSlot->type != FIELD_TYPE_FLOAT) {
        return false;
    }

#if WINDOW_STORAGE_INLINE_NUMERICS
    *valueOut = fieldSlot->data.d;
#else
    *valueOut = copyOutDouble(fieldSlot->data.buffer.offset);
#endif
    return true;
}

bool CursorWindow::getNull(unsigned int row, unsigned int col, bool * valueOut)
{
    field_slot_t * fieldSlot = getFieldSlotWithCheck(row, col);
    if (!fieldSlot) {
        return false;
    }
    
    if (fieldSlot->type != FIELD_TYPE_NULL) {
        *valueOut = false;
    } else {
        *valueOut = true;
    }
    return true;
}

}; // namespace android
