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

package org.webrtc;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import javax.annotation.Nullable;

/**
 * Java-land version of the PeerConnection APIs; wraps the C++ API
 * http://www.webrtc.org/reference/native-apis, which in turn is inspired by the
 * JS APIs: http://dev.w3.org/2011/webrtc/editor/webrtc.html and
 * http://www.w3.org/TR/mediacapture-streams/
 */
@JNINamespace("webrtc::jni")
public class PeerConnection {
  /** Tracks PeerConnectionInterface::IceGatheringState */
  public enum IceGatheringState {
    NEW,
    GATHERING,
    COMPLETE;

    @CalledByNative("IceGatheringState")
    static IceGatheringState fromNativeIndex(int nativeIndex) {
      return values()[nativeIndex];
    }
  }

  /** Tracks PeerConnectionInterface::IceConnectionState */
  public enum IceConnectionState {
    NEW,
    CHECKING,
    CONNECTED,
    COMPLETED,
    FAILED,
    DISCONNECTED,
    CLOSED;

    @CalledByNative("IceConnectionState")
    static IceConnectionState fromNativeIndex(int nativeIndex) {
      return values()[nativeIndex];
    }
  }

  /** Tracks PeerConnectionInterface::TlsCertPolicy */
  public enum TlsCertPolicy {
    TLS_CERT_POLICY_SECURE,
    TLS_CERT_POLICY_INSECURE_NO_CHECK,
  }

  /** Tracks PeerConnectionInterface::SignalingState */
  public enum SignalingState {
    STABLE,
    HAVE_LOCAL_OFFER,
    HAVE_LOCAL_PRANSWER,
    HAVE_REMOTE_OFFER,
    HAVE_REMOTE_PRANSWER,
    CLOSED;

    @CalledByNative("SignalingState")
    static SignalingState fromNativeIndex(int nativeIndex) {
      return values()[nativeIndex];
    }
  }

  /** Java version of PeerConnectionObserver. */
  public static interface Observer {
    /** Triggered when the SignalingState changes. */
    @CalledByNative("Observer") void onSignalingChange(SignalingState newState);

    /** Triggered when the IceConnectionState changes. */
    @CalledByNative("Observer") void onIceConnectionChange(IceConnectionState newState);

    /** Triggered when the ICE connection receiving status changes. */
    @CalledByNative("Observer") void onIceConnectionReceivingChange(boolean receiving);

    /** Triggered when the IceGatheringState changes. */
    @CalledByNative("Observer") void onIceGatheringChange(IceGatheringState newState);

    /** Triggered when a new ICE candidate has been found. */
    @CalledByNative("Observer") void onIceCandidate(IceCandidate candidate);

    /** Triggered when some ICE candidates have been removed. */
    @CalledByNative("Observer") void onIceCandidatesRemoved(IceCandidate[] candidates);

    /** Triggered when media is received on a new stream from remote peer. */
    @CalledByNative("Observer") void onAddStream(MediaStream stream);

    /** Triggered when a remote peer close a stream. */
    @CalledByNative("Observer") void onRemoveStream(MediaStream stream);

    /** Triggered when a remote peer opens a DataChannel. */
    @CalledByNative("Observer") void onDataChannel(DataChannel dataChannel);

    /** Triggered when renegotiation is necessary. */
    @CalledByNative("Observer") void onRenegotiationNeeded();

    /**
     * Triggered when a new track is signaled by the remote peer, as a result of
     * setRemoteDescription.
     */
    @CalledByNative("Observer") void onAddTrack(RtpReceiver receiver, MediaStream[] mediaStreams);

    /**
     * Triggered when the signaling from SetRemoteDescription indicates that a transceiver
     * will be receiving media from a remote endpoint. This is only called if UNIFIED_PLAN
     * semantics are specified. The transceiver will be disposed automatically.
     */
    @CalledByNative("Observer") default void onTrack(RtpTransceiver transceiver){};
  }

  /** Java version of PeerConnectionInterface.IceServer. */
  public static class IceServer {
    // List of URIs associated with this server. Valid formats are described
    // in RFC7064 and RFC7065, and more may be added in the future. The "host"
    // part of the URI may contain either an IP address or a hostname.
    @Deprecated public final String uri;
    public final List<String> urls;
    public final String username;
    public final String password;
    public final TlsCertPolicy tlsCertPolicy;

    // If the URIs in |urls| only contain IP addresses, this field can be used
    // to indicate the hostname, which may be necessary for TLS (using the SNI
    // extension). If |urls| itself contains the hostname, this isn't
    // necessary.
    public final String hostname;

    // List of protocols to be used in the TLS ALPN extension.
    public final List<String> tlsAlpnProtocols;

    // List of elliptic curves to be used in the TLS elliptic curves extension.
    // Only curve names supported by OpenSSL should be used (eg. "P-256","X25519").
    public final List<String> tlsEllipticCurves;

    /** Convenience constructor for STUN servers. */
    @Deprecated
    public IceServer(String uri) {
      this(uri, "", "");
    }

