/*
 * Copyright (c) 2015, 2016 Ericsson AB. All rights reserved.
 * Copyright (c) 2016 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.
 * 
 * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS 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 APPLE INC. OR ITS 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.
 * 
 */

// DO NOT EDIT THIS FILE. It is automatically generated from JavaScript files for
// builtins by the script: Source/JavaScriptCore/Scripts/generate-js-builtins.py

#include "config.h"
#include "RTCPeerConnectionBuiltins.h"

#if ENABLE(WEB_RTC)

#include "WebCoreJSClientData.h"
#include <heap/HeapInlines.h>
#include <runtime/Executable.h>
#include <runtime/Intrinsic.h>
#include <runtime/JSCJSValueInlines.h>
#include <runtime/JSCellInlines.h>
#include <runtime/StructureInlines.h>
#include <runtime/VM.h>

namespace WebCore {

const JSC::ConstructAbility s_rtcPeerConnectionInitializeRTCPeerConnectionCodeConstructAbility = JSC::ConstructAbility::CannotConstruct;
const int s_rtcPeerConnectionInitializeRTCPeerConnectionCodeLength = 603;
static const JSC::Intrinsic s_rtcPeerConnectionInitializeRTCPeerConnectionCodeIntrinsic = JSC::NoIntrinsic;
const char* s_rtcPeerConnectionInitializeRTCPeerConnectionCode =
    "(function (configuration)\n" \
    "{\n" \
    "    \"use strict\";\n" \
    "    if (arguments.length < 1)\n" \
    "        throw new @TypeError(\"Not enough arguments\");\n" \
    "    if (!@isObject(configuration))\n" \
    "        throw new @TypeError(\"RTCPeerConnection argument must be a valid Dictionary\");\n" \
    "    try {\n" \
    "        this.@initializeWith(configuration);\n" \
    "    } catch (e) {\n" \
    "        const message = e.name === \"TypeMismatchError\" ? \"Invalid RTCPeerConnection constructor arguments\"\n" \
    "            : \"Error creating RTCPeerConnection\";\n" \
    "        throw new @TypeError(message);\n" \
    "    }\n" \
    "    this.@operations = [];\n" \
    "    this.@localStreams = [];\n" \
    "    return this;\n" \
    "})\n" \
;

const JSC::ConstructAbility s_rtcPeerConnectionGetLocalStreamsCodeConstructAbility = JSC::ConstructAbility::CannotConstruct;
const int s_rtcPeerConnectionGetLocalStreamsCodeLength = 195;
static const JSC::Intrinsic s_rtcPeerConnectionGetLocalStreamsCodeIntrinsic = JSC::NoIntrinsic;
const char* s_rtcPeerConnectionGetLocalStreamsCode =
    "(function ()\n" \
    "{\n" \
    "    \"use strict\";\n" \
    "    if (!@isRTCPeerConnection(this))\n" \
    "        throw new @TypeError(\"Function should be called on an RTCPeerConnection\");\n" \
    "    return this.@localStreams.slice();\n" \
    "})\n" \
;

const JSC::ConstructAbility s_rtcPeerConnectionGetStreamByIdCodeConstructAbility = JSC::ConstructAbility::CannotConstruct;
const int s_rtcPeerConnectionGetStreamByIdCodeLength = 455;
static const JSC::Intrinsic s_rtcPeerConnectionGetStreamByIdCodeIntrinsic = JSC::NoIntrinsic;
const char* s_rtcPeerConnectionGetStreamByIdCode =
    "(function (streamIdArg)\n" \
    "{\n" \
    "    \"use strict\";\n" \
    "    if (!@isRTCPeerConnection(this))\n" \
    "        throw new @TypeError(\"Function should be called on an RTCPeerConnection\");\n" \
    "    if (arguments.length < 1)\n" \
    "        throw new @TypeError(\"Not enough arguments\");\n" \
    "    const streamId = @String(streamIdArg);\n" \
    "    return this.@localStreams.find(stream => stream.id === streamId)\n" \
    "        || this.@getRemoteStreams().find(stream => stream.id === streamId)\n" \
    "        || null;\n" \
    "})\n" \
;

const JSC::ConstructAbility s_rtcPeerConnectionAddStreamCodeConstructAbility = JSC::ConstructAbility::CannotConstruct;
const int s_rtcPeerConnectionAddStreamCodeLength = 615;
static const JSC::Intrinsic s_rtcPeerConnectionAddStreamCodeIntrinsic = JSC::NoIntrinsic;
const char* s_rtcPeerConnectionAddStreamCode =
    "(function (stream)\n" \
    "{\n" \
    "    \"use strict\";\n" \
    "    if (!@isRTCPeerConnection(this))\n" \
    "        throw new @TypeError(\"Function should be called on an RTCPeerConnection\");\n" \
    "    if (arguments.length < 1)\n" \
    "        throw new @TypeError(\"Not enough arguments\");\n" \
    "    if (!(stream instanceof @MediaStream))\n" \
    "        throw new @TypeError(\"Argument 1 ('stream') to RTCPeerConnection.addStream must be an instance of MediaStream\");\n" \
    "    if (this.@localStreams.find(localStream => localStream.id === stream.id))\n" \
    "        return;\n" \
    "    this.@localStreams.@push(stream);\n" \
    "    stream.@getTracks().forEach(track => this.@addTrack(track, stream));\n" \
    "})\n" \
;

const JSC::ConstructAbility s_rtcPeerConnectionRemoveStreamCodeConstructAbility = JSC::ConstructAbility::CannotConstruct;
const int s_rtcPeerConnectionRemoveStreamCodeLength = 935;
static const JSC::Intrinsic s_rtcPeerConnectionRemoveStreamCodeIntrinsic = JSC::NoIntrinsic;
const char* s_rtcPeerConnectionRemoveStreamCode =
    "(function (stream)\n" \
    "{\n" \
    "    \"use strict\";\n" \
    "    if (!@isRTCPeerConnection(this))\n" \
    "        throw new @TypeError(\"Function should be called on an RTCPeerConnection\");\n" \
    "    if (arguments.length < 1)\n" \
    "        throw new @TypeError(\"Not enough arguments\");\n" \
    "    if (!(stream instanceof @MediaStream))\n" \
    "        throw new @TypeError(\"Argument 1 ('stream') to RTCPeerConnection.removeStream must be an instance of MediaStream\");\n" \
    "    const indexOfStreamToRemove = this.@localStreams.findIndex(localStream => localStream.id === stream.id);\n" \
    "    if (indexOfStreamToRemove === -1)\n" \
    "        return;\n" \
    "    const senders = this.@getSenders();\n" \
    "    this.@localStreams[indexOfStreamToRemove].@getTracks().forEach(track => {\n" \
    "        const senderForTrack = senders.find(sender => sender.track && sender.track.id === track.id);\n" \
    "        if (senderForTrack)\n" \
    "            this.@removeTrack(senderForTrack);\n" \
    "    });\n" \
    "    this.@localStreams.splice(indexOfStreamToRemove, 1);\n" \
    "})\n" \
;

const JSC::ConstructAbility s_rtcPeerConnectionCreateOfferCodeConstructAbility = JSC::ConstructAbility::CannotConstruct;
const int s_rtcPeerConnectionCreateOfferCodeLength = 719;
static const JSC::Intrinsic s_rtcPeerConnectionCreateOfferCodeIntrinsic = JSC::NoIntrinsic;
const char* s_rtcPeerConnectionCreateOfferCode =
    "(function ()\n" \
    "{\n" \
    "    \"use strict\";\n" \
    "    if (!@isRTCPeerConnection(this))\n" \
    "        return @Promise.@reject(new @TypeError(\"Function should be called on an RTCPeerConnection\"));\n" \
    "    const peerConnection = this;\n" \
    "    return @callbacksAndDictionaryOverload(arguments, \"createOffer\", function (options) {\n" \
    "        return @enqueueOperation(peerConnection, function () {\n" \
    "            return peerConnection.@queuedCreateOffer(options);\n" \
    "        });\n" \
    "    }, function (successCallback, errorCallback, options) {\n" \
    "        @enqueueOperation(peerConnection, function () {\n" \
    "            return peerConnection.@queuedCreateOffer(options).@then(successCallback, errorCallback);\n" \
    "        });\n" \
    "        return @Promise.@resolve(@undefined);\n" \
    "    });\n" \
    "})\n" \
;

const JSC::ConstructAbility s_rtcPeerConnectionCreateAnswerCodeConstructAbility = JSC::ConstructAbility::CannotConstruct;
const int s_rtcPeerConnectionCreateAnswerCodeLength = 722;
static const JSC::Intrinsic s_rtcPeerConnectionCreateAnswerCodeIntrinsic = JSC::NoIntrinsic;
const char* s_rtcPeerConnectionCreateAnswerCode =
    "(function ()\n" \
    "{\n" \
    "    \"use strict\";\n" \
    "    if (!@isRTCPeerConnection(this))\n" \
    "        return @Promise.@reject(new @TypeError(\"Function should be called on an RTCPeerConnection\"));\n" \
    "    const peerConnection = this;\n" \
    "    return @callbacksAndDictionaryOverload(arguments, \"createAnswer\", function (options) {\n" \
    "        return @enqueueOperation(peerConnection, function () {\n" \
    "            return peerConnection.@queuedCreateAnswer(options);\n" \
    "        });\n" \
    "    }, function (successCallback, errorCallback, options) {\n" \
    "        @enqueueOperation(peerConnection, function () {\n" \
    "            return peerConnection.@queuedCreateAnswer(options).@then(successCallback, errorCallback);\n" \
    "        });\n" \
    "        return @Promise.@resolve(@undefined);\n" \
    "    });\n" \
    "})\n" \
;

const JSC::ConstructAbility s_rtcPeerConnectionSetLocalDescriptionCodeConstructAbility = JSC::ConstructAbility::CannotConstruct;
const int s_rtcPeerConnectionSetLocalDescriptionCodeLength = 923;
static const JSC::Intrinsic s_rtcPeerConnectionSetLocalDescriptionCodeIntrinsic = JSC::NoIntrinsic;
const char* s_rtcPeerConnectionSetLocalDescriptionCode =
    "(function ()\n" \
    "{\n" \
    "    \"use strict\";\n" \
    "    if (!@isRTCPeerConnection(this))\n" \
    "        return @Promise.@reject(new @TypeError(\"Function should be called on an RTCPeerConnection\"));\n" \
    "    const peerConnection = this;\n" \
    "    const objectInfo = {\n" \
    "        \"constructor\": @RTCSessionDescription,\n" \
    "        \"argName\": \"description\",\n" \
    "        \"argType\": \"RTCSessionDescription\"\n" \
    "    };\n" \
    "    return @objectAndCallbacksOverload(arguments, \"setLocalDescription\", objectInfo, function (description) {\n" \
    "        return @enqueueOperation(peerConnection, function () {\n" \
    "            return peerConnection.@queuedSetLocalDescription(description);\n" \
    "        });\n" \
    "    }, function (description, successCallback, errorCallback) {\n" \
    "        @enqueueOperation(peerConnection, function () {\n" \
    "            return peerConnection.@queuedSetLocalDescription(description).@then(successCallback, errorCallback);\n" \
    "        });\n" \
    "        return @Promise.@resolve(@undefined);\n" \
    "    });\n" \
    "})\n" \
;

const JSC::ConstructAbility s_rtcPeerConnectionSetRemoteDescriptionCodeConstructAbility = JSC::ConstructAbility::CannotConstruct;
const int s_rtcPeerConnectionSetRemoteDescriptionCodeLength = 926;
static const JSC::Intrinsic s_rtcPeerConnectionSetRemoteDescriptionCodeIntrinsic = JSC::NoIntrinsic;
const char* s_rtcPeerConnectionSetRemoteDescriptionCode =
    "(function ()\n" \
    "{\n" \
    "    \"use strict\";\n" \
    "    if (!@isRTCPeerConnection(this))\n" \
    "        return @Promise.@reject(new @TypeError(\"Function should be called on an RTCPeerConnection\"));\n" \
    "    const peerConnection = this;\n" \
    "    const objectInfo = {\n" \
    "        \"constructor\": @RTCSessionDescription,\n" \
    "        \"argName\": \"description\",\n" \
    "        \"argType\": \"RTCSessionDescription\"\n" \
    "    };\n" \
    "    return @objectAndCallbacksOverload(arguments, \"setRemoteDescription\", objectInfo, function (description) {\n" \
    "        return @enqueueOperation(peerConnection, function () {\n" \
    "            return peerConnection.@queuedSetRemoteDescription(description);\n" \
    "        });\n" \
    "    }, function (description, successCallback, errorCallback) {\n" \
    "        @enqueueOperation(peerConnection, function () {\n" \
    "            return peerConnection.@queuedSetRemoteDescription(description).@then(successCallback, errorCallback);\n" \
    "        });\n" \
    "        return @Promise.@resolve(@undefined);\n" \
    "    });\n" \
    "})\n" \
;

const JSC::ConstructAbility s_rtcPeerConnectionAddIceCandidateCodeConstructAbility = JSC::ConstructAbility::CannotConstruct;
const int s_rtcPeerConnectionAddIceCandidateCodeLength = 889;
static const JSC::Intrinsic s_rtcPeerConnectionAddIceCandidateCodeIntrinsic = JSC::NoIntrinsic;
const char* s_rtcPeerConnectionAddIceCandidateCode =
    "(function ()\n" \
    "{\n" \
    "    \"use strict\";\n" \
    "    if (!@isRTCPeerConnection(this))\n" \
    "        return @Promise.@reject(new @TypeError(\"Function should be called on an RTCPeerConnection\"));\n" \
    "    const peerConnection = this;\n" \
    "    const objectInfo = {\n" \
    "        \"constructor\": @RTCIceCandidate,\n" \
    "        \"argName\": \"candidate\",\n" \
    "        \"argType\": \"RTCIceCandidate\"\n" \
    "    };\n" \
    "    return @objectAndCallbacksOverload(arguments, \"addIceCandidate\", objectInfo, function (candidate) {\n" \
    "        return @enqueueOperation(peerConnection, function () {\n" \
    "            return peerConnection.@queuedAddIceCandidate(candidate);\n" \
    "        });\n" \
    "    }, function (candidate, successCallback, errorCallback) {\n" \
    "        @enqueueOperation(peerConnection, function () {\n" \
    "            return peerConnection.@queuedAddIceCandidate(candidate).@then(successCallback, errorCallback);\n" \
    "        });\n" \
    "        return @Promise.@resolve(@undefined);\n" \
    "    });\n" \
    "})\n" \
;

const JSC::ConstructAbility s_rtcPeerConnectionGetStatsCodeConstructAbility = JSC::ConstructAbility::CannotConstruct;
const int s_rtcPeerConnectionGetStatsCodeLength = 741;
static const JSC::Intrinsic s_rtcPeerConnectionGetStatsCodeIntrinsic = JSC::NoIntrinsic;
const char* s_rtcPeerConnectionGetStatsCode =
    "(function ()\n" \
    "{\n" \
    "    \"use strict\";\n" \
    "    if (!@isRTCPeerConnection(this))\n" \
    "        return @Promise.@reject(new @TypeError(\"Function should be called on an RTCPeerConnection\"));\n" \
    "    const peerConnection = this;\n" \
    "    const objectInfo = {\n" \
    "        \"constructor\": @MediaStreamTrack,\n" \
    "        \"argName\": \"selector\",\n" \
    "        \"argType\": \"MediaStreamTrack\",\n" \
    "        \"defaultsToNull\": true\n" \
    "    };\n" \
    "    return @objectAndCallbacksOverload(arguments, \"getStats\", objectInfo, function (selector) {\n" \
    "        return peerConnection.@privateGetStats(selector);\n" \
    "    }, function (selector, successCallback, errorCallback) {\n" \
    "        peerConnection.@privateGetStats(selector).@then(successCallback, errorCallback);\n" \
    "        return @Promise.@resolve(@undefined);\n" \
    "    });\n" \
    "})\n" \
;


#define DEFINE_BUILTIN_GENERATOR(codeName, functionName, argumentCount) \
JSC::FunctionExecutable* codeName##Generator(JSC::VM& vm) \
{\
    JSVMClientData* clientData = static_cast<JSVMClientData*>(vm.clientData); \
    return clientData->builtinFunctions().rtcPeerConnectionBuiltins().codeName##Executable()->link(vm, clientData->builtinFunctions().rtcPeerConnectionBuiltins().codeName##Source(), Nullopt, s_##codeName##Intrinsic); \
}
WEBCORE_FOREACH_RTCPEERCONNECTION_BUILTIN_CODE(DEFINE_BUILTIN_GENERATOR)
#undef DEFINE_BUILTIN_GENERATOR


} // namespace WebCore

#endif // ENABLE(WEB_RTC)
