<!DOCTYPE html>
<html>
<head>
    <script src="../../resources/js-test-pre.js"></script>
    <script src="../../resources/platform-helper.js"></script>
</head>
<body onload="start()">
<p id="description"></p>
<div id="console"></div>
<video controls width="680" height="360"></video>
<canvas width="680" height="360"></canvas>
<script>
    let canvas;
    let context;
    let mediaStream;
    let video;
    let buffer;
    
    let timeout;

    function updateWatchdog()
    {
        if (timeout)
            clearTimeout(timeout);

        timeout = setTimeout(() => {
            console.log("Test took too long, timing out!");
            finishJSTest();
        }, 30000);
    }

    function canvasShouldBeBlack()
    {
        return !mediaStream.getVideoTracks()[0].enabled;
    }
    
    function attempt(numberOfTries, call, callback)
    {
        if (numberOfTries <= 0) {
            testFailed('Pixel check did not succeed after multiple tries.');
            return;
        }

        let attemptSucceeded = call();
        if (attemptSucceeded) {
            testPassed(canvasShouldBeBlack() ? 'pixel was black.' : 'pixel was white.');
            callback();

            return;
        }
        
        setTimeout(() => { attempt(--numberOfTries, call, callback); }, 50);
    }

    function repeatWithVideoPlayingAndFinishTest()
    {
        if (video.paused) {
            debug('<br> ===== play video =====');
            evalAndLog('video.play()');
            beginTestRound();
        } else {
            debug('');
            video.pause();
            if (timeout)
                clearTimeout(timeout);
            finishJSTest();
        }
    }

    function reenableTrack()
    {
        mediaStream.getVideoTracks()[0].enabled = true;
        updateWatchdog();
        debug(`<br> === video track reenabled, should render current frame ===`);

        // The video is not guaranteed to render non-black frames before the canvas is drawn to and the pixels are checked.
        // A timeout is used to ensure that the pixel check is done after the video renders non-black frames.
        attempt(10, checkPixels, repeatWithVideoPlayingAndFinishTest);
    }

    function checkPixels()
    {
        context.clearRect(0, 0, canvas.width, canvas.height);
        buffer = context.getImageData(30, 242, 1, 1).data;
        if (!isPixelTransparent(buffer))
            testFailed('pixel was not transparent after clearing canvas.');

        context.drawImage(video, 0, 0, canvas.width, canvas.height);
        buffer = context.getImageData(30, 242, 1, 1).data;

        if (!canvasShouldBeBlack())
            return isPixelWhite(buffer);
        else
            return isPixelBlack(buffer);
    }

    function disableAllTracks()
    {
        mediaStream.getVideoTracks()[0].enabled = false;
        updateWatchdog();
        debug('<br> === all video tracks disabled ===');
        
        // The video is not guaranteed to render black frames before the canvas is drawn to and the pixels are checked.
        // A timeout is used to ensure that the pixel check is done after the video renders black frames.
        attempt(10, checkPixels, reenableTrack);
    }

    function beginTestRound()
    {
        updateWatchdog();
        debug('<br> === beginning round of pixel tests ===');
        attempt(10, checkPixels, disableAllTracks);
    }

    function canplay()
    {
        canvas = document.querySelector('canvas');
        context = canvas.getContext('2d');

        beginTestRound();
    }

    function start()
    {
        description("Tests that re-enabling a video MediaStreamTrack when all tracks were previously disabled causes captured media to display.");
        if (window.testRunner)
            testRunner.setUserMediaPermission(true);

        video = document.querySelector('video');
        video.addEventListener('canplay', canplay);
        
        updateWatchdog();

        navigator.mediaDevices.getUserMedia({ video : true })
            .then((stream) => {
                mediaStream = stream;
                testPassed('mediaDevices.getUserMedia generated a stream successfully.');
                evalAndLog('video.srcObject = mediaStream');
            });
    }

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