<!doctype html>
<meta charset=utf-8>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="RTCPeerConnection-helper.js"></script>
<script>
'use strict';

async function hasStats(pc, type) {
  const report = await pc.getStats();
  for (const stats of report.values()) {
    if (stats.type == type) {
      return true;
    }
  }
  return false;
}

async function getInboundRtpPollUntilItExists(pc, kTimeoutMs = 10000) {
  const t0 = performance.now();
  while (performance.now() - t0 < kTimeoutMs) {
    const report = await pc.getStats();
    for (const stats of report.values()) {
      if (stats.type == 'inbound-rtp') {
        return stats;
      }
    }
  }
  return null;
}

promise_test(async t => {
  const pc = new RTCPeerConnection();
  t.add_cleanup(() => pc.close());

  pc.addTransceiver('video');
  assert_false(await hasStats(pc, 'outbound-rtp'),
               'outbound-rtp does not exist after addTransceiver');
  await pc.setLocalDescription();
  assert_false(await hasStats(pc, 'outbound-rtp'),
              'outbound-rtp does not exist in have-local-offer');
}, `RTCOutboundRtpStreamStats does not exist as early as have-local-offer`);

// This test does not exchange ICE candidates, meaning no packets are sent.
// We should still see outbound-rtp stats because they are created by the O/A.
promise_test(async t => {
  const pc1 = new RTCPeerConnection();
  t.add_cleanup(() => pc1.close());
  const pc2 = new RTCPeerConnection();
  t.add_cleanup(() => pc1.close());

  // Offer to send. See previous test for assertions that the outbound-rtp is
  // not created this early, which this test does not care about.
  pc1.addTransceiver('video');
  await pc1.setLocalDescription();

  // Answer to send.
  await pc2.setRemoteDescription(pc1.localDescription);
  const [transceiver] = pc2.getTransceivers();
  transceiver.direction = 'sendrecv';
  assert_false(await hasStats(pc2, 'outbound-rtp'),
               'outbound-rtp does not exist in has-remote-offer');
  await pc2.setLocalDescription();
  assert_true(await hasStats(pc2, 'outbound-rtp'),
              'outbound-rtp exists after answerer returns to stable');

  // Complete offerer negotiation.
  await pc1.setRemoteDescription(pc2.localDescription);
  assert_true(await hasStats(pc1, 'outbound-rtp'),
              'outbound-rtp exists after offerer returns to stable');
}, `RTCOutboundRtpStreamStats exists after returning to stable`);

promise_test(async t => {
  const pc1 = new RTCPeerConnection();
  t.add_cleanup(() => pc1.close());
  const pc2 = new RTCPeerConnection();
  t.add_cleanup(() => pc1.close());
  pc1.onicecandidate = e => pc2.addIceCandidate(e.candidate);
  pc2.onicecandidate = e => pc1.addIceCandidate(e.candidate);

  // Negotaite to send, but don't send anything yet (track is null).
  const {sender} = pc1.addTransceiver('video');
  await pc1.setLocalDescription();
  await pc2.setRemoteDescription(pc1.localDescription);
  await pc2.setLocalDescription();
  await pc1.setRemoteDescription(pc2.localDescription);
  assert_false(await hasStats(pc2, 'inbound-rtp'),
               'inbound-rtp does not exist before packets are received');

  // Start sending. This results in inbound-rtp being created.
  const stream = await getNoiseStream({video:true});
  const [track] = stream.getTracks();
  await sender.replaceTrack(track);
  const inboundRtp = await getInboundRtpPollUntilItExists(pc2);
  assert_not_equals(
      inboundRtp, null,
      'inbound-rtp should be created in response to the sender having a track');
  assert_greater_than(
      inboundRtp.packetsReceived, 0,
      'inbound-rtp must only exist after packets have been received');
}, `RTCInboundRtpStreamStats are created by packet reception`);
</script>
