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

#include <pc/mediastreamobserver.h>
#include <string>

#include "rtc_base/ptr_util.h"
#include "sdk/android/src/jni/classreferenceholder.h"
#include "sdk/android/src/jni/pc/java_native_conversion.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();
}

PeerConnectionObserverJni::PeerConnectionObserverJni(JNIEnv* jni,
                                                     jobject j_observer)
    : j_observer_global_(jni, j_observer),
      j_observer_class_(jni, GetObjectClass(jni, *j_observer_global_)),
      j_media_stream_class_(jni, FindClass(jni, "org/webrtc/MediaStream")),
      j_media_stream_ctor_(
          GetMethodID(jni, *j_media_stream_class_, "<init>", "(J)V")),
      j_media_stream_track_class_(
          jni,
          FindClass(jni, "org/webrtc/MediaStreamTrack")),
      j_track_dispose_id_(
          GetMethodID(jni, *j_media_stream_track_class_, "dispose", "()V")),
      j_native_track_id_(
          GetFieldID(jni, *j_media_stream_track_class_, "nativeTrack", "J")),
      j_audio_track_class_(jni, FindClass(jni, "org/webrtc/AudioTrack")),
      j_audio_track_ctor_(
          GetMethodID(jni, *j_audio_track_class_, "<init>", "(J)V")),
      j_video_track_class_(jni, FindClass(jni, "org/webrtc/VideoTrack")),
      j_video_track_ctor_(
          GetMethodID(jni, *j_video_track_class_, "<init>", "(J)V")),
      j_data_channel_class_(jni, FindClass(jni, "org/webrtc/DataChannel")),
      j_data_channel_ctor_(
          GetMethodID(jni, *j_data_channel_class_, "<init>", "(J)V")),
      j_rtp_receiver_class_(jni, FindClass(jni, "org/webrtc/RtpReceiver")),
      j_rtp_receiver_ctor_(
          GetMethodID(jni, *j_rtp_receiver_class_, "<init>", "(J)V")) {}

PeerConnectionObserverJni::~PeerConnectionObserverJni() {
  ScopedLocalRefFrame local_ref_frame(jni());
  while (!remote_streams_.empty())
    DisposeRemoteStream(remote_streams_.begin());
  while (!rtp_receivers_.empty())
    DisposeRtpReceiver(rtp_receivers_.begin());
}

void PeerConnectionObserverJni::OnIceCandidate(
    const IceCandidateInterface* candidate) {
  ScopedLocalRefFrame local_ref_frame(jni());
  std::string sdp;
  RTC_CHECK(candidate->ToString(&sdp)) << "got so far: " << sdp;
  jclass candidate_class = FindClass(jni(), "org/webrtc/IceCandidate");
  jmethodID ctor =
      GetMethodID(jni(), candidate_class, "<init>",
                  "(Ljava/lang/String;ILjava/lang/String;Ljava/lang/String;)V");
  jstring j_mid = JavaStringFromStdString(jni(), candidate->sdp_mid());
  jstring j_sdp = JavaStringFromStdString(jni(), sdp);
  jstring j_url = JavaStringFromStdString(jni(), candidate->candidate().url());
  jobject j_candidate = jni()->NewObject(
      candidate_class, ctor, j_mid, candidate->sdp_mline_index(), j_sdp, j_url);
  CHECK_EXCEPTION(jni()) << "error during NewObject";
  jmethodID m = GetMethodID(jni(), *j_observer_class_, "onIceCandidate",
                            "(Lorg/webrtc/IceCandidate;)V");
  jni()->CallVoidMethod(*j_observer_global_, m, j_candidate);
  CHECK_EXCEPTION(jni()) << "error during CallVoidMethod";
}

void PeerConnectionObserverJni::OnIceCandidatesRemoved(
    const std::vector<cricket::Candidate>& candidates) {
  ScopedLocalRefFrame local_ref_frame(jni());
  jobjectArray candidates_array = NativeToJavaCandidateArray(jni(), candidates);
  jmethodID m = GetMethodID(jni(), *j_observer_class_, "onIceCandidatesRemoved",
                            "([Lorg/webrtc/IceCandidate;)V");
  jni()->CallVoidMethod(*j_observer_global_, m, candidates_array);
  CHECK_EXCEPTION(jni()) << "Error during CallVoidMethod";
}

