/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you 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.
 */

#include <config.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <dlfcn.h>

#include "org_apache_hadoop_io_compress_bzip2.h"
#include "org_apache_hadoop_io_compress_bzip2_Bzip2Decompressor.h"

static jfieldID Bzip2Decompressor_clazz;
static jfieldID Bzip2Decompressor_stream;
static jfieldID Bzip2Decompressor_compressedDirectBuf;
static jfieldID Bzip2Decompressor_compressedDirectBufOff;
static jfieldID Bzip2Decompressor_compressedDirectBufLen;
static jfieldID Bzip2Decompressor_uncompressedDirectBuf;
static jfieldID Bzip2Decompressor_directBufferSize;
static jfieldID Bzip2Decompressor_finished;

static int (*dlsym_BZ2_bzDecompressInit)(bz_stream*, int, int);
static int (*dlsym_BZ2_bzDecompress)(bz_stream*);
static int (*dlsym_BZ2_bzDecompressEnd)(bz_stream*);

JNIEXPORT void JNICALL
Java_org_apache_hadoop_io_compress_bzip2_Bzip2Decompressor_initIDs(
                                 JNIEnv *env, jclass class, jstring libname)
{
    const char* bzlib_name = (*env)->GetStringUTFChars(env, libname, NULL);
    if (strcmp(bzlib_name, "system-native") == 0)
      bzlib_name = HADOOP_BZIP2_LIBRARY;
    // Load the native library.
    void *libbz2 = dlopen(bzlib_name, RTLD_LAZY | RTLD_GLOBAL);
    if (!libbz2) {
        THROW(env, "java/lang/UnsatisfiedLinkError",
              "Cannot load bzip2 native library");
        return;
    }

    // Locate the requisite symbols from libbz2.so.
    dlerror();                                 // Clear any existing error.
    LOAD_DYNAMIC_SYMBOL(dlsym_BZ2_bzDecompressInit, env, libbz2,
                        "BZ2_bzDecompressInit");
    LOAD_DYNAMIC_SYMBOL(dlsym_BZ2_bzDecompress, env, libbz2,
                        "BZ2_bzDecompress");
    LOAD_DYNAMIC_SYMBOL(dlsym_BZ2_bzDecompressEnd, env, libbz2,
                        "BZ2_bzDecompressEnd");

    // Initialize the requisite fieldIds.
    Bzip2Decompressor_clazz = (*env)->GetStaticFieldID(env, class, "clazz", 
                                                       "Ljava/lang/Class;");
    Bzip2Decompressor_stream = (*env)->GetFieldID(env, class, "stream", "J");
    Bzip2Decompressor_finished = (*env)->GetFieldID(env, class,
                                                    "finished", "Z");
    Bzip2Decompressor_compressedDirectBuf = (*env)->GetFieldID(env, class, 
                                                        "compressedDirectBuf", 
                                                        "Ljava/nio/Buffer;");
    Bzip2Decompressor_compressedDirectBufOff = (*env)->GetFieldID(env, class, 
                                                "compressedDirectBufOff", "I");
    Bzip2Decompressor_compressedDirectBufLen = (*env)->GetFieldID(env, class, 
                                                "compressedDirectBufLen", "I");
    Bzip2Decompressor_uncompressedDirectBuf = (*env)->GetFieldID(env, class, 
                                                "uncompressedDirectBuf", 
                                                "Ljava/nio/Buffer;");
    Bzip2Decompressor_directBufferSize = (*env)->GetFieldID(env, class, 
                                                "directBufferSize", "I");
}

JNIEXPORT jlong JNICALL
Java_org_apache_hadoop_io_compress_bzip2_Bzip2Decompressor_init(
                                JNIEnv *env, jclass cls, jint conserveMemory)
{
    bz_stream *stream = malloc(sizeof(bz_stream));
    if (stream == 0) {
        THROW(env, "java/lang/OutOfMemoryError", NULL);
        return (jlong)0;
    } 
    memset((void*)stream, 0, sizeof(bz_stream));
    
    int rv = dlsym_BZ2_bzDecompressInit(stream, 0, conserveMemory);

    if (rv != BZ_OK) {
        // Contingency - Report error by throwing appropriate exceptions.
        free(stream);
        stream = NULL;

        switch (rv) {
        case BZ_MEM_ERROR:
            {
                THROW(env, "java/lang/OutOfMemoryError", NULL);
            }
            break;
        default:
            {
                THROW(env, "java/lang/InternalError", NULL);
            }
            break;
        }
    }

    return JLONG(stream);
}

