/*
 *  Copyright 2013 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.
 */

// Lifecycle notes: objects are owned where they will be called; in other words
// FooObservers are owned by C++-land, and user-callable objects (e.g.
// PeerConnection and VideoTrack) are owned by Java-land.
// When this file (or other files in this directory) allocates C++
// RefCountInterfaces it AddRef()s an artificial ref simulating the jlong held
// in Java-land, and then Release()s the ref in the respective free call.
// Sometimes this AddRef is implicit in the construction of a scoped_refptr<>
// which is then .release()d. Any persistent (non-local) references from C++ to
// Java must be global or weak (in which case they must be checked before use)!
//
// Exception notes: pretty much all JNI calls can throw Java exceptions, so each
// call through a JNIEnv* pointer needs to be followed by an ExceptionCheck()
// call. In this file this is done in CHECK_EXCEPTION, making for much easier
// debugging in case of failure (the alternative is to wait for control to
// return to the Java frame that called code in this file, at which point it's
// impossible to tell which JNI call broke).

#include <limits>
#include <memory>
#include <utility>

#include "webrtc/api/mediaconstraintsinterface.h"
#include "webrtc/api/peerconnectioninterface.h"
#include "webrtc/api/rtpreceiverinterface.h"
#include "webrtc/api/rtpsenderinterface.h"
#include "webrtc/rtc_base/checks.h"
#include "webrtc/rtc_base/logging.h"
#include "webrtc/sdk/android/src/jni/classreferenceholder.h"
#include "webrtc/sdk/android/src/jni/jni_helpers.h"
#include "webrtc/sdk/android/src/jni/pc/java_native_conversion.h"
#include "webrtc/sdk/android/src/jni/pc/mediaconstraints_jni.h"
#include "webrtc/sdk/android/src/jni/pc/peerconnectionobserver_jni.h"
#include "webrtc/sdk/android/src/jni/pc/rtcstatscollectorcallbackwrapper.h"
#include "webrtc/sdk/android/src/jni/pc/sdpobserver_jni.h"
#include "webrtc/sdk/android/src/jni/pc/statsobserver_jni.h"
#include "webrtc/system_wrappers/include/trace.h"

