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

            let audioSender;
            let senderFromAddTrack;

            description("Test that RTCPeerConnection.addTrack reuses an unused sender of the same kind if present");

            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;

                audioTrack = stream.getAudioTracks()[0];
                videoTrack = stream.getVideoTracks()[0];

                remotePc.addTrack(audioTrack, stream);
                return remotePc.createOffer();
            })
            .then(function (audioOffer) {
                return pc.setRemoteDescription(audioOffer);
            })
            .then(function () {
                debug("*** Remote description with audio offer set");

                shouldBe("pc.getSenders().length", "1");
                shouldBe("pc.getReceivers().length", "1");
                shouldBe("pc.getReceivers()[0].track.kind", "'audio'");
                shouldBe("pc.getTransceivers().length", "1");

                debug("<br>*** Check unused sender");
                evalAndLog("audioSender = pc.getSenders()[0]");
                shouldBe("audioSender.track", "null");

                debug("<br>*** Adding a video track should not reuse audioSender (wrong kind)");
                evalAndLog("senderFromAddTrack = pc.addTrack(videoTrack, stream)");
                shouldNotBe("senderFromAddTrack", "audioSender");

                debug("<br>*** An extra sender should have been added");
                shouldBe("pc.getSenders().length", "2");
                shouldBeTrue("pc.getSenders().includes(audioSender)");
                shouldBeTrue("pc.getSenders().includes(senderFromAddTrack)");

                debug("<br>*** Adding an audio track should reuse audioSender");
                evalAndLog("senderFromAddTrack = pc.addTrack(audioTrack, stream)");
                shouldBe("senderFromAddTrack", "audioSender");
                shouldBe("audioSender.track", "audioTrack");

                debug("<br>*** The number of senders should not have changed");
                shouldBe("pc.getSenders().length", "2");

                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>
