<!doctype html>
<html>
    <head>
        <meta charset="utf-8">
        <script src="../resources/testharness.js"></script>
        <script src="../resources/testharnessreport.js"></script>
    </head>
    <body>
        <video id="local" autoplay playsInline></video>
        <video id="remote" autoplay playsInline></video>
        <script src ="routines.js"></script>
        <script>
async function doSFrameTest(codec, shouldClose)
{
    let pc1, pc2;
    let sender, receiver;
    const localStream = await navigator.mediaDevices.getUserMedia({video: true});
    const key = await crypto.subtle.importKey("raw", new Uint8Array([143, 77, 43, 10, 72, 19, 37, 67, 236, 219, 24, 93, 26, 165, 91, 178]), "HKDF", false, ["deriveBits", "deriveKey"]);
    const stream = await new Promise((resolve, reject) => {
        createConnections((firstConnection) => {
            pc1 = firstConnection;
            sender = firstConnection.addTrack(localStream.getTracks()[0], localStream);
            firstConnection.getTransceivers()[0].setCodecPreferences([codec]);
            let transform = new SFrameTransform({compatibilityMode: "H264"});
            transform.setEncryptionKey(key);
            sender.transform = transform;
        }, (secondConnection) => {
            pc2 = secondConnection;
            secondConnection.ontrack = (trackEvent) => {
                let transform = new SFrameTransform({compatibilityMode: "H264"});
                transform.setEncryptionKey(key);
                receiver = trackEvent.receiver;
                receiver.transform = transform;
                resolve(trackEvent.streams[0]);
            };
        });
        setTimeout(() => reject("Test timed out"), 5000);
    });
    local.srcObject = localStream;
    remote.srcObject = stream;
    await remote.play();

    if (window.internals) {
        const senderCounter = internals.sframeCounter(sender.transform);
        const receiverCounter = internals.sframeCounter(receiver.transform);

        let counter = 0;
        while (receiverCounter === internals.sframeCounter(receiver.transform) && ++counter < 100)
            await new Promise(resolve => setTimeout(resolve, 50));
        assert_not_equals(internals.sframeCounter(receiver.transform), receiverCounter, "receiver");

        counter = 0;
        while (senderCounter === internals.sframeCounter(sender.transform) && ++counter < 100)
            await new Promise(resolve => setTimeout(resolve, 50));
        assert_not_equals(internals.sframeCounter(sender.transform), senderCounter, "sender");
    }
    if (shouldClose) {
        pc1.close();
        pc2.close();
    }
}

promise_test((test) => {
    return doSFrameTest({clockRate: 90000, mimeType: "video/H264", sdpFmtpLine: "level-asymmetry-allowed=1;packetization-mode=1;profile-level-id=42e01f"}, "H264", true);
}, "Video exchange with SFrame - H264 baseline");

promise_test((test) => {
    return doSFrameTest({clockRate: 90000, mimeType: "video/H264", sdpFmtpLine: "level-asymmetry-allowed=1;packetization-mode=1;profile-level-id=640c1f"}, "H264", true);
}, "Video exchange with SFrame - H264 high");

promise_test((test) => {
    return doSFrameTest({mimeType: "video/VP8", clockRate: 90000}, "VP8", false);
}, "Video exchange with SFrame - VP8");
        </script>
    </body>
</html>
