<!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>
        <video id="video" muted playsinline></video>
        <script src ="routines.js"></script>
        <script>
promise_test((test) => {
    if (window.testRunner)
        testRunner.setUserMediaPermission(true);

    var firstConnection, secondConnection;
    var localConnectionStates = ["new"];
    var remoteConnectionStates = ["new"];
    var localIceConnectionStates = ["new"];
    var remoteIceConnectionStates = ["new"];
    var localGatheringStates = ["new"];
    var remoteGatheringStates = ["new"];
    return navigator.mediaDevices.getUserMedia({ video: true}).then((stream) => {
        return new Promise((resolve, reject) => {
            createConnections((connection) => {
                firstConnection = connection;
                firstConnection.addTrack(stream.getVideoTracks()[0], stream);
                assert_equals(firstConnection.connectionState, "new");
                firstConnection.onconnectionstatechange = () => {
                    localConnectionStates.push(firstConnection.connectionState);
                }
                firstConnection.onicegatheringstatechange = () => {
                    localGatheringStates.push(firstConnection.iceGatheringState);
                }
                firstConnection.oniceconnectionstatechange = () => {
                    if (firstConnection.iceConnectionState !== 'completed')
                        localIceConnectionStates.push(firstConnection.iceConnectionState);
                }
            }, (connection) => {
                secondConnection = connection;
                assert_equals(secondConnection.connectionState, "new");
                secondConnection.onconnectionstatechange = () => {
                    remoteConnectionStates.push(secondConnection.connectionState);
                }
                secondConnection.onicegatheringstatechange = () => {
                    remoteGatheringStates.push(secondConnection.iceGatheringState);
                }
                secondConnection.oniceconnectionstatechange = () => {
                    if (secondConnection.iceConnectionState !== 'completed')
                        remoteIceConnectionStates.push(secondConnection.iceConnectionState);
                }
                secondConnection.ontrack = (trackEvent) => {
                    resolve(trackEvent.streams[0]);
                };
            });
            setTimeout(() => reject("Test timed out"), 5000);
        });
    }).then((stream) => {
        video.srcObject = stream;
        return video.play();
    }).then(() => {
        assert_array_equals(localConnectionStates, ["new", "connecting", "connected"]);
        assert_array_equals(remoteConnectionStates, ["new", "connecting", "connected"]);
        assert_array_equals(localGatheringStates, ["new", "gathering", "complete"]);
        assert_array_equals(remoteGatheringStates, ["new", "gathering", "complete"]);
        assert_array_equals(localIceConnectionStates, ["new", "checking", "connected"]);
        assert_array_equals(remoteIceConnectionStates, ["new", "checking", "connected"]);
    });
}, "Checking various connection state for video exchange");

promise_test((test) => {
    return new Promise((resolve, reject) => {
        var pc = new RTCPeerConnection();
        pc.onconnectionstatechange = () => {
            assert_unreached();
        };
        pc.close();
        setTimeout(resolve, 200);
    })
}, "Checking connection state event when closing peer connetion");
        </script>
    </body>
</html>
