<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <title>Capture source failure.</title>
    <script src="../../resources/testharness.js"></script>
    <script src="../../resources/testharnessreport.js"></script>
 </head>
<body>
    <video width=320 height=240></video>

    <script>

    let video;

    function waitForPageStateChange(numberOfTries, originalState, resolve, reject)
    {
        let newState = internals.pageMediaState();
        if (newState != originalState) {
            resolve(newState);
            return;
        }

        if (numberOfTries <= 0) {
            reject('Page state did not change in time, original state is ' + originalState);
            return;
        }

        setTimeout(() => { waitForPageStateChange(--numberOfTries, originalState, resolve, reject); }, 10);
    }

    function testTrack(track, title)
    {
        promise_test((test) => {
            return new Promise((resolve, reject) => {
                const mediaState = internals.pageMediaState();
                let trackEndedEventFired = false;
                track.onended = () => {
                    assert_equals(track.readyState, "ended");
                    trackEndedEventFired = true;
                    new Promise((innerResolve, innerReject) => {
                        waitForPageStateChange(10, mediaState, innerResolve, innerReject)
                    }).then((pageMediaState) => {
                        assert_equals(video.videoTracks.length, 1, "Unexpected video track count");
                        assert_equals(video.audioTracks.length, 1, "Unexpected audio track count");
                        assert_equals(video.videoHeight + video.videoWidth, 0, "Video track should have no size");

                        if (window.internals) {
                            if (track.kind === "video") {
                                assert_false(pageMediaState.includes('HasMutedVideoCaptureDevice'), "Unexpected HasMutedVideoCaptureDevice");
                                assert_false(pageMediaState.includes('HasMutedAudioCaptureDevice'), "Unexpected HasMutedAudioCaptureDevice");
                                assert_true(pageMediaState.includes('HasActiveAudioCaptureDevice'), "Unexpected HasActiveAudioCaptureDevice");
                                assert_false(pageMediaState.includes('HasActiveVideoCaptureDevice'), "Unexpected HasActiveVideoCaptureDevice");
                            } else {
                                assert_false(pageMediaState.includes('HasMutedAudioCaptureDevice'), "Unexpected HasMutedAudioCaptureDevice");
                                assert_false(pageMediaState.includes('HasMutedVideoCaptureDevice'), "Unexpected HasMutedVideoCaptureDevice");
                                assert_false(pageMediaState.includes('HasActiveAudioCaptureDevice'), "Unexpected HasActiveAudioCaptureDevice");
                                assert_false(pageMediaState.includes('HasActiveVideoCaptureDevice'), "Unexpected HasActiveVideoCaptureDevice");
                            }
                        }
                        resolve();
                    })
                }

                if (window.internals) {
                    internals.simulateMediaStreamTrackCaptureSourceFailure(track);
                    assert_equals(track.readyState, "live");
                    setTimeout(() => {
                        assert_true(trackEndedEventFired, "ended");
                    }, 0);
                }
                setTimeout(() => reject("Device state did not change in 5 second"), 5000);

            });
        }, title);
    }

    promise_test((test) => {
        let stream;
        return navigator.mediaDevices.getUserMedia({ video: true, audio: true})
            .then(s => {
                stream = s;
                video = document.getElementsByTagName("video")[0];
                video.srcObject = stream;
            })
            .then(() => new Promise(resolve => video.onloadedmetadata = resolve))
            .then(() => {
                assert_equals(video.videoTracks.length, 1, "Expected one video track");
                assert_equals(video.audioTracks.length, 1, "Expected one audio track");
                testTrack(stream.getVideoTracks()[0], "End video track only");
                testTrack(stream.getAudioTracks()[0], "End audio track only");
            })
    }, "Create stream");

    </script>

</body>
</html>
