/*
 * 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=CurrentDocument] 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=CurrentGlobalObject] 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);
};
