/*
 *  Copyright 2017 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/sdk/android/src/jni/pc/rtcstatscollectorcallbackwrapper.h"

#include <string>
#include <vector>

#include "webrtc/sdk/android/src/jni/classreferenceholder.h"

namespace webrtc {
namespace jni {

RTCStatsCollectorCallbackWrapper::RTCStatsCollectorCallbackWrapper(
    JNIEnv* jni,
    jobject j_callback)
    : j_callback_global_(jni, j_callback),
      j_callback_class_(jni, GetObjectClass(jni, j_callback)),
      j_stats_report_class_(FindClass(jni, "org/webrtc/RTCStatsReport")),
      j_stats_report_ctor_(GetMethodID(jni,
                                       j_stats_report_class_,
                                       "<init>",
                                       "(JLjava/util/Map;)V")),
      j_stats_class_(FindClass(jni, "org/webrtc/RTCStats")),
      j_stats_ctor_(GetMethodID(
          jni,
          j_stats_class_,
          "<init>",
          "(JLjava/lang/String;Ljava/lang/String;Ljava/util/Map;)V")),
      j_linked_hash_map_class_(FindClass(jni, "java/util/LinkedHashMap")),
      j_linked_hash_map_ctor_(
          GetMethodID(jni, j_linked_hash_map_class_, "<init>", "()V")),
      j_linked_hash_map_put_(GetMethodID(
          jni,
          j_linked_hash_map_class_,
          "put",
          "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;")),
      j_boolean_class_(FindClass(jni, "java/lang/Boolean")),
      j_boolean_ctor_(GetMethodID(jni, j_boolean_class_, "<init>", "(Z)V")),
      j_integer_class_(FindClass(jni, "java/lang/Integer")),
      j_integer_ctor_(GetMethodID(jni, j_integer_class_, "<init>", "(I)V")),
      j_long_class_(FindClass(jni, "java/lang/Long")),
      j_long_ctor_(GetMethodID(jni, j_long_class_, "<init>", "(J)V")),
      j_big_integer_class_(FindClass(jni, "java/math/BigInteger")),
      j_big_integer_ctor_(GetMethodID(jni,
                                      j_big_integer_class_,
                                      "<init>",
                                      "(Ljava/lang/String;)V")),
      j_double_class_(FindClass(jni, "java/lang/Double")),
      j_double_ctor_(GetMethodID(jni, j_double_class_, "<init>", "(D)V")),
      j_string_class_(FindClass(jni, "java/lang/String")) {}

void RTCStatsCollectorCallbackWrapper::OnStatsDelivered(
    const rtc::scoped_refptr<const RTCStatsReport>& report) {
  JNIEnv* jni = AttachCurrentThreadIfNeeded();
  ScopedLocalRefFrame local_ref_frame(jni);
  jobject j_report = ReportToJava(jni, report);
  jmethodID m = GetMethodID(jni, *j_callback_class_, "onStatsDelivered",
                            "(Lorg/webrtc/RTCStatsReport;)V");
  jni->CallVoidMethod(*j_callback_global_, m, j_report);
  CHECK_EXCEPTION(jni) << "error during CallVoidMethod";
}

jobject RTCStatsCollectorCallbackWrapper::ReportToJava(
    JNIEnv* jni,
    const rtc::scoped_refptr<const RTCStatsReport>& report) {
  jobject j_stats_map =
      jni->NewObject(j_linked_hash_map_class_, j_linked_hash_map_ctor_);
  CHECK_EXCEPTION(jni) << "error during NewObject";
  for (const RTCStats& stats : *report) {
    // Create a local reference frame for each RTCStats, since there is a
    // maximum number of references that can be created in one frame.
    ScopedLocalRefFrame local_ref_frame(jni);
    jstring j_id = JavaStringFromStdString(jni, stats.id());
    jobject j_stats = StatsToJava(jni, stats);
    jni->CallObjectMethod(j_stats_map, j_linked_hash_map_put_, j_id, j_stats);
    CHECK_EXCEPTION(jni) << "error during CallObjectMethod";
  }
  jobject j_report = jni->NewObject(j_stats_report_class_, j_stats_report_ctor_,
                                    report->timestamp_us(), j_stats_map);
  CHECK_EXCEPTION(jni) << "error during NewObject";
  return j_report;
}

jobject RTCStatsCollectorCallbackWrapper::StatsToJava(JNIEnv* jni,
                                                      const RTCStats& stats) {
  jstring j_type = JavaStringFromStdString(jni, stats.type());
  jstring j_id = JavaStringFromStdString(jni, stats.id());
  jobject j_members =
      jni->NewObject(j_linked_hash_map_class_, j_linked_hash_map_ctor_);
  for (const RTCStatsMemberInterface* member : stats.Members()) {
    if (!member->is_defined()) {
      continue;
    }
    // Create a local reference frame for each member as well.
    ScopedLocalRefFrame local_ref_frame(jni);
    jstring j_name = JavaStringFromStdString(jni, member->name());
    jobject j_member = MemberToJava(jni, member);
    jni->CallObjectMethod(j_members, j_linked_hash_map_put_, j_name, j_member);
    CHECK_EXCEPTION(jni) << "error during CallObjectMethod";
  }
  jobject j_stats =
      jni->NewObject(j_stats_class_, j_stats_ctor_, stats.timestamp_us(),
                     j_type, j_id, j_members);
  CHECK_EXCEPTION(jni) << "error during NewObject";
  return j_stats;
}

jobject RTCStatsCollectorCallbackWrapper::MemberToJava(
    JNIEnv* jni,
    const RTCStatsMemberInterface* member) {
  switch (member->type()) {
    case RTCStatsMemberInterface::kBool: {
      jobject value = jni->NewObject(j_boolean_class_, j_boolean_ctor_,
                                     *member->cast_to<RTCStatsMember<bool>>());
      CHECK_EXCEPTION(jni) << "error during NewObject";
      return value;
    }
    case RTCStatsMemberInterface::kInt32: {
      jobject value =
          jni->NewObject(j_integer_class_, j_integer_ctor_,
                         *member->cast_to<RTCStatsMember<int32_t>>());
      CHECK_EXCEPTION(jni) << "error during NewObject";
      return value;
    }
    case RTCStatsMemberInterface::kUint32: {
      jobject value =
          jni->NewObject(j_long_class_, j_long_ctor_,
                         (jlong)*member->cast_to<RTCStatsMember<uint32_t>>());
      CHECK_EXCEPTION(jni) << "error during NewObject";
      return value;
    }
    case RTCStatsMemberInterface::kInt64: {
      jobject value =
          jni->NewObject(j_long_class_, j_long_ctor_,
                         *member->cast_to<RTCStatsMember<int64_t>>());
      CHECK_EXCEPTION(jni) << "error during NewObject";
      return value;
    }
    case RTCStatsMemberInterface::kUint64: {
      jobject value =
          jni->NewObject(j_big_integer_class_, j_big_integer_ctor_,
                         JavaStringFromStdString(jni, member->ValueToString()));
      CHECK_EXCEPTION(jni) << "error during NewObject";
      return value;
    }
    case RTCStatsMemberInterface::kDouble: {
      jobject value =
          jni->NewObject(j_double_class_, j_double_ctor_,
                         *member->cast_to<RTCStatsMember<double>>());
      CHECK_EXCEPTION(jni) << "error during NewObject";
      return value;
    }
    case RTCStatsMemberInterface::kString: {
      return JavaStringFromStdString(
          jni, *member->cast_to<RTCStatsMember<std::string>>());
    }
    case RTCStatsMemberInterface::kSequenceBool: {
      const std::vector<bool>& values =
          *member->cast_to<RTCStatsMember<std::vector<bool>>>();
      jobjectArray j_values =
          jni->NewObjectArray(values.size(), j_boolean_class_, nullptr);
      CHECK_EXCEPTION(jni) << "error during NewObjectArray";
      for (size_t i = 0; i < values.size(); ++i) {
        jobject value =
            jni->NewObject(j_boolean_class_, j_boolean_ctor_, values[i]);
        jni->SetObjectArrayElement(j_values, i, value);
        CHECK_EXCEPTION(jni) << "error during SetObjectArrayElement";
      }
      return j_values;
    }
    case RTCStatsMemberInterface::kSequenceInt32: {
      const std::vector<int32_t>& values =
          *member->cast_to<RTCStatsMember<std::vector<int32_t>>>();
      jobjectArray j_values =
          jni->NewObjectArray(values.size(), j_integer_class_, nullptr);
      CHECK_EXCEPTION(jni) << "error during NewObjectArray";
      for (size_t i = 0; i < values.size(); ++i) {
        jobject value =
            jni->NewObject(j_integer_class_, j_integer_ctor_, values[i]);
        jni->SetObjectArrayElement(j_values, i, value);
        CHECK_EXCEPTION(jni) << "error during SetObjectArrayElement";
      }
      return j_values;
    }
    case RTCStatsMemberInterface::kSequenceUint32: {
      const std::vector<uint32_t>& values =
          *member->cast_to<RTCStatsMember<std::vector<uint32_t>>>();
      jobjectArray j_values =
          jni->NewObjectArray(values.size(), j_long_class_, nullptr);
      CHECK_EXCEPTION(jni) << "error during NewObjectArray";
      for (size_t i = 0; i < values.size(); ++i) {
        jobject value = jni->NewObject(j_long_class_, j_long_ctor_, values[i]);
        jni->SetObjectArrayElement(j_values, i, value);
        CHECK_EXCEPTION(jni) << "error during SetObjectArrayElement";
      }
      return j_values;
    }
    case RTCStatsMemberInterface::kSequenceInt64: {
      const std::vector<int64_t>& values =
          *member->cast_to<RTCStatsMember<std::vector<int64_t>>>();
      jobjectArray j_values =
          jni->NewObjectArray(values.size(), j_long_class_, nullptr);
      CHECK_EXCEPTION(jni) << "error during NewObjectArray";
      for (size_t i = 0; i < values.size(); ++i) {
        jobject value = jni->NewObject(j_long_class_, j_long_ctor_, values[i]);
        jni->SetObjectArrayElement(j_values, i, value);
        CHECK_EXCEPTION(jni) << "error during SetObjectArrayElement";
      }
      return j_values;
    }
    case RTCStatsMemberInterface::kSequenceUint64: {
      const std::vector<uint64_t>& values =
          *member->cast_to<RTCStatsMember<std::vector<uint64_t>>>();
      jobjectArray j_values =
          jni->NewObjectArray(values.size(), j_big_integer_class_, nullptr);
      CHECK_EXCEPTION(jni) << "error during NewObjectArray";
      for (size_t i = 0; i < values.size(); ++i) {
        jobject value = jni->NewObject(
            j_big_integer_class_, j_big_integer_ctor_,
            JavaStringFromStdString(jni, rtc::ToString(values[i])));
        jni->SetObjectArrayElement(j_values, i, value);
        CHECK_EXCEPTION(jni) << "error during SetObjectArrayElement";
      }
      return j_values;
    }
    case RTCStatsMemberInterface::kSequenceDouble: {
      const std::vector<double>& values =
          *member->cast_to<RTCStatsMember<std::vector<double>>>();
      jobjectArray j_values =
          jni->NewObjectArray(values.size(), j_double_class_, nullptr);
      CHECK_EXCEPTION(jni) << "error during NewObjectArray";
      for (size_t i = 0; i < values.size(); ++i) {
        jobject value =
            jni->NewObject(j_double_class_, j_double_ctor_, values[i]);
        jni->SetObjectArrayElement(j_values, i, value);
        CHECK_EXCEPTION(jni) << "error during SetObjectArrayElement";
      }
      return j_values;
    }
    case RTCStatsMemberInterface::kSequenceString: {
      const std::vector<std::string>& values =
          *member->cast_to<RTCStatsMember<std::vector<std::string>>>();
      jobjectArray j_values =
          jni->NewObjectArray(values.size(), j_string_class_, nullptr);
      CHECK_EXCEPTION(jni) << "error during NewObjectArray";
      for (size_t i = 0; i < values.size(); ++i) {
        jni->SetObjectArrayElement(j_values, i,
                                   JavaStringFromStdString(jni, values[i]));
        CHECK_EXCEPTION(jni) << "error during SetObjectArrayElement";
      }
      return j_values;
    }
  }
  RTC_NOTREACHED();
  return nullptr;
}

}  // namespace jni
}  // namespace webrtc
