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

#define LOG_TAG "CursorWindow"

#include <androidfw/CursorWindow.h>

#include <sys/mman.h>

#include "android-base/logging.h"
#include "cutils/ashmem.h"

namespace android {

/**
 * By default windows are lightweight inline allocations of this size;
 * they're only inflated to ashmem regions when more space is needed.
 */
static constexpr const size_t kInlineSize = 16384;

static constexpr const size_t kSlotShift = 4;
static constexpr const size_t kSlotSizeBytes = 1 << kSlotShift;

CursorWindow::CursorWindow() {
}

CursorWindow::~CursorWindow() {
    if (mAshmemFd != -1) {
        ::munmap(mData, mSize);
        ::close(mAshmemFd);
    } else {
        free(mData);
    }
}

status_t CursorWindow::create(const String8 &name, size_t inflatedSize, CursorWindow **outWindow) {
    *outWindow = nullptr;

    CursorWindow* window = new CursorWindow();
    if (!window) goto fail;

    window->mName = name;
    window->mSize = std::min(kInlineSize, inflatedSize);
    window->mInflatedSize = inflatedSize;
    window->mData = malloc(window->mSize);
    if (!window->mData) goto fail;
    window->mReadOnly = false;

    window->clear();
    window->updateSlotsData();

    *outWindow = window;
    return OK;

fail:
    LOG(ERROR) << "Failed create";
fail_silent:
    delete window;
    return UNKNOWN_ERROR;
}

status_t CursorWindow::maybeInflate() {
    int ashmemFd = 0;
    void* newData = nullptr;

    // Bail early when we can't expand any further
    if (mReadOnly || mSize == mInflatedSize) {
        return INVALID_OPERATION;
    }

    String8 ashmemName("CursorWindow: ");
    ashmemName.append(mName);

    ashmemFd = ashmem_create_region(ashmemName.c_str(), mInflatedSize);
    if (ashmemFd < 0) {
        PLOG(ERROR) << "Failed ashmem_create_region";
        goto fail_silent;
    }

    if (ashmem_set_prot_region(ashmemFd, PROT_READ | PROT_WRITE) < 0) {
        PLOG(ERROR) << "Failed ashmem_set_prot_region";
        goto fail_silent;
    }

    newData = ::mmap(nullptr, mInflatedSize, PROT_READ | PROT_WRITE, MAP_SHARED, ashmemFd, 0);
    if (newData == MAP_FAILED) {
        PLOG(ERROR) << "Failed mmap";
        goto fail_silent;
    }

    if (ashmem_set_prot_region(ashmemFd, PROT_READ) < 0) {
        PLOG(ERROR) << "Failed ashmem_set_prot_region";
        goto fail_silent;
    }

    {
        // Migrate existing contents into new ashmem region
        uint32_t slotsSize = sizeOfSlots();
        uint32_t newSlotsOffset = mInflatedSize - slotsSize;
        memcpy(static_cast<uint8_t*>(newData),
                static_cast<uint8_t*>(mData), mAllocOffset);
        memcpy(static_cast<uint8_t*>(newData) + newSlotsOffset,
                static_cast<uint8_t*>(mData) + mSlotsOffset, slotsSize);

        free(mData);
        mAshmemFd = ashmemFd;
        mData = newData;
        mSize = mInflatedSize;
        mSlotsOffset = newSlotsOffset;

        updateSlotsData();
    }

    LOG(DEBUG) << "Inflated: " << this->toString();
    return OK;

fail:
    LOG(ERROR) << "Failed maybeInflate";
fail_silent:
    ::munmap(newData, mInflatedSize);
    ::close(ashmemFd);
    return UNKNOWN_ERROR;
}

status_t CursorWindow::createFromParcel(Parcel* parcel, CursorWindow** outWindow) {
    *outWindow = nullptr;

    CursorWindow* window = new CursorWindow();
    if (!window) goto fail;

    if (parcel->readString8(&window->mName)) goto fail;
    if (parcel->readUint32(&window->mNumRows)) goto fail;
    if (parcel->readUint32(&window->mNumColumns)) goto fail;
    if (parcel->readUint32(&window->mSize)) goto fail;

    if ((window->mNumRows * window->mNumColumns * kSlotSizeBytes) > window->mSize) {
        LOG(ERROR) << "Unexpected size " << window->mSize << " for " << window->mNumRows
                << " rows and " << window->mNumColumns << " columns";
        goto fail_silent;
    }

    bool isAshmem;
    if (parcel->readBool(&isAshmem)) goto fail;
    if (isAshmem) {
        window->mAshmemFd = parcel->readFileDescriptor();
        if (window->mAshmemFd < 0) {
            LOG(ERROR) << "Failed readFileDescriptor";
            goto fail_silent;
        }

        window->mAshmemFd = ::fcntl(window->mAshmemFd, F_DUPFD_CLOEXEC, 0);
        if (window->mAshmemFd < 0) {
            PLOG(ERROR) << "Failed F_DUPFD_CLOEXEC";
            goto fail_silent;
        }

        window->mData = ::mmap(nullptr, window->mSize, PROT_READ, MAP_SHARED, window->mAshmemFd, 0);
        if (window->mData == MAP_FAILED) {
            PLOG(ERROR) << "Failed mmap";
            goto fail_silent;
        }
    } else {
        window->mAshmemFd = -1;

        if (window->mSize > kInlineSize) {
            LOG(ERROR) << "Unexpected size " << window->mSize << " for inline window";
            goto fail_silent;
        }

        window->mData = malloc(window->mSize);
        if (!window->mData) goto fail;

        if (parcel->read(window->mData, window->mSize)) goto fail;
    }

    // We just came from a remote source, so we're read-only
    // and we can't inflate ourselves
    window->mInflatedSize = window->mSize;
    window->mReadOnly = true;

    window->updateSlotsData();

    LOG(DEBUG) << "Created from parcel: " << window->toString();
    *outWindow = window;
    return OK;

fail:
    LOG(ERROR) << "Failed createFromParcel";
fail_silent:
    delete window;
    return UNKNOWN_ERROR;
}

status_t CursorWindow::writeToParcel(Parcel* parcel) {
    LOG(DEBUG) << "Writing to parcel: " << this->toString();

    if (parcel->writeString8(mName)) goto fail;
    if (parcel->writeUint32(mNumRows)) goto fail;
    if (parcel->writeUint32(mNumColumns)) goto fail;
    if (mAshmemFd != -1) {
        if (parcel->writeUint32(mSize)) goto fail;
        if (parcel->writeBool(true)) goto fail;
        if (parcel->writeDupFileDescriptor(mAshmemFd)) goto fail;
    } else {
        // Since we know we're going to be read-only on the remote side,
        // we can compact ourselves on the wire.
        size_t slotsSize = sizeOfSlots();
        size_t compactedSize = sizeInUse();
        if (parcel->writeUint32(compactedSize)) goto fail;
        if (parcel->writeBool(false)) goto fail;
        void* dest = parcel->writeInplace(compactedSize);
        if (!dest) goto fail;
        memcpy(static_cast<uint8_t*>(dest),
                static_cast<uint8_t*>(mData), mAllocOffset);
        memcpy(static_cast<uint8_t*>(dest) + compactedSize - slotsSize,
                static_cast<uint8_t*>(mData) + mSlotsOffset, slotsSize);
    }
    return OK;

fail:
    LOG(ERROR) << "Failed writeToParcel";
fail_silent:
    return UNKNOWN_ERROR;
}

status_t CursorWindow::clear() {
    if (mReadOnly) {
        return INVALID_OPERATION;
    }
    mAllocOffset = 0;
    mSlotsOffset = mSize;
    mNumRows = 0;
    mNumColumns = 0;
    return OK;
}

void CursorWindow::updateSlotsData() {
    mSlotsStart = static_cast<uint8_t*>(mData) + mSize - kSlotSizeBytes;
    mSlotsEnd = static_cast<uint8_t*>(mData) + mSlotsOffset;
}

void* CursorWindow::offsetToPtr(uint32_t offset, uint32_t bufferSize = 0) {
    if (offset > mSize) {
        LOG(ERROR) << "Offset " << offset
                << " out of bounds, max value " << mSize;
        return nullptr;
    }
    if (offset + bufferSize > mSize) {
        LOG(ERROR) << "End offset " << (offset + bufferSize)
                << " out of bounds, max value " << mSize;
        return nullptr;
    }
    return static_cast<uint8_t*>(mData) + offset;
}

uint32_t CursorWindow::offsetFromPtr(void* ptr) {
    return static_cast<uint8_t*>(ptr) - static_cast<uint8_t*>(mData);
}

status_t CursorWindow::setNumColumns(uint32_t numColumns) {
    if (mReadOnly) {
        return INVALID_OPERATION;
    }
    uint32_t cur = mNumColumns;
    if ((cur > 0 || mNumRows > 0) && cur != numColumns) {
        LOG(ERROR) << "Trying to go from " << cur << " columns to " << numColumns;
        return INVALID_OPERATION;
    }
    mNumColumns = numColumns;
    return OK;
}

status_t CursorWindow::allocRow() {
    if (mReadOnly) {
        return INVALID_OPERATION;
    }
    size_t size = mNumColumns * kSlotSizeBytes;
    int32_t newOffset = mSlotsOffset - size;
    if (newOffset < (int32_t) mAllocOffset) {
        maybeInflate();
        newOffset = mSlotsOffset - size;
        if (newOffset < (int32_t) mAllocOffset) {
            return NO_MEMORY;
        }
    }
    memset(offsetToPtr(newOffset), 0, size);
    mSlotsOffset = newOffset;
    updateSlotsData();
    mNumRows++;
    return OK;
}

status_t CursorWindow::freeLastRow() {
    if (mReadOnly) {
        return INVALID_OPERATION;
    }
    size_t size = mNumColumns * kSlotSizeBytes;
    size_t newOffset = mSlotsOffset + size;
    if (newOffset > mSize) {
        return NO_MEMORY;
    }
    mSlotsOffset = newOffset;
    updateSlotsData();
    mNumRows--;
    return OK;
}

status_t CursorWindow::alloc(size_t size, uint32_t* outOffset) {
    if (mReadOnly) {
        return INVALID_OPERATION;
    }
    size_t alignedSize = (size + 3) & ~3;
    size_t newOffset = mAllocOffset + alignedSize;
    if (newOffset > mSlotsOffset) {
        maybeInflate();
        newOffset = mAllocOffset + alignedSize;
        if (newOffset > mSlotsOffset) {
            return NO_MEMORY;
        }
    }
    *outOffset = mAllocOffset;
    mAllocOffset = newOffset;
    return OK;
}

CursorWindow::FieldSlot* CursorWindow::getFieldSlot(uint32_t row, uint32_t column) {
    // This is carefully tuned to use as few cycles as
    // possible, since this is an extremely hot code path;
    // see CursorWindow_bench.cpp for more details
    void *result = static_cast<uint8_t*>(mSlotsStart)
            - (((row * mNumColumns) + column) << kSlotShift);
    if (result < mSlotsEnd || result > mSlotsStart || column >= mNumColumns) {
        LOG(ERROR) << "Failed to read row " << row << ", column " << column
                << " from a window with " << mNumRows << " rows, " << mNumColumns << " columns";
        return nullptr;
    } else {
        return static_cast<FieldSlot*>(result);
    }
}

status_t CursorWindow::putBlob(uint32_t row, uint32_t column, const void* value, size_t size) {
    return putBlobOrString(row, column, value, size, FIELD_TYPE_BLOB);
}

status_t CursorWindow::putString(uint32_t row, uint32_t column, const char* value,
        size_t sizeIncludingNull) {
    return putBlobOrString(row, column, value, sizeIncludingNull, FIELD_TYPE_STRING);
}

status_t CursorWindow::putBlobOrString(uint32_t row, uint32_t column,
        const void* value, size_t size, int32_t type) {
    if (mReadOnly) {
        return INVALID_OPERATION;
    }

    FieldSlot* fieldSlot = getFieldSlot(row, column);
    if (!fieldSlot) {
        return BAD_VALUE;
    }

    uint32_t offset;
    if (alloc(size, &offset)) {
        return NO_MEMORY;
    }

    memcpy(offsetToPtr(offset), value, size);

    fieldSlot = getFieldSlot(row, column);
    fieldSlot->type = type;
    fieldSlot->data.buffer.offset = offset;
    fieldSlot->data.buffer.size = size;
    return OK;
}

status_t CursorWindow::putLong(uint32_t row, uint32_t column, int64_t value) {
    if (mReadOnly) {
        return INVALID_OPERATION;
    }

    FieldSlot* fieldSlot = getFieldSlot(row, column);
    if (!fieldSlot) {
        return BAD_VALUE;
    }

    fieldSlot->type = FIELD_TYPE_INTEGER;
    fieldSlot->data.l = value;
    return OK;
}

status_t CursorWindow::putDouble(uint32_t row, uint32_t column, double value) {
    if (mReadOnly) {
        return INVALID_OPERATION;
    }

    FieldSlot* fieldSlot = getFieldSlot(row, column);
    if (!fieldSlot) {
        return BAD_VALUE;
    }

    fieldSlot->type = FIELD_TYPE_FLOAT;
    fieldSlot->data.d = value;
    return OK;
}

status_t CursorWindow::putNull(uint32_t row, uint32_t column) {
    if (mReadOnly) {
        return INVALID_OPERATION;
    }

    FieldSlot* fieldSlot = getFieldSlot(row, column);
    if (!fieldSlot) {
        return BAD_VALUE;
    }

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

}; // namespace android
