// 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 <limits>

#include "base/android/jni_android.h"
#include "base/android/scoped_java_ref.h"
#include "base/macros.h"
#include "starboard/string.h"
#include "starboard/types.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);
}

TEST(JniArray, ByteArrayStringConversions) {
  JNIEnv* env = AttachCurrentThread();
  std::string inputString("hello\0world");
  ScopedJavaLocalRef<jbyteArray> bytesFromString =
      ToJavaByteArray(env, inputString);
  ASSERT_TRUE(bytesFromString.obj());

  std::string stringFromString;
  JavaByteArrayToString(env, bytesFromString.obj(), &stringFromString);
  EXPECT_EQ(inputString, stringFromString);
}

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>(SbStringGetLength(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
