/*
 * Copyright (C) 2009 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 "BackupHelperDispatcher_native"
#include <utils/Log.h>

#include <nativehelper/JNIPlatformHelp.h>
#include <android_runtime/AndroidRuntime.h>

#include <sys/types.h>
#include <sys/uio.h>
#include <unistd.h>

#include "core_jni_helpers.h"

#define VERSION_1_HEADER 0x01706c48  // 'Hlp'1 little endian

namespace android
{

struct chunk_header_v1 {
    int headerSize;
    int version;
    int dataSize; // corresponds to Header.chunkSize
    int nameLength; // not including the NULL terminator, which is not written to the file
};

static jfieldID s_chunkSizeField = 0;
static jfieldID s_keyPrefixField = 0;

static jint
readHeader_native(JNIEnv* env, jobject clazz, jobject headerObj, jobject fdObj)
{
    chunk_header_v1 flattenedHeader;
    ssize_t amt;
    String8 keyPrefix;
    char* buf;

    int fd = jniGetFDFromFileDescriptor(env, fdObj);

    amt = read(fd, &flattenedHeader.headerSize, sizeof(flattenedHeader.headerSize));
    if (amt != sizeof(flattenedHeader.headerSize)) {
        return (jint) -1;
    }

    int remainingHeader = flattenedHeader.headerSize - sizeof(flattenedHeader.headerSize);

    if (flattenedHeader.headerSize < (int)sizeof(chunk_header_v1)) {
        ALOGW("Skipping unknown header: %d bytes", flattenedHeader.headerSize);
        if (remainingHeader > 0) {
            lseek(fd, remainingHeader, SEEK_CUR);
            // >0 means skip this chunk
            return (jint) 1;
        }
    }

    amt = read(fd, &flattenedHeader.version,
            sizeof(chunk_header_v1)-sizeof(flattenedHeader.headerSize));
    if (amt <= 0) {
        ALOGW("Failed reading chunk header");
        return (jint) -1;
    }
    remainingHeader -= sizeof(chunk_header_v1)-sizeof(flattenedHeader.headerSize);

    if (flattenedHeader.version != VERSION_1_HEADER) {
        ALOGW("Skipping unknown header version: 0x%08x, %d bytes", flattenedHeader.version,
                flattenedHeader.headerSize);
        if (remainingHeader > 0) {
            lseek(fd, remainingHeader, SEEK_CUR);
            // >0 means skip this chunk
            return (jint) 1;
        }
    }

#if 0
    ALOGD("chunk header:");
    ALOGD("  headerSize=%d", flattenedHeader.headerSize);
    ALOGD("  version=0x%08x", flattenedHeader.version);
    ALOGD("  dataSize=%d", flattenedHeader.dataSize);
    ALOGD("  nameLength=%d", flattenedHeader.nameLength);
#endif

    if (flattenedHeader.dataSize < 0 || flattenedHeader.nameLength < 0 ||
            remainingHeader < flattenedHeader.nameLength) {
        ALOGW("Malformed V1 header remainingHeader=%d dataSize=%d nameLength=%d", remainingHeader,
                flattenedHeader.dataSize, flattenedHeader.nameLength);
        return (jint) -1;
    }

    buf = keyPrefix.lockBuffer(flattenedHeader.nameLength);
    if (buf == NULL) {
        ALOGW("unable to allocate %d bytes", flattenedHeader.nameLength);
        return (jint) -1;
    }

    amt = read(fd, buf, flattenedHeader.nameLength);
    buf[flattenedHeader.nameLength] = 0;

    keyPrefix.unlockBuffer(flattenedHeader.nameLength);

    remainingHeader -= flattenedHeader.nameLength;

    if (remainingHeader > 0) {
        lseek(fd, remainingHeader, SEEK_CUR);
    }

    env->SetIntField(headerObj, s_chunkSizeField, flattenedHeader.dataSize);
    env->SetObjectField(headerObj, s_keyPrefixField, env->NewStringUTF(keyPrefix.string()));

    return (jint) 0;
}

static jint
skipChunk_native(JNIEnv* env, jobject clazz, jobject fdObj, jint bytesToSkip)
{
    int fd = jniGetFDFromFileDescriptor(env, fdObj);

    lseek(fd, bytesToSkip, SEEK_CUR);

    return (jint) 0;
}

static int
padding_len(int len)
{
    len = len % 4;
    return len == 0 ? len : 4 - len;
}

static jint
allocateHeader_native(JNIEnv* env, jobject clazz, jobject headerObj, jobject fdObj)
{
    int pos;
    jstring nameObj;
    int nameLength;
    int namePadding;
    int headerSize;

    int fd = jniGetFDFromFileDescriptor(env, fdObj);

    nameObj = (jstring)env->GetObjectField(headerObj, s_keyPrefixField);

    nameLength = env->GetStringUTFLength(nameObj);
    namePadding = padding_len(nameLength);

    headerSize = sizeof(chunk_header_v1) + nameLength + namePadding;

    pos = lseek(fd, 0, SEEK_CUR);

    lseek(fd, headerSize, SEEK_CUR);

    return (jint) pos;
}

static jint
writeHeader_native(JNIEnv* env, jobject clazz, jobject headerObj, jobject fdObj, jint pos)
{
    int err;
    chunk_header_v1 header;
    int namePadding;
    int prevPos;
    jstring nameObj;
    const char* buf;

    int fd = jniGetFDFromFileDescriptor(env, fdObj);
    prevPos = lseek(fd, 0, SEEK_CUR);

    nameObj = (jstring)env->GetObjectField(headerObj, s_keyPrefixField);
    header.nameLength = env->GetStringUTFLength(nameObj);
    namePadding = padding_len(header.nameLength);

    header.headerSize = sizeof(chunk_header_v1) + header.nameLength + namePadding;
    header.version = VERSION_1_HEADER;
    header.dataSize = prevPos - (pos + header.headerSize);

    lseek(fd, pos, SEEK_SET);
    err = write(fd, &header, sizeof(chunk_header_v1));
    if (err != sizeof(chunk_header_v1)) {
        return (jint) errno;
    }

    buf = env->GetStringUTFChars(nameObj, NULL);
    err = write(fd, buf, header.nameLength);
    env->ReleaseStringUTFChars(nameObj, buf);
    if (err != header.nameLength) {
        return (jint) errno;
    }

    if (namePadding != 0) {
        int zero = 0;
        err = write(fd, &zero, namePadding);
        if (err != namePadding) {
            return (jint) errno;
        }
    }

    lseek(fd, prevPos, SEEK_SET);
    return (jint) 0;
}

static const JNINativeMethod g_methods[] = {
    { "readHeader_native",
       "(Landroid/app/backup/BackupHelperDispatcher$Header;Ljava/io/FileDescriptor;)I",
       (void*)readHeader_native },
    { "skipChunk_native",
        "(Ljava/io/FileDescriptor;I)I",
        (void*)skipChunk_native },
    { "allocateHeader_native",
        "(Landroid/app/backup/BackupHelperDispatcher$Header;Ljava/io/FileDescriptor;)I",
        (void*)allocateHeader_native },
    { "writeHeader_native",
       "(Landroid/app/backup/BackupHelperDispatcher$Header;Ljava/io/FileDescriptor;I)I",
       (void*)writeHeader_native },
};

int register_android_backup_BackupHelperDispatcher(JNIEnv* env)
{
    jclass clazz = FindClassOrDie(env, "android/app/backup/BackupHelperDispatcher$Header");
    s_chunkSizeField = GetFieldIDOrDie(env, clazz, "chunkSize", "I");
    s_keyPrefixField = GetFieldIDOrDie(env, clazz, "keyPrefix", "Ljava/lang/String;");

    return RegisterMethodsOrDie(env, "android/app/backup/BackupHelperDispatcher", g_methods,
                                NELEM(g_methods));
}

}