    @Deprecated
    public IceServer(String uri, String username, String password) {
      this(uri, username, password, TlsCertPolicy.TLS_CERT_POLICY_SECURE);
    }

    @Deprecated
    public IceServer(String uri, String username, String password, TlsCertPolicy tlsCertPolicy) {
      this(uri, username, password, tlsCertPolicy, "");
    }

    @Deprecated
    public IceServer(String uri, String username, String password, TlsCertPolicy tlsCertPolicy,
        String hostname) {
      this(uri, Collections.singletonList(uri), username, password, tlsCertPolicy, hostname, null,
          null);
    }

    private IceServer(String uri, List<String> urls, String username, String password,
        TlsCertPolicy tlsCertPolicy, String hostname, List<String> tlsAlpnProtocols,
        List<String> tlsEllipticCurves) {
      if (uri == null || urls == null || urls.isEmpty()) {
        throw new IllegalArgumentException("uri == null || urls == null || urls.isEmpty()");
      }
      for (String it : urls) {
        if (it == null) {
          throw new IllegalArgumentException("urls element is null: " + urls);
        }
      }
      if (username == null) {
        throw new IllegalArgumentException("username == null");
      }
      if (password == null) {
        throw new IllegalArgumentException("password == null");
      }
      if (hostname == null) {
        throw new IllegalArgumentException("hostname == null");
      }
      this.uri = uri;
      this.urls = urls;
      this.username = username;
      this.password = password;
      this.tlsCertPolicy = tlsCertPolicy;
      this.hostname = hostname;
      this.tlsAlpnProtocols = tlsAlpnProtocols;
      this.tlsEllipticCurves = tlsEllipticCurves;
    }

    @Override
    public String toString() {
      return urls + " [" + username + ":" + password + "] [" + tlsCertPolicy + "] [" + hostname
          + "] [" + tlsAlpnProtocols + "] [" + tlsEllipticCurves + "]";
    }

    public static Builder builder(String uri) {
      return new Builder(Collections.singletonList(uri));
    }

    public static Builder builder(List<String> urls) {
      return new Builder(urls);
    }

    public static class Builder {
      @Nullable private final List<String> urls;
      private String username = "";
      private String password = "";
      private TlsCertPolicy tlsCertPolicy = TlsCertPolicy.TLS_CERT_POLICY_SECURE;
      private String hostname = "";
      private List<String> tlsAlpnProtocols;
      private List<String> tlsEllipticCurves;

      private Builder(List<String> urls) {
        if (urls == null || urls.isEmpty()) {
          throw new IllegalArgumentException("urls == null || urls.isEmpty(): " + urls);
        }
        this.urls = urls;
      }

      public Builder setUsername(String username) {
        this.username = username;
        return this;
      }

      public Builder setPassword(String password) {
        this.password = password;
        return this;
      }

      public Builder setTlsCertPolicy(TlsCertPolicy tlsCertPolicy) {
        this.tlsCertPolicy = tlsCertPolicy;
        return this;
      }

      public Builder setHostname(String hostname) {
        this.hostname = hostname;
        return this;
      }

      public Builder setTlsAlpnProtocols(List<String> tlsAlpnProtocols) {
        this.tlsAlpnProtocols = tlsAlpnProtocols;
        return this;
      }

      public Builder setTlsEllipticCurves(List<String> tlsEllipticCurves) {
        this.tlsEllipticCurves = tlsEllipticCurves;
        return this;
      }

      public IceServer createIceServer() {
        return new IceServer(urls.get(0), urls, username, password, tlsCertPolicy, hostname,
            tlsAlpnProtocols, tlsEllipticCurves);
      }
    }

    @Nullable
    @CalledByNative("IceServer")
    List<String> getUrls() {
      return urls;
    }

    @Nullable
    @CalledByNative("IceServer")
    String getUsername() {
      return username;
    }

    @Nullable
    @CalledByNative("IceServer")
    String getPassword() {
      return password;
    }

    @CalledByNative("IceServer")
    TlsCertPolicy getTlsCertPolicy() {
      return tlsCertPolicy;
    }

    @Nullable
    @CalledByNative("IceServer")
    String getHostname() {
      return hostname;
    }

    @CalledByNative("IceServer")
    List<String> getTlsAlpnProtocols() {
      return tlsAlpnProtocols;
    }

    @CalledByNative("IceServer")
    List<String> getTlsEllipticCurves() {
      return tlsEllipticCurves;
    }
  }

  /** Java version of PeerConnectionInterface.IceTransportsType */
  public enum IceTransportsType { NONE, RELAY, NOHOST, ALL }

  /** Java version of PeerConnectionInterface.BundlePolicy */
  public enum BundlePolicy { BALANCED, MAXBUNDLE, MAXCOMPAT }

  /** Java version of PeerConnectionInterface.RtcpMuxPolicy */
  public enum RtcpMuxPolicy { NEGOTIATE, REQUIRE }

  /** Java version of PeerConnectionInterface.TcpCandidatePolicy */
  public enum TcpCandidatePolicy { ENABLED, DISABLED }

