/*
 * 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();

    LOG(DEBUG) << "Created: " << window->toString();
    *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.string(), 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 = mSize - mSlotsOffset;
        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, with just enough padding
        // to ensure our slots stay aligned
        size_t slotsSize = mSize - mSlotsOffset;
        size_t compactedSize = mAllocOffset + slotsSize;
        compactedSize = (compactedSize + 3) & ~3;
        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
