// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "base/android/jni_array.h"

#include <stddef.h>
#include <stdint.h>

#include <limits>

#include "base/android/jni_android.h"
#include "base/android/scoped_java_ref.h"
#include "base/macros.h"
#include "testing/gtest/include/gtest/gtest.h"

namespace base {
namespace android {

TEST(JniArray, BasicConversions) {
  const uint8_t kBytes[] = {0, 1, 2, 3};
  const size_t kLen = arraysize(kBytes);
  JNIEnv* env = AttachCurrentThread();
  ScopedJavaLocalRef<jbyteArray> bytes = ToJavaByteArray(env, kBytes, kLen);
  ASSERT_TRUE(bytes.obj());

  std::vector<uint8_t> inputVector(kBytes, kBytes + kLen);
  ScopedJavaLocalRef<jbyteArray> bytesFromVector =
      ToJavaByteArray(env, inputVector);
  ASSERT_TRUE(bytesFromVector.obj());

  std::vector<uint8_t> vectorFromBytes(5);
  std::vector<uint8_t> vectorFromVector(5);
  JavaByteArrayToByteVector(env, bytes.obj(), &vectorFromBytes);
  JavaByteArrayToByteVector(env, bytesFromVector.obj(), &vectorFromVector);
  EXPECT_EQ(4U, vectorFromBytes.size());
  EXPECT_EQ(4U, vectorFromVector.size());
  std::vector<uint8_t> expected_vec(kBytes, kBytes + kLen);
  EXPECT_EQ(expected_vec, vectorFromBytes);
  EXPECT_EQ(expected_vec, vectorFromVector);

  AppendJavaByteArrayToByteVector(env, bytes.obj(), &vectorFromBytes);
  EXPECT_EQ(8U, vectorFromBytes.size());
  expected_vec.insert(expected_vec.end(), kBytes, kBytes + kLen);
  EXPECT_EQ(expected_vec, vectorFromBytes);
}

void CheckBoolConversion(JNIEnv* env,
                         const bool* bool_array,
                         const size_t len,
                         const ScopedJavaLocalRef<jbooleanArray>& booleans) {
  ASSERT_TRUE(booleans.obj());

  jsize java_array_len = env->GetArrayLength(booleans.obj());
  ASSERT_EQ(static_cast<jsize>(len), java_array_len);

  jboolean value;
  for (size_t i = 0; i < len; ++i) {
    env->GetBooleanArrayRegion(booleans.obj(), i, 1, &value);
    ASSERT_EQ(bool_array[i], value);
  }
}

TEST(JniArray, BoolConversions) {
  const bool kBools[] = {false, true, false};
  const size_t kLen = arraysize(kBools);

  JNIEnv* env = AttachCurrentThread();
  CheckBoolConversion(env, kBools, kLen, ToJavaBooleanArray(env, kBools, kLen));
}

void CheckIntConversion(
    JNIEnv* env,
    const int* int_array,
    const size_t len,
    const ScopedJavaLocalRef<jintArray>& ints) {
  ASSERT_TRUE(ints.obj());

  jsize java_array_len = env->GetArrayLength(ints.obj());
  ASSERT_EQ(static_cast<jsize>(len), java_array_len);

  jint value;
  for (size_t i = 0; i < len; ++i) {
    env->GetIntArrayRegion(ints.obj(), i, 1, &value);
    ASSERT_EQ(int_array[i], value);
  }
}

TEST(JniArray, IntConversions) {
  const int kInts[] = {0, 1, -1, std::numeric_limits<int32_t>::min(),
                       std::numeric_limits<int32_t>::max()};
  const size_t kLen = arraysize(kInts);

  JNIEnv* env = AttachCurrentThread();
  CheckIntConversion(env, kInts, kLen, ToJavaIntArray(env, kInts, kLen));

  const std::vector<int> vec(kInts, kInts + kLen);
  CheckIntConversion(env, kInts, kLen, ToJavaIntArray(env, vec));
}

void CheckLongConversion(JNIEnv* env,
                         const int64_t* long_array,
                         const size_t len,
                         const ScopedJavaLocalRef<jlongArray>& longs) {
  ASSERT_TRUE(longs.obj());

  jsize java_array_len = env->GetArrayLength(longs.obj());
  ASSERT_EQ(static_cast<jsize>(len), java_array_len);

  jlong value;
  for (size_t i = 0; i < len; ++i) {
    env->GetLongArrayRegion(longs.obj(), i, 1, &value);
    ASSERT_EQ(long_array[i], value);
  }
}

TEST(JniArray, LongConversions) {
  const int64_t kLongs[] = {0, 1, -1, std::numeric_limits<int64_t>::min(),
                            std::numeric_limits<int64_t>::max()};
  const size_t kLen = arraysize(kLongs);

  JNIEnv* env = AttachCurrentThread();
  CheckLongConversion(env, kLongs, kLen, ToJavaLongArray(env, kLongs, kLen));

  const std::vector<int64_t> vec(kLongs, kLongs + kLen);
  CheckLongConversion(env, kLongs, kLen, ToJavaLongArray(env, vec));
}

void CheckIntArrayConversion(JNIEnv* env,
                             ScopedJavaLocalRef<jintArray> jints,
                             std::vector<int> int_vector,
                             const size_t len) {
  jint value;
  for (size_t i = 0; i < len; ++i) {
    env->GetIntArrayRegion(jints.obj(), i, 1, &value);
    ASSERT_EQ(int_vector[i], value);
  }
}

void CheckBoolArrayConversion(JNIEnv* env,
                              ScopedJavaLocalRef<jbooleanArray> jbooleans,
                              std::vector<bool> bool_vector,
                              const size_t len) {
  jboolean value;
  for (size_t i = 0; i < len; ++i) {
    env->GetBooleanArrayRegion(jbooleans.obj(), i, 1, &value);
    ASSERT_EQ(bool_vector[i], value);
  }
}

void CheckFloatConversion(
    JNIEnv* env,
    const float* float_array,
    const size_t len,
    const ScopedJavaLocalRef<jfloatArray>& floats) {
  ASSERT_TRUE(floats.obj());

  jsize java_array_len = env->GetArrayLength(floats.obj());
  ASSERT_EQ(static_cast<jsize>(len), java_array_len);

  jfloat value;
  for (size_t i = 0; i < len; ++i) {
    env->GetFloatArrayRegion(floats.obj(), i, 1, &value);
    ASSERT_EQ(float_array[i], value);
  }
}

TEST(JniArray, FloatConversions) {
  const float kFloats[] = { 0.0f, 1.0f, -10.0f};
  const size_t kLen = arraysize(kFloats);

  JNIEnv* env = AttachCurrentThread();
  CheckFloatConversion(env, kFloats, kLen,
                       ToJavaFloatArray(env, kFloats, kLen));

  const std::vector<float> vec(kFloats, kFloats + kLen);
  CheckFloatConversion(env, kFloats, kLen, ToJavaFloatArray(env, vec));
}

TEST(JniArray, JavaBooleanArrayToBoolVector) {
  const bool kBools[] = {false, true, false};
  const size_t kLen = arraysize(kBools);

  JNIEnv* env = AttachCurrentThread();
  ScopedJavaLocalRef<jbooleanArray> jbooleans(env, env->NewBooleanArray(kLen));
  ASSERT_TRUE(jbooleans.obj());

  for (size_t i = 0; i < kLen; ++i) {
    jboolean j = static_cast<jboolean>(kBools[i]);
    env->SetBooleanArrayRegion(jbooleans.obj(), i, 1, &j);
    ASSERT_FALSE(HasException(env));
  }

  std::vector<bool> bools;
  JavaBooleanArrayToBoolVector(env, jbooleans.obj(), &bools);

  ASSERT_EQ(static_cast<jsize>(bools.size()),
            env->GetArrayLength(jbooleans.obj()));

  CheckBoolArrayConversion(env, jbooleans, bools, kLen);
}

TEST(JniArray, JavaIntArrayToIntVector) {
  const int kInts[] = {0, 1, -1};
  const size_t kLen = arraysize(kInts);

  JNIEnv* env = AttachCurrentThread();
  ScopedJavaLocalRef<jintArray> jints(env, env->NewIntArray(kLen));
  ASSERT_TRUE(jints.obj());

  for (size_t i = 0; i < kLen; ++i) {
    jint j = static_cast<jint>(kInts[i]);
    env->SetIntArrayRegion(jints.obj(), i, 1, &j);
    ASSERT_FALSE(HasException(env));
  }

  std::vector<int> ints;
  JavaIntArrayToIntVector(env, jints.obj(), &ints);

  ASSERT_EQ(static_cast<jsize>(ints.size()), env->GetArrayLength(jints.obj()));

  CheckIntArrayConversion(env, jints, ints, kLen);
}

TEST(JniArray, JavaLongArrayToInt64Vector) {
  const int64_t kInt64s[] = {0LL, 1LL, -1LL};
  const size_t kLen = arraysize(kInt64s);

  JNIEnv* env = AttachCurrentThread();
  ScopedJavaLocalRef<jlongArray> jlongs(env, env->NewLongArray(kLen));
  ASSERT_TRUE(jlongs.obj());

  for (size_t i = 0; i < kLen; ++i) {
    jlong j = static_cast<jlong>(kInt64s[i]);
    env->SetLongArrayRegion(jlongs.obj(), i, 1, &j);
    ASSERT_FALSE(HasException(env));
  }

  std::vector<int64_t> int64s;
  JavaLongArrayToInt64Vector(env, jlongs.obj(), &int64s);

  ASSERT_EQ(static_cast<jsize>(int64s.size()),
            env->GetArrayLength(jlongs.obj()));

  jlong value;
  for (size_t i = 0; i < kLen; ++i) {
    env->GetLongArrayRegion(jlongs.obj(), i, 1, &value);
    ASSERT_EQ(int64s[i], value);
    ASSERT_EQ(kInt64s[i], int64s[i]);
  }
}

TEST(JniArray, JavaLongArrayToLongVector) {
  const int64_t kInt64s[] = {0LL, 1LL, -1LL};
  const size_t kLen = arraysize(kInt64s);

  JNIEnv* env = AttachCurrentThread();
  ScopedJavaLocalRef<jlongArray> jlongs(env, env->NewLongArray(kLen));
  ASSERT_TRUE(jlongs.obj());

  for (size_t i = 0; i < kLen; ++i) {
    jlong j = static_cast<jlong>(kInt64s[i]);
    env->SetLongArrayRegion(jlongs.obj(), i, 1, &j);
    ASSERT_FALSE(HasException(env));
  }

  std::vector<jlong> jlongs_vector;
  JavaLongArrayToLongVector(env, jlongs.obj(), &jlongs_vector);

  ASSERT_EQ(static_cast<jsize>(jlongs_vector.size()),
            env->GetArrayLength(jlongs.obj()));

  jlong value;
  for (size_t i = 0; i < kLen; ++i) {
    env->GetLongArrayRegion(jlongs.obj(), i, 1, &value);
    ASSERT_EQ(jlongs_vector[i], value);
  }
}

TEST(JniArray, JavaFloatArrayToFloatVector) {
  const float kFloats[] = {0.0, 0.5, -0.5};
  const size_t kLen = arraysize(kFloats);

  JNIEnv* env = AttachCurrentThread();
  ScopedJavaLocalRef<jfloatArray> jfloats(env, env->NewFloatArray(kLen));
  ASSERT_TRUE(jfloats.obj());

  for (size_t i = 0; i < kLen; ++i) {
    jfloat j = static_cast<jfloat>(kFloats[i]);
    env->SetFloatArrayRegion(jfloats.obj(), i, 1, &j);
    ASSERT_FALSE(HasException(env));
  }

  std::vector<float> floats;
  JavaFloatArrayToFloatVector(env, jfloats.obj(), &floats);

  ASSERT_EQ(static_cast<jsize>(floats.size()),
      env->GetArrayLength(jfloats.obj()));

  jfloat value;
  for (size_t i = 0; i < kLen; ++i) {
    env->GetFloatArrayRegion(jfloats.obj(), i, 1, &value);
    ASSERT_EQ(floats[i], value);
  }
}

TEST(JniArray, JavaArrayOfByteArrayToStringVector) {
  const int kMaxItems = 50;
  JNIEnv* env = AttachCurrentThread();

  // Create a byte[][] object.
  ScopedJavaLocalRef<jclass> byte_array_clazz(env, env->FindClass("[B"));
  ASSERT_TRUE(byte_array_clazz.obj());

  ScopedJavaLocalRef<jobjectArray> array(
      env, env->NewObjectArray(kMaxItems, byte_array_clazz.obj(), NULL));
  ASSERT_TRUE(array.obj());

  // Create kMaxItems byte buffers.
  char text[16];
  for (int i = 0; i < kMaxItems; ++i) {
    snprintf(text, sizeof text, "%d", i);
    ScopedJavaLocalRef<jbyteArray> byte_array =
        ToJavaByteArray(env, reinterpret_cast<uint8_t*>(text),
                        static_cast<size_t>(strlen(text)));
    ASSERT_TRUE(byte_array.obj());

    env->SetObjectArrayElement(array.obj(), i, byte_array.obj());
    ASSERT_FALSE(HasException(env));
  }

  // Convert to std::vector<std::string>, check the content.
  std::vector<std::string> vec;
  JavaArrayOfByteArrayToStringVector(env, array.obj(), &vec);

  EXPECT_EQ(static_cast<size_t>(kMaxItems), vec.size());
  for (int i = 0; i < kMaxItems; ++i) {
    snprintf(text, sizeof text, "%d", i);
    EXPECT_STREQ(text, vec[i].c_str());
  }
}

TEST(JniArray, JavaArrayOfIntArrayToIntVector) {
  const size_t kNumItems = 4;
  JNIEnv* env = AttachCurrentThread();

  // Create an int[][] object.
  ScopedJavaLocalRef<jclass> int_array_clazz(env, env->FindClass("[I"));
  ASSERT_TRUE(int_array_clazz.obj());

  ScopedJavaLocalRef<jobjectArray> array(
      env, env->NewObjectArray(kNumItems, int_array_clazz.obj(), nullptr));
  ASSERT_TRUE(array.obj());

  // Populate int[][] object.
  const int kInts0[] = {0, 1, -1, std::numeric_limits<int32_t>::min(),
                        std::numeric_limits<int32_t>::max()};
  const size_t kLen0 = arraysize(kInts0);
  ScopedJavaLocalRef<jintArray> int_array0 = ToJavaIntArray(env, kInts0, kLen0);
  env->SetObjectArrayElement(array.obj(), 0, int_array0.obj());

  const int kInts1[] = {3, 4, 5};
  const size_t kLen1 = arraysize(kInts1);
  ScopedJavaLocalRef<jintArray> int_array1 = ToJavaIntArray(env, kInts1, kLen1);
  env->SetObjectArrayElement(array.obj(), 1, int_array1.obj());

  const int kInts2[] = {};
  const size_t kLen2 = 0;
  ScopedJavaLocalRef<jintArray> int_array2 = ToJavaIntArray(env, kInts2, kLen2);
  env->SetObjectArrayElement(array.obj(), 2, int_array2.obj());

  const int kInts3[] = {16};
  const size_t kLen3 = arraysize(kInts3);
  ScopedJavaLocalRef<jintArray> int_array3 = ToJavaIntArray(env, kInts3, kLen3);
  env->SetObjectArrayElement(array.obj(), 3, int_array3.obj());

  // Convert to std::vector<std::vector<int>>, check the content.
  std::vector<std::vector<int>> out;
  JavaArrayOfIntArrayToIntVector(env, array.obj(), &out);

  EXPECT_EQ(kNumItems, out.size());
  CheckIntArrayConversion(env, int_array0, out[0], kLen0);
  CheckIntArrayConversion(env, int_array1, out[1], kLen1);
  CheckIntArrayConversion(env, int_array2, out[2], kLen2);
  CheckIntArrayConversion(env, int_array3, out[3], kLen3);
}

}  // namespace android
}  // namespace base