void PeerConnectionObserverJni::OnSignalingChange(
    PeerConnectionInterface::SignalingState new_state) {
  ScopedLocalRefFrame local_ref_frame(jni());
  jmethodID m = GetMethodID(jni(), *j_observer_class_, "onSignalingChange",
                            "(Lorg/webrtc/PeerConnection$SignalingState;)V");
  jobject new_state_enum = JavaEnumFromIndexAndClassName(
      jni(), "PeerConnection$SignalingState", new_state);
  jni()->CallVoidMethod(*j_observer_global_, m, new_state_enum);
  CHECK_EXCEPTION(jni()) << "error during CallVoidMethod";
}

void PeerConnectionObserverJni::OnIceConnectionChange(
    PeerConnectionInterface::IceConnectionState new_state) {
  ScopedLocalRefFrame local_ref_frame(jni());
  jmethodID m =
      GetMethodID(jni(), *j_observer_class_, "onIceConnectionChange",
                  "(Lorg/webrtc/PeerConnection$IceConnectionState;)V");
  jobject new_state_enum = JavaEnumFromIndexAndClassName(
      jni(), "PeerConnection$IceConnectionState", new_state);
  jni()->CallVoidMethod(*j_observer_global_, m, new_state_enum);
  CHECK_EXCEPTION(jni()) << "error during CallVoidMethod";
}

void PeerConnectionObserverJni::OnIceConnectionReceivingChange(bool receiving) {
  ScopedLocalRefFrame local_ref_frame(jni());
  jmethodID m = GetMethodID(jni(), *j_observer_class_,
                            "onIceConnectionReceivingChange", "(Z)V");
  jni()->CallVoidMethod(*j_observer_global_, m, receiving);
  CHECK_EXCEPTION(jni()) << "error during CallVoidMethod";
}

void PeerConnectionObserverJni::OnIceGatheringChange(
    PeerConnectionInterface::IceGatheringState new_state) {
  ScopedLocalRefFrame local_ref_frame(jni());
  jmethodID m = GetMethodID(jni(), *j_observer_class_, "onIceGatheringChange",
                            "(Lorg/webrtc/PeerConnection$IceGatheringState;)V");
  jobject new_state_enum = JavaEnumFromIndexAndClassName(
      jni(), "PeerConnection$IceGatheringState", new_state);
  jni()->CallVoidMethod(*j_observer_global_, m, new_state_enum);
  CHECK_EXCEPTION(jni()) << "error during CallVoidMethod";
}

void PeerConnectionObserverJni::OnAddStream(
    rtc::scoped_refptr<MediaStreamInterface> stream) {
  ScopedLocalRefFrame local_ref_frame(jni());
  // The stream could be added into the remote_streams_ map when calling
  // OnAddTrack.
  jobject j_stream = GetOrCreateJavaStream(stream);

  for (const auto& track : stream->GetAudioTracks()) {
    AddNativeAudioTrackToJavaStream(track, j_stream);
  }
  for (const auto& track : stream->GetVideoTracks()) {
    AddNativeVideoTrackToJavaStream(track, j_stream);
  }

  jmethodID m = GetMethodID(jni(), *j_observer_class_, "onAddStream",
                            "(Lorg/webrtc/MediaStream;)V");
  jni()->CallVoidMethod(*j_observer_global_, m, j_stream);
  CHECK_EXCEPTION(jni()) << "error during CallVoidMethod";

  // Create an observer to update the Java stream when the native stream's set
  // of tracks changes.
  auto observer = rtc::MakeUnique<MediaStreamObserver>(stream);
  observer->SignalAudioTrackRemoved.connect(
      this, &PeerConnectionObserverJni::OnAudioTrackRemovedFromStream);
  observer->SignalVideoTrackRemoved.connect(
      this, &PeerConnectionObserverJni::OnVideoTrackRemovedFromStream);
  observer->SignalAudioTrackAdded.connect(
      this, &PeerConnectionObserverJni::OnAudioTrackAddedToStream);
  observer->SignalVideoTrackAdded.connect(
      this, &PeerConnectionObserverJni::OnVideoTrackAddedToStream);
  stream_observers_.push_back(std::move(observer));
}