JNIEXPORT jint JNICALL
Java_org_apache_hadoop_io_compress_bzip2_Bzip2Decompressor_inflateBytesDirect(
                        JNIEnv *env, jobject this)
{
    // Get members of Bzip2Decompressor.
    bz_stream *stream = BZSTREAM((*env)->GetLongField(env, this,
                                                Bzip2Decompressor_stream));
    if (!stream) {
        THROW(env, "java/lang/NullPointerException", NULL);
        return (jint)0;
    } 

    jobject clazz = (*env)->GetStaticObjectField(env, this, 
                                                 Bzip2Decompressor_clazz);
    jarray compressed_direct_buf = (jarray)(*env)->GetObjectField(env,
                                this, Bzip2Decompressor_compressedDirectBuf);
    jint compressed_direct_buf_off = (*env)->GetIntField(env, this, 
                                Bzip2Decompressor_compressedDirectBufOff);
    jint compressed_direct_buf_len = (*env)->GetIntField(env, this, 
                                Bzip2Decompressor_compressedDirectBufLen);

    jarray uncompressed_direct_buf = (jarray)(*env)->GetObjectField(env,
                                this, Bzip2Decompressor_uncompressedDirectBuf);
    jint uncompressed_direct_buf_len = (*env)->GetIntField(env, this, 
                                Bzip2Decompressor_directBufferSize);

    // Get the input and output direct buffers.
    LOCK_CLASS(env, clazz, "Bzip2Decompressor");
    char* compressed_bytes = (*env)->GetDirectBufferAddress(env, 
                                                compressed_direct_buf);
    char* uncompressed_bytes = (*env)->GetDirectBufferAddress(env, 
                                                uncompressed_direct_buf);
    UNLOCK_CLASS(env, clazz, "Bzip2Decompressor");

    if (!compressed_bytes || !uncompressed_bytes) {
        return (jint)0;
    }
        
    // Re-calibrate the bz_stream.
    stream->next_in  = compressed_bytes + compressed_direct_buf_off;
    stream->avail_in  = compressed_direct_buf_len;
    stream->next_out = uncompressed_bytes;
    stream->avail_out = uncompressed_direct_buf_len;
        
    // Decompress.
    int rv = dlsym_BZ2_bzDecompress(stream);

    // Contingency? - Report error by throwing appropriate exceptions.
    int no_decompressed_bytes = 0;      
    switch (rv) {
    case BZ_STREAM_END:
        {
            (*env)->SetBooleanField(env, this,
                                    Bzip2Decompressor_finished,
                                    JNI_TRUE);
        } // cascade down
    case BZ_OK:
        {
            compressed_direct_buf_off +=
                compressed_direct_buf_len - stream->avail_in;
            (*env)->SetIntField(env, this,
                                Bzip2Decompressor_compressedDirectBufOff, 
                                compressed_direct_buf_off);
            (*env)->SetIntField(env, this,
                                Bzip2Decompressor_compressedDirectBufLen, 
                                stream->avail_in);
            no_decompressed_bytes =
                uncompressed_direct_buf_len - stream->avail_out;
        }
        break;
    case BZ_DATA_ERROR:
    case BZ_DATA_ERROR_MAGIC:
        {
            THROW(env, "java/io/IOException", NULL);
        }
        break;
    case BZ_MEM_ERROR:
        {
            THROW(env, "java/lang/OutOfMemoryError", NULL);
        }
        break;
    default:
        {
            THROW(env, "java/lang/InternalError", NULL);
        }
        break;
    }
    
    return no_decompressed_bytes;
}

JNIEXPORT jlong JNICALL
Java_org_apache_hadoop_io_compress_bzip2_Bzip2Decompressor_getBytesRead(
                                JNIEnv *env, jclass cls, jlong stream)
{
    const bz_stream* strm = BZSTREAM(stream);
    return ((jlong)strm->total_in_hi32 << 32) | strm->total_in_lo32;
}

JNIEXPORT jlong JNICALL
Java_org_apache_hadoop_io_compress_bzip2_Bzip2Decompressor_getBytesWritten(
                                JNIEnv *env, jclass cls, jlong stream)
{
    const bz_stream* strm = BZSTREAM(stream);
    return ((jlong)strm->total_out_hi32 << 32) | strm->total_out_lo32;
}

JNIEXPORT jint JNICALL
Java_org_apache_hadoop_io_compress_bzip2_Bzip2Decompressor_getRemaining(
                                JNIEnv *env, jclass cls, jlong stream)
{
    return (BZSTREAM(stream))->avail_in;
}

JNIEXPORT void JNICALL
Java_org_apache_hadoop_io_compress_bzip2_Bzip2Decompressor_end(
                                JNIEnv *env, jclass cls, jlong stream)
{
    if (dlsym_BZ2_bzDecompressEnd(BZSTREAM(stream)) != BZ_OK) {
        THROW(env, "java/lang/InternalError", 0);
    } else {
        free(BZSTREAM(stream));
    }
}

/**
 * vim: sw=2: ts=2: et:
 */

