/*
 * Copyright (C) 2012 Google Inc. All rights reserved.
 * Copyright (C) 2013 Nokia Corporation and/or its subsidiary(-ies).
 * Copyright (C) 2015, 2016 Ericsson AB. All rights reserved.
 * Copyright (C) 2017 Apple Inc. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer
 *    in the documentation and/or other materials provided with the
 *    distribution.
 * 3. Neither the name of Google Inc. nor the names of its contributors
 *    may be used to endorse or promote products derived from this
 *    software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

typedef RTCRtpTransceiverDirection RtpTransceiverDirection;

[
    Conditional=WEB_RTC,
    EnabledAtRuntime=PeerConnection
] dictionary RTCDataChannelInit {
    boolean ordered = true;
    unsigned short maxPacketLifeTime;
    unsigned short maxRetransmits;
    USVString protocol = "";
    boolean negotiated = false;
    [EnforceRange] unsigned short id;
    // FIXME 169644: missing priority
};

[
    Conditional=WEB_RTC,
    EnabledAtRuntime=PeerConnection,
    ImplementedAs=RTCRtpTransceiverInit
] dictionary RTCRtpTransceiverInit {
    RtpTransceiverDirection direction = "sendrecv";
    // FIXME 169662: missing streams
    // FIXME 169662: missing sendEncodings
};

[
    ActiveDOMObject,
    Conditional=WEB_RTC,
    ConstructorCallWith=ScriptExecutionContext,
    EnabledAtRuntime=PeerConnection,
    ExportMacro=WEBCORE_EXPORT,
    JSBuiltinConstructor
] interface RTCPeerConnection : EventTarget {
    // JS built-in constructor handles the optional RTCConfiguration
    [PrivateIdentifier, CallWith=Document, MayThrowException] void initializeWith(RTCConfiguration configuration);


    // 4.3.2 Interface Definition
    // JSBuiltins provide support for legacy signatures
    [JSBuiltin] Promise<RTCSessionDescriptionInit> createOffer(optional RTCOfferOptions offerOptions);
    [JSBuiltin] Promise<RTCSessionDescriptionInit> createAnswer(optional RTCAnswerOptions answerOptions);

    [JSBuiltin] Promise<void> setLocalDescription(RTCSessionDescriptionInit description);
    readonly attribute RTCSessionDescription? localDescription;
    readonly attribute RTCSessionDescription? currentLocalDescription;
    readonly attribute RTCSessionDescription? pendingLocalDescription;

    [JSBuiltin] Promise<void> setRemoteDescription(RTCSessionDescriptionInit description);
    readonly attribute RTCSessionDescription? remoteDescription;
    readonly attribute RTCSessionDescription? currentRemoteDescription;
    readonly attribute RTCSessionDescription? pendingRemoteDescription;

    [JSBuiltin] Promise<void> addIceCandidate((RTCIceCandidateInit or RTCIceCandidate) candidate);

    readonly attribute RTCSignalingState signalingState;
    readonly attribute RTCIceGatheringState iceGatheringState;
    readonly attribute RTCIceConnectionState iceConnectionState;
    readonly attribute RTCPeerConnectionState connectionState;
    // FIXME 169644: missing canTrickleIceCandidates
    // FIXME 169644: missing defaultIceServers

    RTCConfiguration getConfiguration();
    [MayThrowException] void setConfiguration(RTCConfiguration configuration);
    void close();

    attribute EventHandler onnegotiationneeded;
    attribute EventHandler onicecandidate;
    attribute EventHandler onsignalingstatechange;
    attribute EventHandler oniceconnectionstatechange;
    attribute EventHandler onicegatheringstatechange;
    attribute EventHandler onconnectionstatechange;
    // FIXME 169644: missing onfingerprintfailure and onicecandidateerror

    // Private API used to implement the overloaded operations above. Queued functions are called by runQueuedOperation().
    // See RTCPeerConnectionInternals.js.
    [PrivateIdentifier] Promise<RTCSessionDescriptionInit> queuedCreateOffer(optional RTCOfferOptions offerOptions);
    [PrivateIdentifier] Promise<RTCSessionDescriptionInit> queuedCreateAnswer(optional RTCAnswerOptions answerOptions);
    [PrivateIdentifier] Promise<void> queuedSetLocalDescription(RTCSessionDescription description);
    [PrivateIdentifier] Promise<void> queuedSetRemoteDescription(RTCSessionDescription description);
    [PrivateIdentifier] Promise<void> queuedAddIceCandidate(RTCIceCandidate? candidate);


    // 4.11 Certificate management
    // FIXME 169644: missing generateCertificate


    // 5.1 RTCPeerConnection extensions
    // RTP Media API extensions
    [PrivateIdentifier, PublicIdentifier] sequence<RTCRtpSender> getSenders();
    sequence<RTCRtpReceiver> getReceivers();
    sequence<RTCRtpTransceiver> getTransceivers();

    [PrivateIdentifier, PublicIdentifier, MayThrowException] RTCRtpSender addTrack(MediaStreamTrack track, MediaStream... streams);
    [PrivateIdentifier, PublicIdentifier, MayThrowException] void removeTrack(RTCRtpSender sender);

    [MayThrowException] RTCRtpTransceiver addTransceiver((MediaStreamTrack or DOMString) track, optional RTCRtpTransceiverInit init);

    attribute EventHandler ontrack;


    // 6.1 Peer-to-peer data API
    // FIXME 169644: missing sctp

    [CallWith=ScriptExecutionContext, MayThrowException] RTCDataChannel createDataChannel([TreatNullAs=EmptyString] USVString label, optional RTCDataChannelInit options);
    attribute EventHandler ondatachannel;


    // 8.2 Statistics API
    // FIXME 169644: |selector| may go away in a future version of the spec
    Promise<RTCStatsReport> getStats(optional MediaStreamTrack? selector = null);


    // 9.6 Identity Provider API
    // FIXME 169644: missing IdP

    // Legacy MediaStream API
    [JSBuiltin, EnabledAtRuntime=WebRTCLegacyAPI] sequence<MediaStream> getLocalStreams();
    [PrivateIdentifier, PublicIdentifier, EnabledAtRuntime=WebRTCLegacyAPI] sequence<MediaStream> getRemoteStreams();
    [JSBuiltin, EnabledAtRuntime=WebRTCLegacyAPI] MediaStream getStreamById(DOMString streamId);

    [JSBuiltin, EnabledAtRuntime=WebRTCLegacyAPI] void addStream(MediaStream stream);
    [JSBuiltin, EnabledAtRuntime=WebRTCLegacyAPI] void removeStream(MediaStream stream);

    // Legacy event handler (MediaStream-based API)
    [EnabledAtRuntime=WebRTCLegacyAPI] attribute EventHandler onaddstream;
};
