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

#ifndef SDK_ANDROID_SRC_JNI_PC_PEER_CONNECTION_H_
#define SDK_ANDROID_SRC_JNI_PC_PEER_CONNECTION_H_

#include <map>
#include <memory>
#include <vector>

#include "api/peer_connection_interface.h"
#include "pc/media_stream_observer.h"
#include "sdk/android/src/jni/jni_helpers.h"
#include "sdk/android/src/jni/pc/media_constraints.h"
#include "sdk/android/src/jni/pc/media_stream.h"
#include "sdk/android/src/jni/pc/rtp_receiver.h"
#include "sdk/android/src/jni/pc/rtp_transceiver.h"

namespace webrtc {
namespace jni {

void JavaToNativeRTCConfiguration(
    JNIEnv* jni,
    const JavaRef<jobject>& j_rtc_config,
    PeerConnectionInterface::RTCConfiguration* rtc_config);

rtc::KeyType GetRtcConfigKeyType(JNIEnv* env,
                                 const JavaRef<jobject>& j_rtc_config);

ScopedJavaLocalRef<jobject> NativeToJavaAdapterType(JNIEnv* env,
                                                    int adapterType);

// Adapter between the C++ PeerConnectionObserver interface and the Java
// PeerConnection.Observer interface.  Wraps an instance of the Java interface
// and dispatches C++ callbacks to Java.
class PeerConnectionObserverJni : public PeerConnectionObserver {
 public:
  PeerConnectionObserverJni(JNIEnv* jni, const JavaRef<jobject>& j_observer);
  ~PeerConnectionObserverJni() override;

  // Implementation of PeerConnectionObserver interface, which propagates
  // the callbacks to the Java observer.
  void OnIceCandidate(const IceCandidateInterface* candidate) override;
  void OnIceCandidatesRemoved(
      const std::vector<cricket::Candidate>& candidates) override;
  void OnSignalingChange(
      PeerConnectionInterface::SignalingState new_state) override;
  void OnIceConnectionChange(
      PeerConnectionInterface::IceConnectionState new_state) override;
  void OnStandardizedIceConnectionChange(
      PeerConnectionInterface::IceConnectionState new_state) override;
  void OnConnectionChange(
      PeerConnectionInterface::PeerConnectionState new_state) override;
  void OnIceConnectionReceivingChange(bool receiving) override;
  void OnIceGatheringChange(
      PeerConnectionInterface::IceGatheringState new_state) override;
  void OnIceSelectedCandidatePairChanged(
      const cricket::CandidatePairChangeEvent& event) override;
  void OnAddStream(rtc::scoped_refptr<MediaStreamInterface> stream) override;
  void OnRemoveStream(rtc::scoped_refptr<MediaStreamInterface> stream) override;
  void OnDataChannel(rtc::scoped_refptr<DataChannelInterface> channel) override;
  void OnRenegotiationNeeded() override;
  void OnAddTrack(rtc::scoped_refptr<RtpReceiverInterface> receiver,
                  const std::vector<rtc::scoped_refptr<MediaStreamInterface>>&
                      streams) override;
  void OnTrack(
      rtc::scoped_refptr<RtpTransceiverInterface> transceiver) override;
  void OnRemoveTrack(
      rtc::scoped_refptr<RtpReceiverInterface> receiver) override;

 private:
  typedef std::map<MediaStreamInterface*, JavaMediaStream>
      NativeToJavaStreamsMap;
  typedef std::map<MediaStreamTrackInterface*, RtpReceiverInterface*>
      NativeMediaStreamTrackToNativeRtpReceiver;

  // If the NativeToJavaStreamsMap contains the stream, return it.
  // Otherwise, create a new Java MediaStream. Returns a global jobject.
  JavaMediaStream& GetOrCreateJavaStream(
      JNIEnv* env,
      const rtc::scoped_refptr<MediaStreamInterface>& stream);

  // Converts array of streams, creating or re-using Java streams as necessary.
  ScopedJavaLocalRef<jobjectArray> NativeToJavaMediaStreamArray(
      JNIEnv* jni,
      const std::vector<rtc::scoped_refptr<MediaStreamInterface>>& streams);

  const ScopedJavaGlobalRef<jobject> j_observer_global_;

  // C++ -> Java remote streams.
  NativeToJavaStreamsMap remote_streams_;
  std::vector<JavaRtpReceiverGlobalOwner> rtp_receivers_;
  // Holds a reference to the Java transceivers given to the AddTrack
  // callback, so that the shared ownership by the Java object will be
  // properly disposed.
  std::vector<JavaRtpTransceiverGlobalOwner> rtp_transceivers_;
};

// PeerConnection doesn't take ownership of the observer. In Java API, we don't
// want the client to have to manually dispose the observer. To solve this, this
// wrapper class is used for object ownership.
//
// Also stores reference to the deprecated PeerConnection constraints for now.
class OwnedPeerConnection {
 public:
  OwnedPeerConnection(
      rtc::scoped_refptr<PeerConnectionInterface> peer_connection,
      std::unique_ptr<PeerConnectionObserver> observer);
  // Deprecated. PC constraints are deprecated.
  OwnedPeerConnection(
      rtc::scoped_refptr<PeerConnectionInterface> peer_connection,
      std::unique_ptr<PeerConnectionObserver> observer,
      std::unique_ptr<MediaConstraints> constraints);
  ~OwnedPeerConnection();

  PeerConnectionInterface* pc() const { return peer_connection_.get(); }
  const MediaConstraints* constraints() const { return constraints_.get(); }

 private:
  rtc::scoped_refptr<PeerConnectionInterface> peer_connection_;
  std::unique_ptr<PeerConnectionObserver> observer_;
  std::unique_ptr<MediaConstraints> constraints_;
};

}  // namespace jni
}  // namespace webrtc

#endif  // SDK_ANDROID_SRC_JNI_PC_PEER_CONNECTION_H_
