/*
 *  Copyright (c) 2013 The WebRTC project authors. All Rights Reserved.
 *
 *  Use of this source code is governed by a BSD-style license
 *  that can be found in the LICENSE file in the root of the source
 *  tree. An additional intellectual property rights grant can be found
 *  in the file PATENTS.  All contributing project authors may
 *  be found in the AUTHORS file in the root of the source tree.
 */

#include "webrtc/modules/utility/include/helpers_android.h"
#include "webrtc/rtc_base/checks.h"

#include <android/log.h>
#include <assert.h>
#include <pthread.h>
#include <stddef.h>
#include <unistd.h>

#define TAG "HelpersAndroid"
#define ALOGD(...) __android_log_print(ANDROID_LOG_DEBUG, TAG, __VA_ARGS__)

namespace webrtc {

JNIEnv* GetEnv(JavaVM* jvm) {
  void* env = NULL;
  jint status = jvm->GetEnv(&env, JNI_VERSION_1_6);
  RTC_CHECK(((env != NULL) && (status == JNI_OK)) ||
            ((env == NULL) && (status == JNI_EDETACHED)))
      << "Unexpected GetEnv return: " << status << ":" << env;
  return reinterpret_cast<JNIEnv*>(env);
}

// Return a |jlong| that will correctly convert back to |ptr|.  This is needed
// because the alternative (of silently passing a 32-bit pointer to a vararg
// function expecting a 64-bit param) picks up garbage in the high 32 bits.
jlong PointerTojlong(void* ptr) {
  static_assert(sizeof(intptr_t) <= sizeof(jlong),
                "Time to rethink the use of jlongs");
  // Going through intptr_t to be obvious about the definedness of the
  // conversion from pointer to integral type.  intptr_t to jlong is a standard
  // widening by the static_assert above.
  jlong ret = reinterpret_cast<intptr_t>(ptr);
  RTC_DCHECK(reinterpret_cast<void*>(ret) == ptr);
  return ret;
}

jmethodID GetMethodID (
    JNIEnv* jni, jclass c, const char* name, const char* signature) {
  jmethodID m = jni->GetMethodID(c, name, signature);
  CHECK_EXCEPTION(jni) << "Error during GetMethodID: " << name << ", "
                       << signature;
  RTC_CHECK(m) << name << ", " << signature;
  return m;
}

jmethodID GetStaticMethodID (
    JNIEnv* jni, jclass c, const char* name, const char* signature) {
  jmethodID m = jni->GetStaticMethodID(c, name, signature);
  CHECK_EXCEPTION(jni) << "Error during GetStaticMethodID: " << name << ", "
                       << signature;
  RTC_CHECK(m) << name << ", " << signature;
  return m;
}

jclass FindClass(JNIEnv* jni, const char* name) {
  jclass c = jni->FindClass(name);
  CHECK_EXCEPTION(jni) << "Error during FindClass: " << name;
  RTC_CHECK(c) << name;
  return c;
}

jobject NewGlobalRef(JNIEnv* jni, jobject o) {
  jobject ret = jni->NewGlobalRef(o);
  CHECK_EXCEPTION(jni) << "Error during NewGlobalRef";
  RTC_CHECK(ret);
  return ret;
}

void DeleteGlobalRef(JNIEnv* jni, jobject o) {
  jni->DeleteGlobalRef(o);
  CHECK_EXCEPTION(jni) << "Error during DeleteGlobalRef";
}

std::string GetThreadId() {
  char buf[21];  // Big enough to hold a kuint64max plus terminating NULL.
  int thread_id = gettid();
  RTC_CHECK_LT(snprintf(buf, sizeof(buf), "%i", thread_id),
               static_cast<int>(sizeof(buf)))
      << "Thread id is bigger than uint64??";
  return std::string(buf);
}

std::string GetThreadInfo() {
  return "@[tid=" + GetThreadId() + "]";
}

AttachThreadScoped::AttachThreadScoped(JavaVM* jvm)
    : attached_(false), jvm_(jvm), env_(NULL) {
  env_ = GetEnv(jvm);
  if (!env_) {
    // Adding debug log here so we can track down potential leaks and figure
    // out why we sometimes see "Native thread exiting without having called
    // DetachCurrentThread" in logcat outputs.
    ALOGD("Attaching thread to JVM%s", GetThreadInfo().c_str());
    jint res = jvm->AttachCurrentThread(&env_, NULL);
    attached_ = (res == JNI_OK);
    RTC_CHECK(attached_) << "AttachCurrentThread failed: " << res;
  }
}

AttachThreadScoped::~AttachThreadScoped() {
  if (attached_) {
    ALOGD("Detaching thread from JVM%s", GetThreadInfo().c_str());
    jint res = jvm_->DetachCurrentThread();
    RTC_CHECK(res == JNI_OK) << "DetachCurrentThread failed: " << res;
    RTC_CHECK(!GetEnv(jvm_));
  }
}

JNIEnv* AttachThreadScoped::env() { return env_; }

}  // namespace webrtc