  /** Java version of PeerConnectionInterface.CandidateNetworkPolicy */
  public enum CandidateNetworkPolicy { ALL, LOW_COST }

  // Keep in sync with webrtc/rtc_base/network_constants.h.
  public enum AdapterType {
    UNKNOWN,
    ETHERNET,
    WIFI,
    CELLULAR,
    VPN,
    LOOPBACK,
  }

  /** Java version of rtc::KeyType */
  public enum KeyType { RSA, ECDSA }

  /** Java version of PeerConnectionInterface.ContinualGatheringPolicy */
  public enum ContinualGatheringPolicy { GATHER_ONCE, GATHER_CONTINUALLY }

  /** Java version of rtc::IntervalRange */
  public static class IntervalRange {
    private final int min;
    private final int max;

    public IntervalRange(int min, int max) {
      this.min = min;
      this.max = max;
    }

    @CalledByNative("IntervalRange")
    public int getMin() {
      return min;
    }

    @CalledByNative("IntervalRange")
    public int getMax() {
      return max;
    }
  }

  /**
   * Java version of webrtc::SdpSemantics.
   *
   * Configure the SDP semantics used by this PeerConnection. Note that the
   * WebRTC 1.0 specification requires UNIFIED_PLAN semantics. The
   * RtpTransceiver API is only available with UNIFIED_PLAN semantics.
   *
   * <p>PLAN_B will cause PeerConnection to create offers and answers with at
   * most one audio and one video m= section with multiple RtpSenders and
   * RtpReceivers specified as multiple a=ssrc lines within the section. This
   * will also cause PeerConnection to ignore all but the first m= section of
   * the same media type.
   *
   * <p>UNIFIED_PLAN will cause PeerConnection to create offers and answers with
   * multiple m= sections where each m= section maps to one RtpSender and one
   * RtpReceiver (an RtpTransceiver), either both audio or both video. This
   * will also cause PeerConnection to ignore all but the first a=ssrc lines
   * that form a Plan B stream.
   *
   * <p>For users who wish to send multiple audio/video streams and need to stay
   * interoperable with legacy WebRTC implementations, specify PLAN_B.
   *
   * <p>For users who wish to send multiple audio/video streams and/or wish to
   * use the new RtpTransceiver API, specify UNIFIED_PLAN.
   */
  public enum SdpSemantics { PLAN_B, UNIFIED_PLAN }

  /** Java version of PeerConnectionInterface.RTCConfiguration */
  // TODO(qingsi): Resolve the naming inconsistency of fields with/without units.
  public static class RTCConfiguration {
    public IceTransportsType iceTransportsType;
    public List<IceServer> iceServers;
    public BundlePolicy bundlePolicy;
    public RtcpMuxPolicy rtcpMuxPolicy;
    public TcpCandidatePolicy tcpCandidatePolicy;
    public CandidateNetworkPolicy candidateNetworkPolicy;
    public int audioJitterBufferMaxPackets;
    public boolean audioJitterBufferFastAccelerate;
    public int iceConnectionReceivingTimeout;
    public int iceBackupCandidatePairPingInterval;
    public KeyType keyType;
    public ContinualGatheringPolicy continualGatheringPolicy;
    public int iceCandidatePoolSize;
    public boolean pruneTurnPorts;
    public boolean presumeWritableWhenFullyRelayed;
    // The following fields define intervals in milliseconds at which ICE
    // connectivity checks are sent.
    //
    // We consider ICE is "strongly connected" for an agent when there is at
    // least one candidate pair that currently succeeds in connectivity check
    // from its direction i.e. sending a ping and receives a ping response, AND
    // all candidate pairs have sent a minimum number of pings for connectivity
    // (this number is implementation-specific). Otherwise, ICE is considered in
    // "weak connectivity".
    //
    // Note that the above notion of strong and weak connectivity is not defined
    // in RFC 5245, and they apply to our current ICE implementation only.
    //
    // 1) iceCheckIntervalStrongConnectivityMs defines the interval applied to
    // ALL candidate pairs when ICE is strongly connected,
    // 2) iceCheckIntervalWeakConnectivityMs defines the counterpart for ALL
    // pairs when ICE is weakly connected, and
    // 3) iceCheckMinInterval defines the minimal interval (equivalently the
    // maximum rate) that overrides the above two intervals when either of them
    // is less.
    @Nullable public Integer iceCheckIntervalStrongConnectivityMs;
    @Nullable public Integer iceCheckIntervalWeakConnectivityMs;
    @Nullable public Integer iceCheckMinInterval;
    // The time period in milliseconds for which a candidate pair must wait for response to
    // connectivitiy checks before it becomes unwritable.
    @Nullable public Integer iceUnwritableTimeMs;
    // The minimum number of connectivity checks that a candidate pair must sent without receiving
    // response before it becomes unwritable.
    @Nullable public Integer iceUnwritableMinChecks;
    // The interval in milliseconds at which STUN candidates will resend STUN binding requests
    // to keep NAT bindings open.
    // The default value in the implementation is used if this field is null.
    @Nullable public Integer stunCandidateKeepaliveIntervalMs;
    public boolean disableIPv6OnWifi;
    // By default, PeerConnection will use a limited number of IPv6 network
    // interfaces, in order to avoid too many ICE candidate pairs being created
    // and delaying ICE completion.
    //
    // Can be set to Integer.MAX_VALUE to effectively disable the limit.
    public int maxIPv6Networks;
    @Nullable public IntervalRange iceRegatherIntervalRange;

