<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
<html>
    <head>
        <script src="../../resources/js-test-pre.js"></script>
        <script src="./resources/getUserMedia-helper.js"></script>
    </head>
    <body>
        <script>
            description("Tests RTCPeerConnection [add|remove]Stream.");

            var stream = null;
            var stream2 = null;
            var pc = null;

            function error()
            {
                testFailed('Stream generation failed.');
                finishJSTest();
            }

            function getUserMedia(dictionary, callback)
            {
                try {
                    navigator.mediaDevices.getUserMedia(dictionary)
                        .then(callback)
                        .catch(error);
                } catch (e) {
                    testFailed('webkitGetUserMedia threw exception :' + e);
                    finishJSTest();
                }
            }

            function onErroneousNegotiationNeeded()
            {
                testFailed('onErroneousNegotiationNeeded was called.');
                finishJSTest();
            }

            function onRemoveStream(event)
            {
                testPassed('onRemoveStream was called.');

                shouldBe('pc.getLocalStreams().length', '0');

                finishJSTest();
            }

            function onAddStream(event)
            {
                testPassed('onAddStream was called.');

                shouldBe('pc.getStreamById(stream.id)', 'stream');
                shouldBe('pc.getStreamById(stream2.id)', 'null');

                pc.onnegotiationneeded = onErroneousNegotiationNeeded;
                pc.addStream(stream);
                shouldBe('pc.getLocalStreams().length', '1');
                pc.removeStream(stream2);
                shouldBe('pc.getLocalStreams().length', '1');

                pc.onnegotiationneeded = onRemoveStream;
                pc.removeStream(stream);
            }

            function gotStream2(s)
            {
                testPassed('Got another stream.');
                stream2 = s;

                shouldBeFalse("stream.id === stream2.id");

                pc.onnegotiationneeded = onAddStream;
                pc.addStream(stream);
            }

            function gotStream1(s)
            {
                testPassed('Got a stream.');
                stream = s;

                pc = new RTCPeerConnection({iceServers:[{urls:'stun:foo.com'}]});
                pc.onnegotiationneeded = onErroneousNegotiationNeeded;
                shouldThrow("pc.addStream(null)");

                shouldBe('pc.getLocalStreams().length', '0');

                getUserMedia({audio:true, video:true}, gotStream2);
            }

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

            getUserMedia({audio:true, video:true}, gotStream1);

            window.jsTestIsAsync = true;
            window.successfullyParsed = true;
        </script>
        <script src="../../resources/js-test-post.js"></script>
    </body>
</html>