void PeerConnectionObserverJni::AddNativeAudioTrackToJavaStream(
    rtc::scoped_refptr<AudioTrackInterface> track,
    jobject j_stream) {
  jstring id = JavaStringFromStdString(jni(), track->id());
  // Java AudioTrack holds one reference. Corresponding Release() is in
  // MediaStreamTrack_free, triggered by AudioTrack.dispose().
  track->AddRef();
  jobject j_track = jni()->NewObject(*j_audio_track_class_, j_audio_track_ctor_,
                                     reinterpret_cast<jlong>(track.get()), id);
  CHECK_EXCEPTION(jni()) << "error during NewObject";

  // Now add to the audioTracks linked list.
  jfieldID audio_tracks_id = GetFieldID(jni(), *j_media_stream_class_,
                                        "audioTracks", "Ljava/util/List;");
  jobject audio_tracks = GetObjectField(jni(), j_stream, audio_tracks_id);
  jmethodID add = GetMethodID(jni(), GetObjectClass(jni(), audio_tracks), "add",
                              "(Ljava/lang/Object;)Z");
  jboolean added = jni()->CallBooleanMethod(audio_tracks, add, j_track);
  CHECK_EXCEPTION(jni()) << "error during CallBooleanMethod";
  RTC_CHECK(added);
}

void PeerConnectionObserverJni::AddNativeVideoTrackToJavaStream(
    rtc::scoped_refptr<VideoTrackInterface> track,
    jobject j_stream) {
  jstring id = JavaStringFromStdString(jni(), track->id());
  // Java VideoTrack holds one reference. Corresponding Release() is in
  // MediaStreamTrack_free, triggered by VideoTrack.dispose().
  track->AddRef();
  jobject j_track = jni()->NewObject(*j_video_track_class_, j_video_track_ctor_,
                                     reinterpret_cast<jlong>(track.get()), id);
  CHECK_EXCEPTION(jni()) << "error during NewObject";

  // Now add to the videoTracks linked list.
  jfieldID video_tracks_id = GetFieldID(jni(), *j_media_stream_class_,
                                        "videoTracks", "Ljava/util/List;");
  jobject video_tracks = GetObjectField(jni(), j_stream, video_tracks_id);
  jmethodID add = GetMethodID(jni(), GetObjectClass(jni(), video_tracks), "add",
                              "(Ljava/lang/Object;)Z");
  jboolean added = jni()->CallBooleanMethod(video_tracks, add, j_track);
  CHECK_EXCEPTION(jni()) << "error during CallBooleanMethod";
  RTC_CHECK(added);
}

void PeerConnectionObserverJni::RemoveAndDisposeNativeTrackFromJavaTrackList(
    MediaStreamTrackInterface* track,
    jobject j_tracks) {
  Iterable iterable_tracks(jni(), j_tracks);
  for (auto it = iterable_tracks.begin(); it != iterable_tracks.end(); ++it) {
    MediaStreamTrackInterface* native_track =
        reinterpret_cast<MediaStreamTrackInterface*>(
            jni()->GetLongField(*it, j_native_track_id_));
    CHECK_EXCEPTION(jni()) << "error during GetLongField";
    if (native_track == track) {
      jni()->CallVoidMethod(*it, j_track_dispose_id_);
      it.Remove();
      return;
    }
  }
  // If we reached this point, we didn't find the track, which means we're
  // getting a "track removed" callback but the Java stream doesn't have a
  // corresponding track, which indicates a bug somewhere.
  RTC_NOTREACHED();
}

void PeerConnectionObserverJni::OnAudioTrackAddedToStream(
    AudioTrackInterface* track,
    MediaStreamInterface* stream) {
  ScopedLocalRefFrame local_ref_frame(jni());
  jobject j_stream = GetOrCreateJavaStream(stream);
  AddNativeAudioTrackToJavaStream(track, j_stream);
}