    // These values will be overridden by MediaStream constraints if deprecated constraints-based
    // create peerconnection interface is used.
    public boolean disableIpv6;
    public boolean enableDscp;
    public boolean enableCpuOveruseDetection;
    public boolean enableRtpDataChannel;
    public boolean suspendBelowMinBitrate;
    @Nullable public Integer screencastMinBitrate;
    @Nullable public Boolean combinedAudioVideoBwe;
    @Nullable public Boolean enableDtlsSrtp;
    // Use "Unknown" to represent no preference of adapter types, not the
    // preference of adapters of unknown types.
    public AdapterType networkPreference;
    public SdpSemantics sdpSemantics;

    // This is an optional wrapper for the C++ webrtc::TurnCustomizer.
    @Nullable public TurnCustomizer turnCustomizer;

    // TODO(deadbeef): Instead of duplicating the defaults here, we should do
    // something to pick up the defaults from C++. The Objective-C equivalent
    // of RTCConfiguration does that.
    public RTCConfiguration(List<IceServer> iceServers) {
      iceTransportsType = IceTransportsType.ALL;
      bundlePolicy = BundlePolicy.BALANCED;
      rtcpMuxPolicy = RtcpMuxPolicy.REQUIRE;
      tcpCandidatePolicy = TcpCandidatePolicy.ENABLED;
      candidateNetworkPolicy = CandidateNetworkPolicy.ALL;
      this.iceServers = iceServers;
      audioJitterBufferMaxPackets = 50;
      audioJitterBufferFastAccelerate = false;
      iceConnectionReceivingTimeout = -1;
      iceBackupCandidatePairPingInterval = -1;
      keyType = KeyType.ECDSA;
      continualGatheringPolicy = ContinualGatheringPolicy.GATHER_ONCE;
      iceCandidatePoolSize = 0;
      pruneTurnPorts = false;
      presumeWritableWhenFullyRelayed = false;
      iceCheckIntervalStrongConnectivityMs = null;
      iceCheckIntervalWeakConnectivityMs = null;
      iceCheckMinInterval = null;
      iceUnwritableTimeMs = null;
      iceUnwritableMinChecks = null;
      stunCandidateKeepaliveIntervalMs = null;
      disableIPv6OnWifi = false;
      maxIPv6Networks = 5;
      iceRegatherIntervalRange = null;
      disableIpv6 = false;
      enableDscp = false;
      enableCpuOveruseDetection = true;
      enableRtpDataChannel = false;
      suspendBelowMinBitrate = false;
      screencastMinBitrate = null;
      combinedAudioVideoBwe = null;
      enableDtlsSrtp = null;
      networkPreference = AdapterType.UNKNOWN;
      sdpSemantics = SdpSemantics.PLAN_B;
    }

    @CalledByNative("RTCConfiguration")
    IceTransportsType getIceTransportsType() {
      return iceTransportsType;
    }

    @CalledByNative("RTCConfiguration")
    List<IceServer> getIceServers() {
      return iceServers;
    }

    @CalledByNative("RTCConfiguration")
    BundlePolicy getBundlePolicy() {
      return bundlePolicy;
    }

    @CalledByNative("RTCConfiguration")
    RtcpMuxPolicy getRtcpMuxPolicy() {
      return rtcpMuxPolicy;
    }

    @CalledByNative("RTCConfiguration")
    TcpCandidatePolicy getTcpCandidatePolicy() {
      return tcpCandidatePolicy;
    }

    @CalledByNative("RTCConfiguration")
    CandidateNetworkPolicy getCandidateNetworkPolicy() {
      return candidateNetworkPolicy;
    }

    @CalledByNative("RTCConfiguration")
    int getAudioJitterBufferMaxPackets() {
      return audioJitterBufferMaxPackets;
    }

    @CalledByNative("RTCConfiguration")
    boolean getAudioJitterBufferFastAccelerate() {
      return audioJitterBufferFastAccelerate;
    }

    @CalledByNative("RTCConfiguration")
    int getIceConnectionReceivingTimeout() {
      return iceConnectionReceivingTimeout;
    }

    @CalledByNative("RTCConfiguration")
    int getIceBackupCandidatePairPingInterval() {
      return iceBackupCandidatePairPingInterval;
    }

    @CalledByNative("RTCConfiguration")
    KeyType getKeyType() {
      return keyType;
    }

    @CalledByNative("RTCConfiguration")
    ContinualGatheringPolicy getContinualGatheringPolicy() {
      return continualGatheringPolicy;
    }

    @CalledByNative("RTCConfiguration")
    int getIceCandidatePoolSize() {
      return iceCandidatePoolSize;
    }

