<!doctype html>
<meta charset=utf-8>
<meta name="timeout" content="long">
<title></title>
<script src=/resources/testharness.js></script>
<script src=/resources/testharnessreport.js></script>
<script>
'use strict';

function peer(other, polite, fail = null) {
  const send = (tgt, msg) => tgt.postMessage(JSON.parse(JSON.stringify(msg)),
                                             "*");
  if (!fail) fail = e => send(window.parent, {error: `${e.name}: ${e.message}`});
  const pc = new RTCPeerConnection();

  if (!window.assert_equals) {
    window.assert_equals = (a, b, msg) => a === b ||
        fail(new Error(`${msg} expected ${b} but got ${a}`));
  }

  const commands = {
    async addTransceiver() {
      const transceiver = pc.addTransceiver("video");
      await new Promise(r => pc.addEventListener("negotiated", r, {once: true}));
      if (!transceiver.currentDirection) {
        // Might have just missed the negotiation train. Catch next one.
        await new Promise(r => pc.addEventListener("negotiated", r, {once: true}));
      }
      assert_equals(transceiver.currentDirection, "sendonly", "have direction");
      return pc.getTransceivers().length;
    },
    async simpleConnect() {
      const p = commands.addTransceiver();
      await new Promise(r => pc.oniceconnectionstatechange =
                        () => pc.iceConnectionState == "connected" && r());
      return await p;
    },
    async getNumTransceivers() {
      return pc.getTransceivers().length;
    },
  };

  try {
    pc.addEventListener("icecandidate", ({candidate}) => send(other,
                                                              {candidate}));
    let makingOffer = false, ignoreOffer = false;
    pc.addEventListener("negotiationneeded", async () => {
      try {
        assert_equals(pc.signalingState, "stable", "negotiationneeded always fires in stable state");
        assert_equals(makingOffer, false, "negotiationneeded not already in progress");
        makingOffer = true;
        await pc.setLocalDescription();
        assert_equals(pc.signalingState, "have-local-offer", "negotiationneeded not racing with onmessage");
        assert_equals(pc.localDescription.type, "offer", "negotiationneeded SLD worked");
        send(other, {description: pc.localDescription});
      } catch (e) {
        fail(e);
      } finally {
        makingOffer = false;
      }
    });
    window.onmessage = async ({data: {description, candidate, run}}) => {
      try {
        if (description) {
          ignoreOffer = description.type == "offer" && !polite &&
                         (makingOffer || pc.signalingState != "stable");
          if (ignoreOffer) {
            return;
          }
          await pc.setRemoteDescription(description);
          if (description.type == "offer") {
            assert_equals(pc.signalingState, "have-remote-offer", "Remote offer");
            assert_equals(pc.remoteDescription.type, "offer", "SRD worked");
            await pc.setLocalDescription();
            assert_equals(pc.signalingState, "stable", "onmessage not racing with negotiationneeded");
            assert_equals(pc.localDescription.type, "answer", "onmessage SLD worked");
            send(other, {description: pc.localDescription});
          } else {
            assert_equals(pc.remoteDescription.type, "answer", "Answer was set");
            assert_equals(pc.signalingState, "stable", "answered");
            pc.dispatchEvent(new Event("negotiated"));
          }
        } else if (candidate) {
          try {
            await pc.addIceCandidate(candidate);
          } catch (e) {
            if (!ignoreOffer) throw e;
          }
        } else if (run) {
          send(window.parent, {[run.id]: await commands[run.cmd]() || 0});
        }
      } catch (e) {
        fail(e);
      }
    };
  } catch (e) {
    fail(e);
  }
  return pc;
}

async function setupPeerIframe(t, polite) {
  const iframe = document.createElement("iframe");
  t.add_cleanup(() => iframe.remove());
  iframe.srcdoc =
   `<html\><script\>(${peer.toString()})(window.parent, ${polite});</script\></html\>`;
  document.documentElement.appendChild(iframe);

  const failCatcher = t.step_func(({data}) =>
      ("error" in data) && assert_unreached(`Error in iframe: ${data.error}`));
  window.addEventListener("message", failCatcher);
  t.add_cleanup(() => window.removeEventListener("message", failCatcher));
  await new Promise(r => iframe.onload = r);
  return iframe;
}

function setupPeerTopLevel(t, other, polite) {
  const pc = peer(other, polite, t.step_func(e => { throw e; }));
  t.add_cleanup(() => { pc.close(); window.onmessage = null; });
}

let counter = 0;
async function run(target, cmd) {
  const id = `result${counter++}`;
  target.postMessage({run: {cmd, id}}, "*");
  return new Promise(r => window.addEventListener("message",
                                                  function listen({data}) {
    if (!(id in data)) return;
    window.removeEventListener("message", listen);
    r(data[id]);
  }));
}

let iframe;
async function setupAB(t, politeA, politeB) {
  iframe = await setupPeerIframe(t, politeB);
  return setupPeerTopLevel(t, iframe.contentWindow, politeA);
}
const runA = cmd => run(window, cmd);
const runB = cmd => run(iframe.contentWindow, cmd);
const runBoth = (cmdA, cmdB = cmdA) => Promise.all([runA(cmdA), runB(cmdB)]);

async function promise_test_both_roles(f, name) {
  promise_test(async t => f(t, await setupAB(t, true, false)), name);
  promise_test(async t => f(t, await setupAB(t, false, true)),
               `${name} with roles reversed`);
}

promise_test_both_roles(async (t, pc) => {
  assert_equals(await runA("simpleConnect"), 1, "one transceiver");
  assert_equals(await runB("addTransceiver"), 2, "two transceivers");
}, "Perfect negotiation setup connects");

promise_test_both_roles(async (t, pc) => {
  await runBoth("addTransceiver");
  const [numA, numB] = await runBoth("getNumTransceivers");
  assert_equals(numA, 2, "two transceivers on side A");
  assert_equals(numB, 2, "two transceivers on side B");
}, "Perfect negotiation glare");

promise_test_both_roles(async (t, pc) => {
  const ps = [];
  for (let i = 20; i > 0; i--) {
    ps.push(runBoth("addTransceiver"));
    await new Promise(r => t.step_timeout(r, i - 1));
  }
  ps.push(runBoth("addTransceiver"));
  await Promise.all(ps);
  const [numA, numB] = await runBoth("getNumTransceivers");
  assert_equals(numA, 42, "42 transceivers on side A");
  assert_equals(numB, 42, "42 transceivers on side B");
}, "Perfect negotiation stress glare");

promise_test_both_roles(async (t, pc) => {
  const ps = [];
  for (let i = 20; i > 0; i--) {
    ps.push(runBoth("addTransceiver"));
    await new Promise(r => t.step_timeout(r, 0));
  }
  ps.push(runBoth("addTransceiver"));
  await Promise.all(ps);
  const [numA, numB] = await runBoth("getNumTransceivers");
  assert_equals(numA, 42, "42 transceivers on side A");
  assert_equals(numB, 42, "42 transceivers on side B");
}, "Perfect negotiation stress glare linear");
</script>
