/*
 *  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.h"

#include <vector>

#include "sdk/android/generated_peerconnection_jni/jni/StatsObserver_jni.h"
#include "sdk/android/generated_peerconnection_jni/jni/StatsReport_jni.h"
#include "sdk/android/native_api/jni/java_types.h"
#include "sdk/android/src/jni/jni_helpers.h"

namespace webrtc {
namespace jni {

namespace {

ScopedJavaLocalRef<jobject> NativeToJavaStatsReportValue(
    JNIEnv* env,
    const rtc::scoped_refptr<StatsReport::Value>& value_ptr) {
  // Should we use the '.name' enum value here instead of converting the
  // name to a string?
  return Java_Value_Constructor(
      env, NativeToJavaString(env, value_ptr->display_name()),
      NativeToJavaString(env, value_ptr->ToString()));
}

ScopedJavaLocalRef<jobjectArray> NativeToJavaStatsReportValueArray(
    JNIEnv* env,
    const StatsReport::Values& value_map) {
  // Ignore the keys and make an array out of the values.
  std::vector<StatsReport::ValuePtr> values;
  for (const auto& it : value_map)
    values.push_back(it.second);
  return NativeToJavaObjectArray(env, values,
                                 org_webrtc_StatsReport_00024Value_clazz(env),
                                 &NativeToJavaStatsReportValue);
}

ScopedJavaLocalRef<jobject> NativeToJavaStatsReport(JNIEnv* env,
                                                    const StatsReport& report) {
  return Java_StatsReport_Constructor(
      env, NativeToJavaString(env, report.id()->ToString()),
      NativeToJavaString(env, report.TypeToString()), report.timestamp(),
      NativeToJavaStatsReportValueArray(env, report.values()));
}

}  // namespace

StatsObserverJni::StatsObserverJni(JNIEnv* jni,
                                   const JavaRef<jobject>& j_observer)
    : j_observer_global_(jni, j_observer) {}

StatsObserverJni::~StatsObserverJni() = default;

void StatsObserverJni::OnComplete(const StatsReports& reports) {
  JNIEnv* env = AttachCurrentThreadIfNeeded();
  ScopedJavaLocalRef<jobjectArray> j_reports =
      NativeToJavaObjectArray(env, reports, org_webrtc_StatsReport_clazz(env),
                              [](JNIEnv* env, const StatsReport* report) {
                                return NativeToJavaStatsReport(env, *report);
                              });
  Java_StatsObserver_onComplete(env, j_observer_global_, j_reports);
}

}  // namespace jni
}  // namespace webrtc