    @CalledByNative("RTCConfiguration")
    boolean getPruneTurnPorts() {
      return pruneTurnPorts;
    }

    @CalledByNative("RTCConfiguration")
    boolean getPresumeWritableWhenFullyRelayed() {
      return presumeWritableWhenFullyRelayed;
    }

    @Nullable
    @CalledByNative("RTCConfiguration")
    Integer getIceCheckIntervalStrongConnectivity() {
      return iceCheckIntervalStrongConnectivityMs;
    }

    @Nullable
    @CalledByNative("RTCConfiguration")
    Integer getIceCheckIntervalWeakConnectivity() {
      return iceCheckIntervalWeakConnectivityMs;
    }

    @Nullable
    @CalledByNative("RTCConfiguration")
    Integer getIceCheckMinInterval() {
      return iceCheckMinInterval;
    }

    @Nullable
    @CalledByNative("RTCConfiguration")
    Integer getIceUnwritableTimeout() {
      return iceUnwritableTimeMs;
    }

    @Nullable
    @CalledByNative("RTCConfiguration")
    Integer getIceUnwritableMinChecks() {
      return iceUnwritableMinChecks;
    }

    @Nullable
    @CalledByNative("RTCConfiguration")
    Integer getStunCandidateKeepaliveInterval() {
      return stunCandidateKeepaliveIntervalMs;
    }

    @CalledByNative("RTCConfiguration")
    boolean getDisableIPv6OnWifi() {
      return disableIPv6OnWifi;
    }

    @CalledByNative("RTCConfiguration")
    int getMaxIPv6Networks() {
      return maxIPv6Networks;
    }

    @Nullable
    @CalledByNative("RTCConfiguration")
    IntervalRange getIceRegatherIntervalRange() {
      return iceRegatherIntervalRange;
    }

    @Nullable
    @CalledByNative("RTCConfiguration")
    TurnCustomizer getTurnCustomizer() {
      return turnCustomizer;
    }

    @CalledByNative("RTCConfiguration")
    boolean getDisableIpv6() {
      return disableIpv6;
    }

    @CalledByNative("RTCConfiguration")
    boolean getEnableDscp() {
      return enableDscp;
    }

    @CalledByNative("RTCConfiguration")
    boolean getEnableCpuOveruseDetection() {
      return enableCpuOveruseDetection;
    }

    @CalledByNative("RTCConfiguration")
    boolean getEnableRtpDataChannel() {
      return enableRtpDataChannel;
    }

    @CalledByNative("RTCConfiguration")
    boolean getSuspendBelowMinBitrate() {
      return suspendBelowMinBitrate;
    }

    @Nullable
    @CalledByNative("RTCConfiguration")
    Integer getScreencastMinBitrate() {
      return screencastMinBitrate;
    }

    @Nullable
    @CalledByNative("RTCConfiguration")
    Boolean getCombinedAudioVideoBwe() {
      return combinedAudioVideoBwe;
    }

    @Nullable
    @CalledByNative("RTCConfiguration")
    Boolean getEnableDtlsSrtp() {
      return enableDtlsSrtp;
    }

    @CalledByNative("RTCConfiguration")
    AdapterType getNetworkPreference() {
      return networkPreference;
    }

    @CalledByNative("RTCConfiguration")
    SdpSemantics getSdpSemantics() {
      return sdpSemantics;
    }
  };

  private final List<MediaStream> localStreams = new ArrayList<>();
  private final long nativePeerConnection;
  private List<RtpSender> senders = new ArrayList<>();
  private List<RtpReceiver> receivers = new ArrayList<>();
  private List<RtpTransceiver> transceivers = new ArrayList<>();

  /**
   * Wraps a PeerConnection created by the factory. Can be used by clients that want to implement
   * their PeerConnection creation in JNI.
   */
  public PeerConnection(NativePeerConnectionFactory factory) {
    this(factory.createNativePeerConnection());
  }

  PeerConnection(long nativePeerConnection) {
    this.nativePeerConnection = nativePeerConnection;
  }

  // JsepInterface.
  public SessionDescription getLocalDescription() {
    return nativeGetLocalDescription();
  }

  public SessionDescription getRemoteDescription() {
    return nativeGetRemoteDescription();
  }

  public DataChannel createDataChannel(String label, DataChannel.Init init) {
    return nativeCreateDataChannel(label, init);
  }

  public void createOffer(SdpObserver observer, MediaConstraints constraints) {
    nativeCreateOffer(observer, constraints);
  }

  public void createAnswer(SdpObserver observer, MediaConstraints constraints) {
    nativeCreateAnswer(observer, constraints);
  }

  public void setLocalDescription(SdpObserver observer, SessionDescription sdp) {
    nativeSetLocalDescription(observer, sdp);
  }

  public void setRemoteDescription(SdpObserver observer, SessionDescription sdp) {
    nativeSetRemoteDescription(observer, sdp);
  }