void PeerConnectionObserverJni::OnVideoTrackAddedToStream(
    VideoTrackInterface* track,
    MediaStreamInterface* stream) {
  ScopedLocalRefFrame local_ref_frame(jni());
  jobject j_stream = GetOrCreateJavaStream(stream);
  AddNativeVideoTrackToJavaStream(track, j_stream);
}

void PeerConnectionObserverJni::OnAudioTrackRemovedFromStream(
    AudioTrackInterface* track,
    MediaStreamInterface* stream) {
  ScopedLocalRefFrame local_ref_frame(jni());
  jobject j_stream = GetOrCreateJavaStream(stream);
  jfieldID audio_tracks_id = GetFieldID(jni(), *j_media_stream_class_,
                                        "audioTracks", "Ljava/util/List;");
  jobject audio_tracks = GetObjectField(jni(), j_stream, audio_tracks_id);
  RemoveAndDisposeNativeTrackFromJavaTrackList(track, audio_tracks);
}

void PeerConnectionObserverJni::OnVideoTrackRemovedFromStream(
    VideoTrackInterface* track,
    MediaStreamInterface* stream) {
  ScopedLocalRefFrame local_ref_frame(jni());
  jobject j_stream = GetOrCreateJavaStream(stream);
  jfieldID video_tracks_id = GetFieldID(jni(), *j_media_stream_class_,
                                        "videoTracks", "Ljava/util/List;");
  jobject video_tracks = GetObjectField(jni(), j_stream, video_tracks_id);
  RemoveAndDisposeNativeTrackFromJavaTrackList(track, video_tracks);
}

void PeerConnectionObserverJni::OnRemoveStream(
    rtc::scoped_refptr<MediaStreamInterface> stream) {
  ScopedLocalRefFrame local_ref_frame(jni());
  NativeToJavaStreamsMap::iterator it = remote_streams_.find(stream);
  RTC_CHECK(it != remote_streams_.end())
      << "unexpected stream: " << std::hex << stream;
  jobject j_stream = it->second;
  jmethodID m = GetMethodID(jni(), *j_observer_class_, "onRemoveStream",
                            "(Lorg/webrtc/MediaStream;)V");
  jni()->CallVoidMethod(*j_observer_global_, m, j_stream);
  CHECK_EXCEPTION(jni()) << "error during CallVoidMethod";

  // Release the refptr reference so that DisposeRemoteStream can assert
  // it removes the final reference.
  stream = nullptr;
  DisposeRemoteStream(it);
}

void PeerConnectionObserverJni::OnDataChannel(
    rtc::scoped_refptr<DataChannelInterface> channel) {
  ScopedLocalRefFrame local_ref_frame(jni());
  jobject j_channel =
      jni()->NewObject(*j_data_channel_class_, j_data_channel_ctor_,
                       jlongFromPointer(channel.get()));
  CHECK_EXCEPTION(jni()) << "error during NewObject";

  jmethodID m = GetMethodID(jni(), *j_observer_class_, "onDataChannel",
                            "(Lorg/webrtc/DataChannel;)V");
  jni()->CallVoidMethod(*j_observer_global_, m, j_channel);

  // Channel is now owned by Java object, and will be freed from
  // DataChannel.dispose().  Important that this be done _after_ the
  // CallVoidMethod above as Java code might call back into native code and be
  // surprised to see a refcount of 2.
  channel->AddRef();

  CHECK_EXCEPTION(jni()) << "error during CallVoidMethod";
}

void PeerConnectionObserverJni::OnRenegotiationNeeded() {
  ScopedLocalRefFrame local_ref_frame(jni());
  jmethodID m =
      GetMethodID(jni(), *j_observer_class_, "onRenegotiationNeeded", "()V");
  jni()->CallVoidMethod(*j_observer_global_, m);
  CHECK_EXCEPTION(jni()) << "error during CallVoidMethod";
}