namespace webrtc_jni {

static rtc::scoped_refptr<webrtc::PeerConnectionInterface> ExtractNativePC(
    JNIEnv* jni,
    jobject j_pc) {
  jfieldID native_pc_id =
      GetFieldID(jni, GetObjectClass(jni, j_pc), "nativePeerConnection", "J");
  jlong j_p = GetLongField(jni, j_pc, native_pc_id);
  return rtc::scoped_refptr<webrtc::PeerConnectionInterface>(
      reinterpret_cast<webrtc::PeerConnectionInterface*>(j_p));
}

JNI_FUNCTION_DECLARATION(void,
                         PeerConnection_freePeerConnection,
                         JNIEnv*,
                         jclass,
                         jlong j_p) {
  CHECK_RELEASE(reinterpret_cast<webrtc::PeerConnectionInterface*>(j_p));
}

JNI_FUNCTION_DECLARATION(void,
                         PeerConnection_freeObserver,
                         JNIEnv*,
                         jclass,
                         jlong j_p) {
  PeerConnectionObserverJni* p =
      reinterpret_cast<PeerConnectionObserverJni*>(j_p);
  delete p;
}

JNI_FUNCTION_DECLARATION(jobject,
                         PeerConnection_getLocalDescription,
                         JNIEnv* jni,
                         jobject j_pc) {
  const webrtc::SessionDescriptionInterface* sdp =
      ExtractNativePC(jni, j_pc)->local_description();
  return sdp ? NativeToJavaSessionDescription(jni, sdp) : NULL;
}

JNI_FUNCTION_DECLARATION(jobject,
                         PeerConnection_getRemoteDescription,
                         JNIEnv* jni,
                         jobject j_pc) {
  const webrtc::SessionDescriptionInterface* sdp =
      ExtractNativePC(jni, j_pc)->remote_description();
  return sdp ? NativeToJavaSessionDescription(jni, sdp) : NULL;
}

JNI_FUNCTION_DECLARATION(jobject,
                         PeerConnection_createDataChannel,
                         JNIEnv* jni,
                         jobject j_pc,
                         jstring j_label,
                         jobject j_init) {
  webrtc::DataChannelInit init = JavaToNativeDataChannelInit(jni, j_init);
  rtc::scoped_refptr<webrtc::DataChannelInterface> channel(
      ExtractNativePC(jni, j_pc)->CreateDataChannel(
          JavaToStdString(jni, j_label), &init));
  // Mustn't pass channel.get() directly through NewObject to avoid reading its
  // vararg parameter as 64-bit and reading memory that doesn't belong to the
  // 32-bit parameter.
  jlong nativeChannelPtr = jlongFromPointer(channel.get());
  if (!nativeChannelPtr) {
    LOG(LS_ERROR) << "Failed to create DataChannel";
    return nullptr;
  }
  jclass j_data_channel_class = FindClass(jni, "org/webrtc/DataChannel");
  jmethodID j_data_channel_ctor =
      GetMethodID(jni, j_data_channel_class, "<init>", "(J)V");
  jobject j_channel = jni->NewObject(j_data_channel_class, j_data_channel_ctor,
                                     nativeChannelPtr);
  CHECK_EXCEPTION(jni) << "error during NewObject";
  // Channel is now owned by Java object, and will be freed from there.
  int bumped_count = channel->AddRef();
  RTC_CHECK(bumped_count == 2) << "Unexpected refcount";
  return j_channel;
}

JNI_FUNCTION_DECLARATION(void,
                         PeerConnection_createOffer,
                         JNIEnv* jni,
                         jobject j_pc,
                         jobject j_observer,
                         jobject j_constraints) {
  MediaConstraintsJni* constraints =
      new MediaConstraintsJni(jni, j_constraints);
  rtc::scoped_refptr<CreateSdpObserverJni> observer(
      new rtc::RefCountedObject<CreateSdpObserverJni>(jni, j_observer,
                                                      constraints));
  ExtractNativePC(jni, j_pc)->CreateOffer(observer, constraints);
}

JNI_FUNCTION_DECLARATION(void,
                         PeerConnection_createAnswer,
                         JNIEnv* jni,
                         jobject j_pc,
                         jobject j_observer,
                         jobject j_constraints) {
  MediaConstraintsJni* constraints =
      new MediaConstraintsJni(jni, j_constraints);
  rtc::scoped_refptr<CreateSdpObserverJni> observer(
      new rtc::RefCountedObject<CreateSdpObserverJni>(jni, j_observer,
                                                      constraints));
  ExtractNativePC(jni, j_pc)->CreateAnswer(observer, constraints);
}

JNI_FUNCTION_DECLARATION(void,
                         PeerConnection_setLocalDescription,
                         JNIEnv* jni,
                         jobject j_pc,
                         jobject j_observer,
                         jobject j_sdp) {
  rtc::scoped_refptr<SetSdpObserverJni> observer(
      new rtc::RefCountedObject<SetSdpObserverJni>(jni, j_observer, nullptr));
  ExtractNativePC(jni, j_pc)->SetLocalDescription(
      observer, JavaToNativeSessionDescription(jni, j_sdp));
}

JNI_FUNCTION_DECLARATION(void,
                         PeerConnection_setRemoteDescription,
                         JNIEnv* jni,
                         jobject j_pc,
                         jobject j_observer,
                         jobject j_sdp) {
  rtc::scoped_refptr<SetSdpObserverJni> observer(
      new rtc::RefCountedObject<SetSdpObserverJni>(jni, j_observer, nullptr));
  ExtractNativePC(jni, j_pc)->SetRemoteDescription(
      observer, JavaToNativeSessionDescription(jni, j_sdp));
}

JNI_FUNCTION_DECLARATION(jboolean,
                         PeerConnection_nativeSetConfiguration,
                         JNIEnv* jni,
                         jobject j_pc,
                         jobject j_rtc_config,
                         jlong native_observer) {
  // Need to merge constraints into RTCConfiguration again, which are stored
  // in the observer object.
  PeerConnectionObserverJni* observer =
      reinterpret_cast<PeerConnectionObserverJni*>(native_observer);
  webrtc::PeerConnectionInterface::RTCConfiguration rtc_config(
      webrtc::PeerConnectionInterface::RTCConfigurationType::kAggressive);
  JavaToNativeRTCConfiguration(jni, j_rtc_config, &rtc_config);
  CopyConstraintsIntoRtcConfiguration(observer->constraints(), &rtc_config);
  return ExtractNativePC(jni, j_pc)->SetConfiguration(rtc_config);
}

JNI_FUNCTION_DECLARATION(jboolean,
                         PeerConnection_nativeAddIceCandidate,
                         JNIEnv* jni,
                         jobject j_pc,
                         jstring j_sdp_mid,
                         jint j_sdp_mline_index,
                         jstring j_candidate_sdp) {
  std::string sdp_mid = JavaToStdString(jni, j_sdp_mid);
  std::string sdp = JavaToStdString(jni, j_candidate_sdp);
  std::unique_ptr<webrtc::IceCandidateInterface> candidate(
      webrtc::CreateIceCandidate(sdp_mid, j_sdp_mline_index, sdp, nullptr));
  return ExtractNativePC(jni, j_pc)->AddIceCandidate(candidate.get());
}

JNI_FUNCTION_DECLARATION(jboolean,
                         PeerConnection_nativeRemoveIceCandidates,
                         JNIEnv* jni,
                         jobject j_pc,
                         jobjectArray j_candidates) {
  std::vector<cricket::Candidate> candidates;
  size_t num_candidates = jni->GetArrayLength(j_candidates);
  for (size_t i = 0; i < num_candidates; ++i) {
    jobject j_candidate = jni->GetObjectArrayElement(j_candidates, i);
    candidates.push_back(JavaToNativeCandidate(jni, j_candidate));
  }
  return ExtractNativePC(jni, j_pc)->RemoveIceCandidates(candidates);
}

JNI_FUNCTION_DECLARATION(jboolean,
                         PeerConnection_nativeAddLocalStream,
                         JNIEnv* jni,
                         jobject j_pc,
                         jlong native_stream) {
  return ExtractNativePC(jni, j_pc)->AddStream(
      reinterpret_cast<webrtc::MediaStreamInterface*>(native_stream));
}

JNI_FUNCTION_DECLARATION(void,
                         PeerConnection_nativeRemoveLocalStream,
                         JNIEnv* jni,
                         jobject j_pc,
                         jlong native_stream) {
  ExtractNativePC(jni, j_pc)->RemoveStream(
      reinterpret_cast<webrtc::MediaStreamInterface*>(native_stream));
}

JNI_FUNCTION_DECLARATION(jobject,
                         PeerConnection_nativeCreateSender,
                         JNIEnv* jni,
                         jobject j_pc,
                         jstring j_kind,
                         jstring j_stream_id) {
  jclass j_rtp_sender_class = FindClass(jni, "org/webrtc/RtpSender");
  jmethodID j_rtp_sender_ctor =
      GetMethodID(jni, j_rtp_sender_class, "<init>", "(J)V");

  std::string kind = JavaToStdString(jni, j_kind);
  std::string stream_id = JavaToStdString(jni, j_stream_id);
  rtc::scoped_refptr<webrtc::RtpSenderInterface> sender =
      ExtractNativePC(jni, j_pc)->CreateSender(kind, stream_id);
  if (!sender.get()) {
    return nullptr;
  }
  jlong nativeSenderPtr = jlongFromPointer(sender.get());
  jobject j_sender =
      jni->NewObject(j_rtp_sender_class, j_rtp_sender_ctor, nativeSenderPtr);
  CHECK_EXCEPTION(jni) << "error during NewObject";
  // Sender is now owned by the Java object, and will be freed from
  // RtpSender.dispose(), called by PeerConnection.dispose() or getSenders().
  sender->AddRef();
  return j_sender;
}

JNI_FUNCTION_DECLARATION(jobject,
                         PeerConnection_nativeGetSenders,
                         JNIEnv* jni,
                         jobject j_pc) {
  jclass j_array_list_class = FindClass(jni, "java/util/ArrayList");
  jmethodID j_array_list_ctor =
      GetMethodID(jni, j_array_list_class, "<init>", "()V");
  jmethodID j_array_list_add =
      GetMethodID(jni, j_array_list_class, "add", "(Ljava/lang/Object;)Z");
  jobject j_senders = jni->NewObject(j_array_list_class, j_array_list_ctor);
  CHECK_EXCEPTION(jni) << "error during NewObject";

  jclass j_rtp_sender_class = FindClass(jni, "org/webrtc/RtpSender");
  jmethodID j_rtp_sender_ctor =
      GetMethodID(jni, j_rtp_sender_class, "<init>", "(J)V");

  auto senders = ExtractNativePC(jni, j_pc)->GetSenders();
  for (const auto& sender : senders) {
    jlong nativeSenderPtr = jlongFromPointer(sender.get());
    jobject j_sender =
        jni->NewObject(j_rtp_sender_class, j_rtp_sender_ctor, nativeSenderPtr);
    CHECK_EXCEPTION(jni) << "error during NewObject";
    // Sender is now owned by the Java object, and will be freed from
    // RtpSender.dispose(), called by PeerConnection.dispose() or getSenders().
    sender->AddRef();
    jni->CallBooleanMethod(j_senders, j_array_list_add, j_sender);
    CHECK_EXCEPTION(jni) << "error during CallBooleanMethod";
  }
  return j_senders;
}

JNI_FUNCTION_DECLARATION(jobject,
                         PeerConnection_nativeGetReceivers,
                         JNIEnv* jni,
                         jobject j_pc) {
  jclass j_array_list_class = FindClass(jni, "java/util/ArrayList");
  jmethodID j_array_list_ctor =
      GetMethodID(jni, j_array_list_class, "<init>", "()V");
  jmethodID j_array_list_add =
      GetMethodID(jni, j_array_list_class, "add", "(Ljava/lang/Object;)Z");
  jobject j_receivers = jni->NewObject(j_array_list_class, j_array_list_ctor);
  CHECK_EXCEPTION(jni) << "error during NewObject";

  jclass j_rtp_receiver_class = FindClass(jni, "org/webrtc/RtpReceiver");
  jmethodID j_rtp_receiver_ctor =
      GetMethodID(jni, j_rtp_receiver_class, "<init>", "(J)V");

  auto receivers = ExtractNativePC(jni, j_pc)->GetReceivers();
  for (const auto& receiver : receivers) {
    jlong nativeReceiverPtr = jlongFromPointer(receiver.get());
    jobject j_receiver = jni->NewObject(j_rtp_receiver_class,
                                        j_rtp_receiver_ctor, nativeReceiverPtr);
    CHECK_EXCEPTION(jni) << "error during NewObject";
    // Receiver is now owned by Java object, and will be freed from there.
    receiver->AddRef();
    jni->CallBooleanMethod(j_receivers, j_array_list_add, j_receiver);
    CHECK_EXCEPTION(jni) << "error during CallBooleanMethod";
  }
  return j_receivers;
}

JNI_FUNCTION_DECLARATION(bool,
                         PeerConnection_nativeOldGetStats,
                         JNIEnv* jni,
                         jobject j_pc,
                         jobject j_observer,
                         jlong native_track) {
  rtc::scoped_refptr<StatsObserverJni> observer(
      new rtc::RefCountedObject<StatsObserverJni>(jni, j_observer));
  return ExtractNativePC(jni, j_pc)->GetStats(
      observer,
      reinterpret_cast<webrtc::MediaStreamTrackInterface*>(native_track),
      webrtc::PeerConnectionInterface::kStatsOutputLevelStandard);
}

JNI_FUNCTION_DECLARATION(void,
                         PeerConnection_nativeNewGetStats,
                         JNIEnv* jni,
                         jobject j_pc,
                         jobject j_callback) {
  rtc::scoped_refptr<RTCStatsCollectorCallbackWrapper> callback(
      new rtc::RefCountedObject<RTCStatsCollectorCallbackWrapper>(jni,
                                                                  j_callback));
  ExtractNativePC(jni, j_pc)->GetStats(callback);
}

JNI_FUNCTION_DECLARATION(jboolean,
                         PeerConnection_setBitrate,
                         JNIEnv* jni,
                         jobject j_pc,
                         jobject j_min,
                         jobject j_current,
                         jobject j_max) {
  webrtc::PeerConnectionInterface::BitrateParameters params;
  jclass j_integer_class = jni->FindClass("java/lang/Integer");
  jmethodID int_value_id = GetMethodID(jni, j_integer_class, "intValue", "()I");
  if (!IsNull(jni, j_min)) {
    int min_value = jni->CallIntMethod(j_min, int_value_id);
    params.min_bitrate_bps = rtc::Optional<int>(min_value);
  }
  if (!IsNull(jni, j_current)) {
    int current_value = jni->CallIntMethod(j_current, int_value_id);
    params.current_bitrate_bps = rtc::Optional<int>(current_value);
  }
  if (!IsNull(jni, j_max)) {
    int max_value = jni->CallIntMethod(j_max, int_value_id);
    params.max_bitrate_bps = rtc::Optional<int>(max_value);
  }
  return ExtractNativePC(jni, j_pc)->SetBitrate(params).ok();
}

JNI_FUNCTION_DECLARATION(bool,
                         PeerConnection_nativeStartRtcEventLog,
                         JNIEnv* jni,
                         jobject j_pc,
                         int file_descriptor,
                         int max_size_bytes) {
  return ExtractNativePC(jni, j_pc)->StartRtcEventLog(file_descriptor,
                                                      max_size_bytes);
}

JNI_FUNCTION_DECLARATION(void,
                         PeerConnection_nativeStopRtcEventLog,
                         JNIEnv* jni,
                         jobject j_pc) {
  ExtractNativePC(jni, j_pc)->StopRtcEventLog();
}

JNI_FUNCTION_DECLARATION(jobject,
                         PeerConnection_signalingState,
                         JNIEnv* jni,
                         jobject j_pc) {
  webrtc::PeerConnectionInterface::SignalingState state =
      ExtractNativePC(jni, j_pc)->signaling_state();
  return JavaEnumFromIndexAndClassName(jni, "PeerConnection$SignalingState",
                                       state);
}

JNI_FUNCTION_DECLARATION(jobject,
                         PeerConnection_iceConnectionState,
                         JNIEnv* jni,
                         jobject j_pc) {
  webrtc::PeerConnectionInterface::IceConnectionState state =
      ExtractNativePC(jni, j_pc)->ice_connection_state();
  return JavaEnumFromIndexAndClassName(jni, "PeerConnection$IceConnectionState",
                                       state);
}

JNI_FUNCTION_DECLARATION(jobject,
                         PeerConnection_iceGatheringState,
                         JNIEnv* jni,
                         jobject j_pc) {
  webrtc::PeerConnectionInterface::IceGatheringState state =
      ExtractNativePC(jni, j_pc)->ice_gathering_state();
  return JavaEnumFromIndexAndClassName(jni, "PeerConnection$IceGatheringState",
                                       state);
}

JNI_FUNCTION_DECLARATION(void,
                         PeerConnection_close,
                         JNIEnv* jni,
                         jobject j_pc) {
  ExtractNativePC(jni, j_pc)->Close();
  return;
}

}  // namespace webrtc_jni