  /**
   * Enables/disables playout of received audio streams. Enabled by default.
   *
   * Note that even if playout is enabled, streams will only be played out if
   * the appropriate SDP is also applied. The main purpose of this API is to
   * be able to control the exact time when audio playout starts.
   */
  public void setAudioPlayout(boolean playout) {
    nativeSetAudioPlayout(playout);
  }

  /**
   * Enables/disables recording of transmitted audio streams. Enabled by default.
   *
   * Note that even if recording is enabled, streams will only be recorded if
   * the appropriate SDP is also applied. The main purpose of this API is to
   * be able to control the exact time when audio recording starts.
   */
  public void setAudioRecording(boolean recording) {
    nativeSetAudioRecording(recording);
  }

  public boolean setConfiguration(RTCConfiguration config) {
    return nativeSetConfiguration(config);
  }

  public boolean addIceCandidate(IceCandidate candidate) {
    return nativeAddIceCandidate(candidate.sdpMid, candidate.sdpMLineIndex, candidate.sdp);
  }

  public boolean removeIceCandidates(final IceCandidate[] candidates) {
    return nativeRemoveIceCandidates(candidates);
  }

  /**
   * Adds a new MediaStream to be sent on this peer connection.
   * Note: This method is not supported with SdpSemantics.UNIFIED_PLAN. Please
   * use addTrack instead.
   */
  public boolean addStream(MediaStream stream) {
    boolean ret = nativeAddLocalStream(stream.nativeStream);
    if (!ret) {
      return false;
    }
    localStreams.add(stream);
    return true;
  }

  /**
   * Removes the given media stream from this peer connection.
   * This method is not supported with SdpSemantics.UNIFIED_PLAN. Please use
   * removeTrack instead.
   */
  public void removeStream(MediaStream stream) {
    nativeRemoveLocalStream(stream.nativeStream);
    localStreams.remove(stream);
  }

  /**
   * Creates an RtpSender without a track.
   *
   * <p>This method allows an application to cause the PeerConnection to negotiate
   * sending/receiving a specific media type, but without having a track to
   * send yet.
   *
   * <p>When the application does want to begin sending a track, it can call
   * RtpSender.setTrack, which doesn't require any additional SDP negotiation.
   *
   * <p>Example use:
   * <pre>
   * {@code
   * audioSender = pc.createSender("audio", "stream1");
   * videoSender = pc.createSender("video", "stream1");
   * // Do normal SDP offer/answer, which will kick off ICE/DTLS and negotiate
   * // media parameters....
   * // Later, when the endpoint is ready to actually begin sending:
   * audioSender.setTrack(audioTrack, false);
   * videoSender.setTrack(videoTrack, false);
   * }
   * </pre>
   * <p>Note: This corresponds most closely to "addTransceiver" in the official
   * WebRTC API, in that it creates a sender without a track. It was
   * implemented before addTransceiver because it provides useful
   * functionality, and properly implementing transceivers would have required
   * a great deal more work.
   *
   * <p>Note: This is only available with SdpSemantics.PLAN_B specified. Please use
   * addTransceiver instead.
   *
   * @param kind      Corresponds to MediaStreamTrack kinds (must be "audio" or
   *                  "video").
   * @param stream_id The ID of the MediaStream that this sender's track will
   *                  be associated with when SDP is applied to the remote
   *                  PeerConnection. If createSender is used to create an
   *                  audio and video sender that should be synchronized, they
   *                  should use the same stream ID.
   * @return          A new RtpSender object if successful, or null otherwise.
   */
  public RtpSender createSender(String kind, String stream_id) {
    RtpSender newSender = nativeCreateSender(kind, stream_id);
    if (newSender != null) {
      senders.add(newSender);
    }
    return newSender;
  }

  /**
   * Gets all RtpSenders associated with this peer connection.
   * Note that calling getSenders will dispose of the senders previously
   * returned.
   */
  public List<RtpSender> getSenders() {
    for (RtpSender sender : senders) {
      sender.dispose();
    }
    senders = nativeGetSenders();
    return Collections.unmodifiableList(senders);
  }

  /**
   * Gets all RtpReceivers associated with this peer connection.
   * Note that calling getReceivers will dispose of the receivers previously
   * returned.
   */
  public List<RtpReceiver> getReceivers() {
    for (RtpReceiver receiver : receivers) {
      receiver.dispose();
    }
    receivers = nativeGetReceivers();
    return Collections.unmodifiableList(receivers);
  }

  /**
   * Gets all RtpTransceivers associated with this peer connection.
   * Note that calling getTransceivers will dispose of the transceivers previously
   * returned.
   * Note: This is only available with SdpSemantics.UNIFIED_PLAN specified.
   */
  public List<RtpTransceiver> getTransceivers() {
    for (RtpTransceiver transceiver : transceivers) {
      transceiver.dispose();
    }
    transceivers = nativeGetTransceivers();
    return Collections.unmodifiableList(transceivers);
  }

  /**
   * Adds a new media stream track to be sent on this peer connection, and returns
   * the newly created RtpSender. If streamIds are specified, the RtpSender will
   * be associated with the streams specified in the streamIds list.
   *
   * @throws IllegalStateException if an error accors in C++ addTrack.
   *         An error can occur if:
   *           - A sender already exists for the track.
   *           - The peer connection is closed.
   */
  public RtpSender addTrack(MediaStreamTrack track) {
    return addTrack(track, Collections.emptyList());
  }

