/*
 * 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 "FileBackupHelper_native"
#include <utils/Log.h>

#include <nativehelper/JNIHelp.h>
#include "core_jni_helpers.h"

#include <androidfw/BackupHelpers.h>

namespace android
{

static jlong
ctor_native(JNIEnv* env, jobject clazz, jobject fileDescriptor)
{
    int fd = jniGetFDFromFileDescriptor(env, fileDescriptor);
    if (fd == -1) {
        return (jlong)NULL;
    }

    return (jlong)new BackupDataWriter(fd);
}

static void
dtor_native(JNIEnv* env, jobject clazz, jlong w)
{
    delete (BackupDataWriter*)w;
}

static jint
writeEntityHeader_native(JNIEnv* env, jobject clazz, jlong w, jstring key, jint dataSize)
{
    int err;
    BackupDataWriter* writer = (BackupDataWriter*)w;

    const char* keyUTF = env->GetStringUTFChars(key, NULL);
    if (keyUTF == NULL) {
        return -1;
    }
    err = writer->WriteEntityHeader(String8(keyUTF), dataSize);

    env->ReleaseStringUTFChars(key, keyUTF);

    return (jint)err;
}

static jint
writeEntityData_native(JNIEnv* env, jobject clazz, jlong w, jbyteArray data, jint size)
{
    int err;
    BackupDataWriter* writer = (BackupDataWriter*)w;

    if (env->GetArrayLength(data) < size) {
        // size mismatch
        return -1;
    }

    jbyte* dataBytes = env->GetByteArrayElements(data, NULL);
    if (dataBytes == NULL) {
        return -1;
    }

    err = writer->WriteEntityData(dataBytes, size);

    env->ReleaseByteArrayElements(data, dataBytes, JNI_ABORT);

    return (jint)err;
}

static void
setKeyPrefix_native(JNIEnv* env, jobject clazz, jlong w, jstring keyPrefixObj)
{
    BackupDataWriter* writer = (BackupDataWriter*)w;

    const char* keyPrefixUTF = env->GetStringUTFChars(keyPrefixObj, NULL);
    String8 keyPrefix(keyPrefixUTF ? keyPrefixUTF : "");

    writer->SetKeyPrefix(keyPrefix);

    env->ReleaseStringUTFChars(keyPrefixObj, keyPrefixUTF);
}

static const JNINativeMethod g_methods[] = {
    { "ctor", "(Ljava/io/FileDescriptor;)J", (void*)ctor_native },
    { "dtor", "(J)V", (void*)dtor_native },
    { "writeEntityHeader_native", "(JLjava/lang/String;I)I", (void*)writeEntityHeader_native },
    { "writeEntityData_native", "(J[BI)I", (void*)writeEntityData_native },
    { "setKeyPrefix_native", "(JLjava/lang/String;)V", (void*)setKeyPrefix_native },
};

int register_android_backup_BackupDataOutput(JNIEnv* env)
{
    //ALOGD("register_android_backup_BackupDataOutput");
    return RegisterMethodsOrDie(env, "android/app/backup/BackupDataOutput",
            g_methods, NELEM(g_methods));
}

}
