<!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>
        <script src="routines.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");

function grabImagePixels()
{
    canvas.width = video.videoWidth;
    canvas.height = video.videoHeight;
    canvas.getContext('2d').drawImage(video, 0, 0, canvas.width, canvas.height);

    imageData = canvas.getContext('2d').getImageData(20, 20, 2, 2);
    return imageData.data;
 }

async function testFrontCameraImage(counter)
{
    if (!counter)
        counter = 0;

    if (isVideoBlack(canvas, video, 20, 20, 2 ,2))
        return;

    if (counter >= 20)
        return Promise.reject("testFrontCameraImage timed out");

    await waitFor(50);
    return testFrontCameraImage(++counter);
}

function isBetween100And200(value)
{
     return data[0] > 100 && data[0] < 200;
}

async function testBackCameraImage(counter)
{
    if (!counter)
        counter = 0;

    data = grabImagePixels();

    if(isBetween100And200(data[0]) && isBetween100And200(data[1]) && isBetween100And200(data[2]))
        return;

    if (counter >= 20)
        return Promise.reject("testFrontCameraImage timed out");

    await waitFor(50);
    return testBackCameraImage(++counter);
}

promise_test((test) => {
    if (window.testRunner)
        testRunner.setUserMediaPermission(true);

    var sender;
    var frontStream;
    var backStream;
    return navigator.mediaDevices.getUserMedia({ video: { facingMode: { exact: ["user"] } } }).then((stream) => {
        frontStream = stream;
        return new Promise((resolve, reject) => {
            createConnections((firstConnection) => {
                sender = firstConnection.addTrack(frontStream.getVideoTracks()[0], frontStream);
           }, (secondConnection) => {
                secondConnection.ontrack = (trackEvent) => {
                    resolve(trackEvent.streams[0]);
                };
            });
            setTimeout(() => reject("Test timed out"), 5000);
        });
    }).then((remoteStream) => {
        video.srcObject = remoteStream;
        return video.play();
    }).then(() => {
        return testFrontCameraImage();
    }).then(() => {
        return navigator.mediaDevices.getUserMedia({ video: { facingMode: { exact: ["environment"] } } });
    }).then((stream) => {
        backStream = stream;
        var currentTrack = sender.track;
        promise = sender.replaceTrack(backStream.getVideoTracks()[0]);
        assert_true(currentTrack === sender.track);
        return promise;
    }).then(() => {
        assert_true(sender.track === backStream.getVideoTracks()[0]);
        return testBackCameraImage();
    });
}, "Switching from front to back camera");

var didReplaceTrack = false;
promise_test((test) => {
    if (window.testRunner)
        testRunner.setUserMediaPermission(true);

    var sender;
    var frontStream;
    var backStream;

    return navigator.mediaDevices.getUserMedia({ video: { width: 640, height: 480, facingMode: { exact: ["user"] } } }).then((stream) => {
        frontStream = stream;
        assert_true(frontStream.getVideoTracks()[0].getSettings().height === 480, "frontStream should be big");
        return new Promise((resolve, reject) => {
            createConnections((firstConnection) => {
                sender = firstConnection.addTrack(frontStream.getVideoTracks()[0], frontStream);
                firstConnection.addEventListener('negotiationneeded', test.step_func(() => {
                    assert_false(didReplaceTrack, 'negotiationeeded should not be called after replacing an ongoing track');
                }));
            }, (secondConnection) => {
                secondConnection.ontrack = (trackEvent) => {
                    resolve(trackEvent.streams[0]);
                };
            });
            setTimeout(() => reject("Test timed out"), 5000);
        });
    }).then((remoteStream) => {
        video.srcObject = remoteStream;
        return video.play();
    }).then(() => {
        return testFrontCameraImage();
    }).then(() => {
        return navigator.mediaDevices.getUserMedia({ video: { width: 320, height: 240, facingMode: { exact: ["environment"] } } });
    }).then((stream) => {
        backStream = stream;
        assert_true(backStream.getVideoTracks()[0].getSettings().height === 240, "backStream should be small");
        didReplaceTrack = true;
        return sender.replaceTrack(backStream.getVideoTracks()[0]);
    }).then(() => {
        return testBackCameraImage();
    });
}, "Switching from front to back camera, with lower resolution");

promise_test((test) => {
    if (window.testRunner)
        testRunner.setUserMediaPermission(true);

    var sender;
    var frontStream;
    var backStream;

    return navigator.mediaDevices.getUserMedia({ video: { width: 320, height: 240, facingMode: { exact: ["user"] } } }).then((stream) => {
        frontStream = stream;
        assert_true(frontStream.getVideoTracks()[0].getSettings().height === 240, "front stream should be small");
    }).then(() => {
        return new Promise((resolve, reject) => {
            createConnections((firstConnection) => {
                sender = firstConnection.addTrack(frontStream.getVideoTracks()[0], frontStream);
            }, (secondConnection) => {
                secondConnection.ontrack = (trackEvent) => {
                    resolve(trackEvent.streams[0]);
                };
            });
            setTimeout(() => reject("Test timed out"), 5000);
        });
    }).then((remoteStream) => {
        video.srcObject = remoteStream;
        return video.play();
    }).then(() => {
        return testFrontCameraImage();
    }).then(() => {
        return navigator.mediaDevices.getUserMedia({ video: { width: 640, height: 480 , facingMode: { exact: ["environment"] } } });
    }).then((stream) => {
        backStream = stream;
        assert_true(backStream.getVideoTracks()[0].getSettings().height === 480, "back stream should be big");
        return sender.replaceTrack(backStream.getVideoTracks()[0]);
    }).then(() => {
        return testBackCameraImage();
    });

}, "Switching from front to back camera, with higher resolution");

promise_test(async (test) => {
    const stream = await navigator.mediaDevices.getUserMedia({ video: true });
    const pc = new RTCPeerConnection();
    pc.addTransceiver("video", {direction: "sendonly"});
    const sender = pc.addTrack(stream.getVideoTracks()[0], stream);
    await sender.replaceTrack(stream.getVideoTracks()[0].clone());
}, "Replace a track for a sender created by addTransceiver and used by addTrack");
        </script>
    </body>
</html>
