<!doctype html>
<html>
    <head>
        <meta charset="utf-8">
        <title>Testing basic video exchange from offerer to receiver</title>
        <script src="../resources/testharness.js"></script>
        <script src="../resources/testharnessreport.js"></script>
    </head>
    <body>
<div id="log"></div>
        <video id="video" autoplay=""></video>
        <canvas id="canvas" width="640" height="480"></canvas>
        <script src ="routines.js"></script>
        <script>
video = document.getElementById("video");
canvas = document.getElementById("canvas");

async function getOutboundRTPStatsNumberOfEncodedFrames(connection)
{
    var report = await connection.getStats();
    var framesEncoded;
    report.forEach((statItem) => {
        if (statItem.type === "outbound-rtp") {
            framesEncoded = statItem.framesEncoded;
        }
    });
    return framesEncoded;
}

async function testFrameEncodedStarted(connection, count, previousFramesNumber)
{
    var framesEncodedNumber = await getOutboundRTPStatsNumberOfEncodedFrames(connection);
    if (previousFramesNumber && framesEncodedNumber > previousFramesNumber)
        return;

    if (count === undefined)
        count = 0;

    if (count >= 20)
        return Promise.reject("test increasing frame encoded timed out");

    await waitFor(100);
    return testFrameEncodedStarted(connection, ++count, framesEncodedNumber);
}

async function testFrameEncodedStopped(connection, count, previousFramesNumber)
{
    var framesEncodedNumber = await getOutboundRTPStatsNumberOfEncodedFrames(connection);
    if (previousFramesNumber && framesEncodedNumber === previousFramesNumber)
        return;

    if (count === undefined)
        count = 0;

    if (count === 20)
        return Promise.reject("test that number of encoded frames stopped increasing timed out");

    await waitFor(100);
    return testFrameEncodedStopped(connection, ++count, framesEncodedNumber);
}

var sender;
var sendingTrack;
var connection;
promise_test(async (test) => {
    if (window.testRunner)
        testRunner.setUserMediaPermission(true);

    const frontStream = await navigator.mediaDevices.getUserMedia({ video: true });

    const remoteStream = await new Promise((resolve, reject) => {
        createConnections((firstConnection) => {
            connection = firstConnection;
            sender = firstConnection.addTrack(frontStream.getVideoTracks()[0], frontStream);
        }, (secondConnection) => {
            secondConnection.ontrack = (trackEvent) => {
                resolve(trackEvent.streams[0]);
            };
        });
        setTimeout(() => reject("Test timed out"), 5000);
    });

    video.srcObject = remoteStream;
    await video.play();
}, "Set-up test");

promise_test(async (test) => {
    await testFrameEncodedStarted(connection);

    sendingTrack = sender.track;
    assert_equals(sendingTrack.readyState, "live");
}, "Test that frame counter increases");

promise_test(async (test) => {
    promise = sender.replaceTrack(null);
    assert_true(!!sender.track);
    await promise;
    assert_equals(sender.track, null);
}, "Test replaceTrack with null track");

promise_test(async (test) => {
    await testFrameEncodedStopped(connection);
    assert_equals(sendingTrack.readyState, "live");
}, "Test that frame counter no longer increases");
        </script>
    </body>
</html>
