/*
 * Copyright (C) 2014 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 "BitmapSerializeUtils"

#include <jni.h>
#include <nativehelper/JNIHelp.h>

#include <android/bitmap.h>
#include <android/log.h>

namespace android {

#define RGBA_8888_COLOR_DEPTH 4

static bool writeAllBytes(const int fd, void* buffer, const size_t byteCount) {
    char* writeBuffer = static_cast<char*>(buffer);
    size_t remainingBytes = byteCount;
    while (remainingBytes > 0) {
        ssize_t writtenByteCount = write(fd, writeBuffer, remainingBytes);
        if (writtenByteCount == -1) {
            if (errno == EINTR) {
                continue;
            }
            __android_log_print(ANDROID_LOG_ERROR, LOG_TAG,
                    "Error writing to buffer: %d", errno);
            return false;
        }
        remainingBytes -= writtenByteCount;
        writeBuffer += writtenByteCount;
    }
    return true;
}

static bool readAllBytes(const int fd, void* buffer, const size_t byteCount) {
    char* readBuffer = static_cast<char*>(buffer);
    size_t remainingBytes = byteCount;
    while (remainingBytes > 0) {
        ssize_t readByteCount = read(fd, readBuffer, remainingBytes);

        remainingBytes -= readByteCount;
        readBuffer += readByteCount;

        if (readByteCount == -1) {
            if (errno == EINTR) {
                continue;
            }
            __android_log_print(ANDROID_LOG_ERROR, LOG_TAG,
                    "Error reading from buffer: %d", errno);
            return false;
        } else if (readByteCount == 0 && remainingBytes > 0) {
            __android_log_print(ANDROID_LOG_ERROR, LOG_TAG,
                    "File closed before all bytes were read. %zu/%zu remaining", remainingBytes,
                    byteCount);
            return false;
        }
    }
    return true;
}

static void throwException(JNIEnv* env, const char* className, const char* message) {
    jclass exceptionClass = env->FindClass(className);
    env->ThrowNew(exceptionClass, message);
}

static void throwIllegalStateException(JNIEnv* env, char *message) {
    const char* className = "java/lang/IllegalStateException";
    throwException(env, className, message);
}

static void throwIllegalArgumentException(JNIEnv* env, char* message) {
    const char* className = "java/lang/IllegalArgumentException";
    throwException(env, className, message);
}

static void readBitmapPixels(JNIEnv* env, jclass /* clazz */, jobject jbitmap, jint fd) {
    // Read the info.
    AndroidBitmapInfo readInfo;
    bool read = readAllBytes(fd, (void*) &readInfo, sizeof(AndroidBitmapInfo));
    if (!read) {
        throwIllegalStateException(env, (char*) "Cannot read bitmap info");
        return;
    }

    // Get the info of the target bitmap.
    AndroidBitmapInfo targetInfo;
    int result = AndroidBitmap_getInfo(env, jbitmap, &targetInfo);
    if (result < 0) {
        throwIllegalStateException(env, (char*) "Cannot get bitmap info");
        return;
    }

    // Enforce we can reuse the bitmap.
    if (readInfo.width != targetInfo.width || readInfo.height != targetInfo.height
            || readInfo.stride != targetInfo.stride || readInfo.format != targetInfo.format
            || readInfo.flags != targetInfo.flags) {
        throwIllegalArgumentException(env, (char*) "Cannot reuse bitmap");
        return;
    }

    // Lock the pixels.
    void* pixels;
    result = AndroidBitmap_lockPixels(env, jbitmap, &pixels);
    if (result < 0) {
        throwIllegalStateException(env, (char*) "Cannot lock bitmap pixels");
        return;
    }

    // Read the pixels.
    size_t byteCount = readInfo.stride * readInfo.height;
    read = readAllBytes(fd, (void*) pixels, byteCount);
    if (!read) {
        throwIllegalStateException(env, (char*) "Cannot read bitmap pixels");
        return;
    }

    // Unlock the pixels.
    result = AndroidBitmap_unlockPixels(env, jbitmap);
    if (result < 0) {
        throwIllegalStateException(env, (char*) "Cannot unlock bitmap pixels");
    }
}

static void writeBitmapPixels(JNIEnv* env, jclass /* clazz */, jobject jbitmap, jint fd) {
    // Get the info.
    AndroidBitmapInfo info;
    int result = AndroidBitmap_getInfo(env, jbitmap, &info);
    if (result < 0) {
        throwIllegalStateException(env, (char*) "Cannot get bitmap info");
        return;
    }

    // Write the info.
    bool written = writeAllBytes(fd, (void*) &info, sizeof(AndroidBitmapInfo));
    if (!written) {
        throwIllegalStateException(env, (char*) "Cannot write bitmap info");
        return;
    }

    // Lock the pixels.
    void* pixels;
    result = AndroidBitmap_lockPixels(env, jbitmap, &pixels);
    if (result < 0) {
        throwIllegalStateException(env, (char*) "Cannot lock bitmap pixels");
        return;
    }

    // Write the pixels.
    size_t byteCount = info.stride * info.height;
    written = writeAllBytes(fd, (void*) pixels, byteCount);
    if (!written) {
        throwIllegalStateException(env, (char*) "Cannot write bitmap pixels");
        return;
    }

    // Unlock the pixels.
    result = AndroidBitmap_unlockPixels(env, jbitmap);
    if (result < 0) {
        throwIllegalStateException(env, (char*) "Cannot unlock bitmap pixels");
    }
}

static const JNINativeMethod sMethods[] = {
    {"nativeReadBitmapPixels", "(Landroid/graphics/Bitmap;I)V", (void *) readBitmapPixels},
    {"nativeWriteBitmapPixels", "(Landroid/graphics/Bitmap;I)V", (void *) writeBitmapPixels},
};

int register_com_android_printspooler_util_BitmapSerializeUtils(JNIEnv* env) {
    return jniRegisterNativeMethods(env, "com/android/printspooler/util/BitmapSerializeUtils",
        sMethods, NELEM(sMethods));
}

}

jint JNI_OnLoad(JavaVM* jvm, void*) {
    JNIEnv *env = NULL;
    if (jvm->GetEnv((void**) &env, JNI_VERSION_1_6)) {
        return JNI_ERR;
    }

    if (android::register_com_android_printspooler_util_BitmapSerializeUtils(env) == -1) {
        return JNI_ERR;
    }

    return JNI_VERSION_1_6;
}
