/*
 * 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,
    EnabledBySetting=PeerConnectionEnabled
] 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,
    EnabledBySetting=PeerConnectionEnabled
] dictionary RTCCertificateParameters {
    DOMString name;
    DOMString hash;
    DOMString namedCurve;
    unsigned long modulusLength;
    Uint8Array publicExponent;
    double expires;
};

typedef (object or DOMString) AlgorithmIdentifier;

[
    Conditional=WEB_RTC,
    EnabledBySetting=PeerConnectionEnabled,
    ImplementedAs=RTCRtpTransceiverInit
] dictionary RTCRtpTransceiverInit {
    RtpTransceiverDirection direction = "sendrecv";
    sequence<MediaStream> streams = [];
    sequence<RTCRtpEncodingParameters> sendEncodings = [];
};

[
    ActiveDOMObject,
    Conditional=WEB_RTC,
    EnabledBySetting=PeerConnectionEnabled,
    ExportMacro=WEBCORE_EXPORT,
    Exposed=Window
] interface RTCPeerConnection : EventTarget {
    [CallWith=Document] constructor(optional RTCConfiguration configuration);

    // 4.3.2 Interface Definition
    Promise<RTCSessionDescriptionInit> createOffer(optional RTCOfferOptions offerOptions);
    Promise<RTCSessionDescriptionInit> createAnswer(optional RTCAnswerOptions answerOptions);

    Promise<undefined> setLocalDescription(optional RTCLocalSessionDescriptionInit description);
    readonly attribute RTCSessionDescription? localDescription;
    readonly attribute RTCSessionDescription? currentLocalDescription;
    readonly attribute RTCSessionDescription? pendingLocalDescription;

    Promise<undefined> setRemoteDescription(RTCSessionDescriptionInit description);
    readonly attribute RTCSessionDescription? remoteDescription;
    readonly attribute RTCSessionDescription? currentRemoteDescription;
    readonly attribute RTCSessionDescription? pendingRemoteDescription;

    Promise<undefined> addIceCandidate(optional (RTCIceCandidateInit or RTCIceCandidate) candidate);

    readonly attribute RTCSignalingState signalingState;
    readonly attribute RTCIceGatheringState iceGatheringState;
    readonly attribute RTCIceConnectionState iceConnectionState;
    readonly attribute RTCPeerConnectionState connectionState;
    readonly attribute boolean? canTrickleIceCandidates;

    undefined restartIce();
    RTCConfiguration getConfiguration();
    undefined setConfiguration(RTCConfiguration configuration);
    undefined close();

    attribute EventHandler onnegotiationneeded;
    attribute EventHandler onicecandidate;
    attribute EventHandler onsignalingstatechange;
    attribute EventHandler oniceconnectionstatechange;
    attribute EventHandler onicegatheringstatechange;
    attribute EventHandler onconnectionstatechange;
    attribute EventHandler onicecandidateerror;

    // 4.11 Certificate management
    [CallWith=GlobalObject] static Promise<RTCCertificate> generateCertificate(AlgorithmIdentifier keygenAlgorithm);

    // 5.1 RTCPeerConnection extensions
    // RTP Media API extensions
    sequence<RTCRtpSender> getSenders();
    sequence<RTCRtpReceiver> getReceivers();
    sequence<RTCRtpTransceiver> getTransceivers();

    RTCRtpSender addTrack(MediaStreamTrack track, MediaStream... streams);
    undefined removeTrack(RTCRtpSender sender);

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

    attribute EventHandler ontrack;

    // 6.1 Peer-to-peer data API
    readonly attribute RTCSctpTransport? sctp;

    RTCDataChannel createDataChannel([LegacyNullToEmptyString] USVString label, optional RTCDataChannelInit options);
    attribute EventHandler ondatachannel;


    // 8.2 Statistics API
    Promise<RTCStatsReport> getStats(optional MediaStreamTrack? selector = null);
};
