/* Copyright 2017 Google Inc. All Rights Reserved.

   Distributed under MIT license.
   See file LICENSE for detail or copy at https://opensource.org/licenses/MIT
*/

#include "decoder_jni.h"  // NOLINT: build/include

#include <brotli/decode.h>

#include <new>

namespace {
/* A structure used to persist the decoder's state in between calls. */
typedef struct DecoderHandle {
  BrotliDecoderState* state;

  jobject dictionary_refs[15];
  size_t dictionary_count;

  uint8_t* input_start;
  size_t input_offset;
  size_t input_length;
} DecoderHandle;

/* Obtain handle from opaque pointer. */
DecoderHandle* getHandle(void* opaque) {
  return static_cast<DecoderHandle*>(opaque);
}

}  /* namespace */

#ifdef __cplusplus
extern "C" {
#endif

/**
 * Creates a new Decoder.
 *
 * Cookie to address created decoder is stored in out_cookie. In case of failure
 * cookie is 0.
 *
 * @param ctx {out_cookie, in_directBufferSize} tuple
 * @returns direct ByteBuffer if directBufferSize is not 0; otherwise null
 */
JNIEXPORT jobject JNICALL
Java_org_brotli_wrapper_dec_DecoderJNI_nativeCreate(
    JNIEnv* env, jobject /*jobj*/, jlongArray ctx) {
  bool ok = true;
  DecoderHandle* handle = nullptr;
  jlong context[3];
  env->GetLongArrayRegion(ctx, 0, 3, context);
  size_t input_size = context[1];
  context[0] = 0;
  context[2] = 0;
  handle = new (std::nothrow) DecoderHandle();
  ok = !!handle;

  if (ok) {
    for (int i = 0; i < 15; ++i) {
      handle->dictionary_refs[i] = nullptr;
    }
    handle->dictionary_count = 0;
    handle->input_offset = 0;
    handle->input_length = 0;
    handle->input_start = nullptr;

    if (input_size == 0) {
      ok = false;
    } else {
      handle->input_start = new (std::nothrow) uint8_t[input_size];
      ok = !!handle->input_start;
    }
  }

  if (ok) {
    handle->state = BrotliDecoderCreateInstance(nullptr, nullptr, nullptr);
    ok = !!handle->state;
  }

  if (ok) {
    /* TODO(eustas): future versions (e.g. when 128-bit architecture comes)
                     might require thread-safe cookie<->handle mapping. */
    context[0] = reinterpret_cast<jlong>(handle);
  } else if (!!handle) {
    if (!!handle->input_start) delete[] handle->input_start;
    delete handle;
  }

  env->SetLongArrayRegion(ctx, 0, 3, context);

  if (!ok) {
    return nullptr;
  }

  return env->NewDirectByteBuffer(handle->input_start, input_size);
}

/**
 * Push data to decoder.
 *
 * status codes:
 *  - 0 error happened
 *  - 1 stream is finished, no more input / output expected
 *  - 2 needs more input to process further
 *  - 3 needs more output to process further
 *  - 4 ok, can proceed further without additional input
 *
 * @param ctx {in_cookie, out_status} tuple
 * @param input_length number of bytes provided in input or direct input;
 *                     0 to process further previous input
 */
JNIEXPORT void JNICALL
Java_org_brotli_wrapper_dec_DecoderJNI_nativePush(
    JNIEnv* env, jobject /*jobj*/, jlongArray ctx, jint input_length) {
  jlong context[3];
  env->GetLongArrayRegion(ctx, 0, 3, context);
  DecoderHandle* handle = getHandle(reinterpret_cast<void*>(context[0]));
  context[1] = 0;  /* ERROR */
  context[2] = 0;
  env->SetLongArrayRegion(ctx, 0, 3, context);

  if (input_length != 0) {
    /* Still have unconsumed data. Workflow is broken. */
    if (handle->input_offset < handle->input_length) {
      return;
    }
    handle->input_offset = 0;
    handle->input_length = input_length;
  }

  /* Actual decompression. */
  const uint8_t* in = handle->input_start + handle->input_offset;
  size_t in_size = handle->input_length - handle->input_offset;
  size_t out_size = 0;
  BrotliDecoderResult status = BrotliDecoderDecompressStream(
      handle->state, &in_size, &in, &out_size, nullptr, nullptr);
  handle->input_offset = handle->input_length - in_size;
  switch (status) {
    case BROTLI_DECODER_RESULT_SUCCESS:
      /* Bytes after stream end are not allowed. */
      context[1] = (handle->input_offset == handle->input_length) ? 1 : 0;
      break;

    case BROTLI_DECODER_RESULT_NEEDS_MORE_INPUT:
      context[1] = 2;
      break;

    case BROTLI_DECODER_RESULT_NEEDS_MORE_OUTPUT:
      context[1] = 3;
      break;

    default:
      context[1] = 0;
      break;
  }
  context[2] = BrotliDecoderHasMoreOutput(handle->state) ? 1 : 0;
  env->SetLongArrayRegion(ctx, 0, 3, context);
}

/**
 * Pull decompressed data from decoder.
 *
 * @param ctx {in_cookie, out_status} tuple
 * @returns direct ByteBuffer; all the produced data MUST be consumed before
 *          any further invocation; null in case of error
 */
JNIEXPORT jobject JNICALL
Java_org_brotli_wrapper_dec_DecoderJNI_nativePull(
    JNIEnv* env, jobject /*jobj*/, jlongArray ctx) {
  jlong context[3];
  env->GetLongArrayRegion(ctx, 0, 3, context);
  DecoderHandle* handle = getHandle(reinterpret_cast<void*>(context[0]));
  size_t data_length = 0;
  const uint8_t* data = BrotliDecoderTakeOutput(handle->state, &data_length);
  bool hasMoreOutput = !!BrotliDecoderHasMoreOutput(handle->state);
  if (hasMoreOutput) {
    context[1] = 3;
  } else if (BrotliDecoderIsFinished(handle->state)) {
    /* Bytes after stream end are not allowed. */
    context[1] = (handle->input_offset == handle->input_length) ? 1 : 0;
  } else {
    /* Can proceed, or more data is required? */
    context[1] = (handle->input_offset == handle->input_length) ? 2 : 4;
  }
  context[2] = hasMoreOutput ? 1 : 0;
  env->SetLongArrayRegion(ctx, 0, 3, context);
  return env->NewDirectByteBuffer(const_cast<uint8_t*>(data), data_length);
}

/**
 * Releases all used resources.
 *
 * @param ctx {in_cookie} tuple
 */
JNIEXPORT void JNICALL
Java_org_brotli_wrapper_dec_DecoderJNI_nativeDestroy(
    JNIEnv* env, jobject /*jobj*/, jlongArray ctx) {
  jlong context[3];
  env->GetLongArrayRegion(ctx, 0, 3, context);
  DecoderHandle* handle = getHandle(reinterpret_cast<void*>(context[0]));
  BrotliDecoderDestroyInstance(handle->state);
  for (size_t i = 0; i < handle->dictionary_count; ++i) {
    env->DeleteGlobalRef(handle->dictionary_refs[i]);
  }
  delete[] handle->input_start;
  delete handle;
}

JNIEXPORT jboolean JNICALL
Java_org_brotli_wrapper_dec_DecoderJNI_nativeAttachDictionary(
    JNIEnv* env, jobject /*jobj*/, jlongArray ctx, jobject dictionary) {
  jlong context[3];
  env->GetLongArrayRegion(ctx, 0, 3, context);
  DecoderHandle* handle = getHandle(reinterpret_cast<void*>(context[0]));
  jobject ref = nullptr;
  uint8_t* address = nullptr;
  jlong capacity = 0;

  bool ok = true;
  if (ok && !dictionary) {
    ok = false;
  }
  if (ok && handle->dictionary_count >= 15) {
    ok = false;
  }
  if (ok) {
    ref = env->NewGlobalRef(dictionary);
    ok = !!ref;
  }
  if (ok) {
    handle->dictionary_refs[handle->dictionary_count] = ref;
    handle->dictionary_count++;
    address = static_cast<uint8_t*>(env->GetDirectBufferAddress(ref));
    ok = !!address;
  }
  if (ok) {
    capacity = env->GetDirectBufferCapacity(ref);
    ok = (capacity > 0) && (capacity < (1 << 30));
  }
  if (ok) {
    size_t size = static_cast<size_t>(capacity);
    ok = !!BrotliDecoderAttachDictionary(handle->state,
        BROTLI_SHARED_DICTIONARY_RAW, size, address);
  }

  return static_cast<jboolean>(ok);
}

#ifdef __cplusplus
}
#endif
