<!DOCTYPE html>
<html>
    <head>
        <script src="../../resources/js-test-pre.js"></script>
    </head>
    <body>
        <script>
            let stream;

            description("Test that a negotiationneeded event is fired when not all local media can be included in an answer");

            if (window.testRunner)
                testRunner.setUserMediaPermission(true);
            else {
                debug("This test can not be run without the testRunner");
                finishJSTest();
            }

            const pc = new RTCPeerConnection({iceServers:[{urls:'stun:foo.com'}]});
            const remotePc = new RTCPeerConnection({iceServers:[{urls:'stun:foo.com'}]});

            navigator.mediaDevices.getUserMedia({ "audio": true, "video": true })
            .then(function (s) {
                stream = s;

                pc.onnegotiationneeded = () => {
                    testPassed("negotiationneededevent fired: There is local media added with addTrack");
                    startTest();
                };

                shouldBe("pc.signalingState", "'stable'");
                debug("Add local audio and video tracks to pc");
                evalAndLog("pc.addTrack(stream.getAudioTracks()[0], stream)");
                evalAndLog("pc.addTrack(stream.getVideoTracks()[0], stream)");
                shouldBe("pc.getTransceivers().length", "2");
            })
            .catch(function (error) {
                testFailed("Error in promise chain: " + error);
                finishJSTest();
            });

            function startTest() {
                debug("<br>Register a new handler for the negotiationneededevent");
                pc.onnegotiationneeded = () => {
                    testPassed("negotiationneededevent fired: There is local media not negotiated that needs to be negotiated in a follow-up offer");
                };

                remotePc.addTrack(stream.getAudioTracks()[0], stream);
                shouldBe("remotePc.getTransceivers().length", "1");

                debug("Create a remote offer with audio only");
                return remotePc.createOffer().then(function (offer) {
                    debug("Set remote offer as remote description");
                    return pc.setRemoteDescription(offer);
                })
                .then(function () {
                    testPassed("Remote offer set");
                    shouldBe("pc.getTransceivers().length", "2");

                    debug("Create an answer for the audio only offer");
                    return pc.createAnswer();
                })
                .then(function (answer) {
                    debug("Set answer as local description");
                    return pc.setLocalDescription(answer);
                })
                .then(function () {
                    testPassed("Answer set");

                    finishJSTest();
                })
                .catch(function (error) {
                    testFailed("Error in promise chain: " + error);
                    finishJSTest();
                });
            }

            window.jsTestIsAsync = true;
            window.successfullyParsed = true;

        </script>
        <script src="../../resources/js-test-post.js"></script>
    </body>
</html>