void PeerConnectionObserverJni::OnAddTrack(
    rtc::scoped_refptr<RtpReceiverInterface> receiver,
    const std::vector<rtc::scoped_refptr<MediaStreamInterface>>& streams) {
  ScopedLocalRefFrame local_ref_frame(jni());
  jobject j_rtp_receiver =
      jni()->NewObject(*j_rtp_receiver_class_, j_rtp_receiver_ctor_,
                       jlongFromPointer(receiver.get()));
  CHECK_EXCEPTION(jni()) << "error during NewObject";
  receiver->AddRef();
  rtp_receivers_[receiver] = NewGlobalRef(jni(), j_rtp_receiver);

  jobjectArray j_stream_array = NativeToJavaMediaStreamArray(jni(), streams);
  jmethodID m =
      GetMethodID(jni(), *j_observer_class_, "onAddTrack",
                  "(Lorg/webrtc/RtpReceiver;[Lorg/webrtc/MediaStream;)V");
  jni()->CallVoidMethod(*j_observer_global_, m, j_rtp_receiver, j_stream_array);
  CHECK_EXCEPTION(jni()) << "Error during CallVoidMethod";
}

void PeerConnectionObserverJni::SetConstraints(
    MediaConstraintsJni* constraints) {
  RTC_CHECK(!constraints_.get()) << "constraints already set!";
  constraints_.reset(constraints);
}

void PeerConnectionObserverJni::DisposeRemoteStream(
    const NativeToJavaStreamsMap::iterator& it) {
  MediaStreamInterface* stream = it->first;
  jobject j_stream = it->second;

  // Remove the observer first, so it doesn't react to events during deletion.
  stream_observers_.erase(
      std::remove_if(
          stream_observers_.begin(), stream_observers_.end(),
          [stream](const std::unique_ptr<MediaStreamObserver>& observer) {
            return observer->stream() == stream;
          }),
      stream_observers_.end());

  remote_streams_.erase(it);
  jni()->CallVoidMethod(
      j_stream, GetMethodID(jni(), *j_media_stream_class_, "dispose", "()V"));
  CHECK_EXCEPTION(jni()) << "error during MediaStream.dispose()";
  DeleteGlobalRef(jni(), j_stream);
}

void PeerConnectionObserverJni::DisposeRtpReceiver(
    const NativeToJavaRtpReceiverMap::iterator& it) {
  jobject j_rtp_receiver = it->second;
  rtp_receivers_.erase(it);
  jni()->CallVoidMethod(
      j_rtp_receiver,
      GetMethodID(jni(), *j_rtp_receiver_class_, "dispose", "()V"));
  CHECK_EXCEPTION(jni()) << "error during RtpReceiver.dispose()";
  DeleteGlobalRef(jni(), j_rtp_receiver);
}

// If the NativeToJavaStreamsMap contains the stream, return it.
// Otherwise, create a new Java MediaStream.
jobject PeerConnectionObserverJni::GetOrCreateJavaStream(
    const rtc::scoped_refptr<MediaStreamInterface>& stream) {
  NativeToJavaStreamsMap::iterator it = remote_streams_.find(stream);
  if (it != remote_streams_.end()) {
    return it->second;
  }
  // Java MediaStream holds one reference. Corresponding Release() is in
  // MediaStream_free, triggered by MediaStream.dispose().
  stream->AddRef();
  jobject j_stream =
      jni()->NewObject(*j_media_stream_class_, j_media_stream_ctor_,
                       reinterpret_cast<jlong>(stream.get()));
  CHECK_EXCEPTION(jni()) << "error during NewObject";

  remote_streams_[stream] = NewGlobalRef(jni(), j_stream);
  return j_stream;
}

jobjectArray PeerConnectionObserverJni::NativeToJavaMediaStreamArray(
    JNIEnv* jni,
    const std::vector<rtc::scoped_refptr<MediaStreamInterface>>& streams) {
  jobjectArray java_streams =
      jni->NewObjectArray(streams.size(), *j_media_stream_class_, nullptr);
  CHECK_EXCEPTION(jni) << "error during NewObjectArray";
  for (size_t i = 0; i < streams.size(); ++i) {
    jobject j_stream = GetOrCreateJavaStream(streams[i]);
    jni->SetObjectArrayElement(java_streams, i, j_stream);
  }
  return java_streams;
}

}  // namespace jni
}  // namespace webrtc
