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

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

namespace webrtc {
namespace jni {

// Convenience, used since callbacks occur on the signaling thread, which may
// be a non-Java thread.
static JNIEnv* jni() {
  return AttachCurrentThreadIfNeeded();
}

StatsObserverJni::StatsObserverJni(JNIEnv* jni, jobject j_observer)
    : j_observer_global_(jni, j_observer),
      j_observer_class_(jni, GetObjectClass(jni, j_observer)),
      j_stats_report_class_(jni, FindClass(jni, "org/webrtc/StatsReport")),
      j_stats_report_ctor_(GetMethodID(jni,
                                       *j_stats_report_class_,
                                       "<init>",
                                       "(Ljava/lang/String;Ljava/lang/String;D"
                                       "[Lorg/webrtc/StatsReport$Value;)V")),
      j_value_class_(jni, FindClass(jni, "org/webrtc/StatsReport$Value")),
      j_value_ctor_(GetMethodID(jni,
                                *j_value_class_,
                                "<init>",
                                "(Ljava/lang/String;Ljava/lang/String;)V")) {}

void StatsObserverJni::OnComplete(const StatsReports& reports) {
  ScopedLocalRefFrame local_ref_frame(jni());
  jobjectArray j_reports = ReportsToJava(jni(), reports);
  jmethodID m = GetMethodID(jni(), *j_observer_class_, "onComplete",
                            "([Lorg/webrtc/StatsReport;)V");
  jni()->CallVoidMethod(*j_observer_global_, m, j_reports);
  CHECK_EXCEPTION(jni()) << "error during CallVoidMethod";
}

jobjectArray StatsObserverJni::ReportsToJava(JNIEnv* jni,
                                             const StatsReports& reports) {
  jobjectArray reports_array =
      jni->NewObjectArray(reports.size(), *j_stats_report_class_, NULL);
  int i = 0;
  for (const auto* report : reports) {
    ScopedLocalRefFrame local_ref_frame(jni);
    jstring j_id = JavaStringFromStdString(jni, report->id()->ToString());
    jstring j_type = JavaStringFromStdString(jni, report->TypeToString());
    jobjectArray j_values = ValuesToJava(jni, report->values());
    jobject j_report =
        jni->NewObject(*j_stats_report_class_, j_stats_report_ctor_, j_id,
                       j_type, report->timestamp(), j_values);
    jni->SetObjectArrayElement(reports_array, i++, j_report);
  }
  return reports_array;
}

jobjectArray StatsObserverJni::ValuesToJava(JNIEnv* jni,
                                            const StatsReport::Values& values) {
  jobjectArray j_values =
      jni->NewObjectArray(values.size(), *j_value_class_, NULL);
  int i = 0;
  for (const auto& it : values) {
    ScopedLocalRefFrame local_ref_frame(jni);
    // Should we use the '.name' enum value here instead of converting the
    // name to a string?
    jstring j_name = JavaStringFromStdString(jni, it.second->display_name());
    jstring j_value = JavaStringFromStdString(jni, it.second->ToString());
    jobject j_element_value =
        jni->NewObject(*j_value_class_, j_value_ctor_, j_name, j_value);
    jni->SetObjectArrayElement(j_values, i++, j_element_value);
  }
  return j_values;
}

}  // namespace jni
}  // namespace webrtc