  public RtpSender addTrack(MediaStreamTrack track, List<String> streamIds) {
    if (track == null || streamIds == null) {
      throw new NullPointerException("No MediaStreamTrack specified in addTrack.");
    }
    RtpSender newSender = nativeAddTrack(track.nativeTrack, streamIds);
    if (newSender == null) {
      throw new IllegalStateException("C++ addTrack failed.");
    }
    senders.add(newSender);
    return newSender;
  }

  /**
   * Stops sending media from sender. The sender will still appear in getSenders. Future
   * calls to createOffer will mark the m section for the corresponding transceiver as
   * receive only or inactive, as defined in JSEP. Returns true on success.
   */
  public boolean removeTrack(RtpSender sender) {
    if (sender == null) {
      throw new NullPointerException("No RtpSender specified for removeTrack.");
    }
    return nativeRemoveTrack(sender.nativeRtpSender);
  }

  /**
   * Creates a new RtpTransceiver and adds it to the set of transceivers. Adding a
   * transceiver will cause future calls to CreateOffer to add a media description
   * for the corresponding transceiver.
   *
   * <p>The initial value of |mid| in the returned transceiver is null. Setting a
   * new session description may change it to a non-null value.
   *
   * <p>https://w3c.github.io/webrtc-pc/#dom-rtcpeerconnection-addtransceiver
   *
   * <p>If a MediaStreamTrack is specified then a transceiver will be added with a
   * sender set to transmit the given track. The kind
   * of the transceiver (and sender/receiver) will be derived from the kind of
   * the track.
   *
   * <p>If MediaType is specified then a transceiver will be added based upon that type.
   * This can be either MEDIA_TYPE_AUDIO or MEDIA_TYPE_VIDEO.
   *
   * <p>Optionally, an RtpTransceiverInit structure can be specified to configure
   * the transceiver from construction. If not specified, the transceiver will
   * default to having a direction of kSendRecv and not be part of any streams.
   *
   * <p>Note: These methods are only available with SdpSemantics.UNIFIED_PLAN specified.
   * @throws IllegalStateException if an error accors in C++ addTransceiver
   */
  public RtpTransceiver addTransceiver(MediaStreamTrack track) {
    return addTransceiver(track, new RtpTransceiver.RtpTransceiverInit());
  }

  public RtpTransceiver addTransceiver(
      MediaStreamTrack track, @Nullable RtpTransceiver.RtpTransceiverInit init) {
    if (track == null) {
      throw new NullPointerException("No MediaStreamTrack specified for addTransceiver.");
    }
    if (init == null) {
      init = new RtpTransceiver.RtpTransceiverInit();
    }
    RtpTransceiver newTransceiver = nativeAddTransceiverWithTrack(track.nativeTrack, init);
    if (newTransceiver == null) {
      throw new IllegalStateException("C++ addTransceiver failed.");
    }
    transceivers.add(newTransceiver);
    return newTransceiver;
  }

  public RtpTransceiver addTransceiver(MediaStreamTrack.MediaType mediaType) {
    return addTransceiver(mediaType, new RtpTransceiver.RtpTransceiverInit());
  }

  public RtpTransceiver addTransceiver(
      MediaStreamTrack.MediaType mediaType, @Nullable RtpTransceiver.RtpTransceiverInit init) {
    if (mediaType == null) {
      throw new NullPointerException("No MediaType specified for addTransceiver.");
    }
    if (init == null) {
      init = new RtpTransceiver.RtpTransceiverInit();
    }
    RtpTransceiver newTransceiver = nativeAddTransceiverOfType(mediaType, init);
    if (newTransceiver == null) {
      throw new IllegalStateException("C++ addTransceiver failed.");
    }
    transceivers.add(newTransceiver);
    return newTransceiver;
  }

  // Older, non-standard implementation of getStats.
  @Deprecated
  public boolean getStats(StatsObserver observer, @Nullable MediaStreamTrack track) {
    return nativeOldGetStats(observer, (track == null) ? 0 : track.nativeTrack);
  }

  /**
   * Gets stats using the new stats collection API, see webrtc/api/stats/. These
   * will replace old stats collection API when the new API has matured enough.
   */
  public void getStats(RTCStatsCollectorCallback callback) {
    nativeNewGetStats(callback);
  }

  /**
   * Limits the bandwidth allocated for all RTP streams sent by this
   * PeerConnection. Pass null to leave a value unchanged.
   */
  public boolean setBitrate(Integer min, Integer current, Integer max) {
    return nativeSetBitrate(min, current, max);
  }

  /**
   * Starts recording an RTC event log.
   *
   * Ownership of the file is transfered to the native code. If an RTC event
   * log is already being recorded, it will be stopped and a new one will start
   * using the provided file. Logging will continue until the stopRtcEventLog
   * function is called. The max_size_bytes argument is ignored, it is added
   * for future use.
   */
  public boolean startRtcEventLog(int file_descriptor, int max_size_bytes) {
    return nativeStartRtcEventLog(file_descriptor, max_size_bytes);
  }

  /**
   * Stops recording an RTC event log. If no RTC event log is currently being
   * recorded, this call will have no effect.
   */
  public void stopRtcEventLog() {
    nativeStopRtcEventLog();
  }

  // TODO(fischman): add support for DTMF-related methods once that API
  // stabilizes.
  public SignalingState signalingState() {
    return nativeSignalingState();
  }

  public IceConnectionState iceConnectionState() {
    return nativeIceConnectionState();
  }

  public IceGatheringState iceGatheringState() {
    return nativeIceGatheringState();
  }

  public void close() {
    nativeClose();
  }

  /**
   * Free native resources associated with this PeerConnection instance.
   *
   * This method removes a reference count from the C++ PeerConnection object,
   * which should result in it being destroyed. It also calls equivalent
   * "dispose" methods on the Java objects attached to this PeerConnection
   * (streams, senders, receivers), such that their associated C++ objects
   * will also be destroyed.
   *
   * <p>Note that this method cannot be safely called from an observer callback
   * (PeerConnection.Observer, DataChannel.Observer, etc.). If you want to, for
   * example, destroy the PeerConnection after an "ICE failed" callback, you
   * must do this asynchronously (in other words, unwind the stack first). See
   * <a href="https://bugs.chromium.org/p/webrtc/issues/detail?id=3721">bug
   * 3721</a> for more details.
   */
  public void dispose() {
    close();
    for (MediaStream stream : localStreams) {
      nativeRemoveLocalStream(stream.nativeStream);
      stream.dispose();
    }
    localStreams.clear();
    for (RtpSender sender : senders) {
      sender.dispose();
    }
    senders.clear();
    for (RtpReceiver receiver : receivers) {
      receiver.dispose();
    }
    for (RtpTransceiver transceiver : transceivers) {
      transceiver.dispose();
    }
    transceivers.clear();
    receivers.clear();
    nativeFreeOwnedPeerConnection(nativePeerConnection);
  }

  /** Returns a pointer to the native webrtc::PeerConnectionInterface. */
  public long getNativePeerConnection() {
    return nativeGetNativePeerConnection();
  }

  @CalledByNative
  long getNativeOwnedPeerConnection() {
    return nativePeerConnection;
  }

  public static long createNativePeerConnectionObserver(Observer observer) {
    return nativeCreatePeerConnectionObserver(observer);
  }

  private native long nativeGetNativePeerConnection();
  private native SessionDescription nativeGetLocalDescription();
  private native SessionDescription nativeGetRemoteDescription();
  private native DataChannel nativeCreateDataChannel(String label, DataChannel.Init init);
  private native void nativeCreateOffer(SdpObserver observer, MediaConstraints constraints);
  private native void nativeCreateAnswer(SdpObserver observer, MediaConstraints constraints);
  private native void nativeSetLocalDescription(SdpObserver observer, SessionDescription sdp);
  private native void nativeSetRemoteDescription(SdpObserver observer, SessionDescription sdp);
  private native void nativeSetAudioPlayout(boolean playout);
  private native void nativeSetAudioRecording(boolean recording);
  private native boolean nativeSetBitrate(Integer min, Integer current, Integer max);
  private native SignalingState nativeSignalingState();
  private native IceConnectionState nativeIceConnectionState();
  private native IceGatheringState nativeIceGatheringState();
  private native void nativeClose();
  private static native long nativeCreatePeerConnectionObserver(Observer observer);
  private static native void nativeFreeOwnedPeerConnection(long ownedPeerConnection);
  private native boolean nativeSetConfiguration(RTCConfiguration config);
  private native boolean nativeAddIceCandidate(
      String sdpMid, int sdpMLineIndex, String iceCandidateSdp);
  private native boolean nativeRemoveIceCandidates(final IceCandidate[] candidates);
  private native boolean nativeAddLocalStream(long stream);
  private native void nativeRemoveLocalStream(long stream);
  private native boolean nativeOldGetStats(StatsObserver observer, long nativeTrack);
  private native void nativeNewGetStats(RTCStatsCollectorCallback callback);
  private native RtpSender nativeCreateSender(String kind, String stream_id);
  private native List<RtpSender> nativeGetSenders();
  private native List<RtpReceiver> nativeGetReceivers();
  private native List<RtpTransceiver> nativeGetTransceivers();
  private native RtpSender nativeAddTrack(long track, List<String> streamIds);
  private native boolean nativeRemoveTrack(long sender);
  private native RtpTransceiver nativeAddTransceiverWithTrack(
      long track, RtpTransceiver.RtpTransceiverInit init);
  private native RtpTransceiver nativeAddTransceiverOfType(
      MediaStreamTrack.MediaType mediaType, RtpTransceiver.RtpTransceiverInit init);
  private native boolean nativeStartRtcEventLog(int file_descriptor, int max_size_bytes);
  private native void nativeStopRtcEventLog();
}
