<!DOCTYPE HTML>
<html>
<head>
  <script type="application/javascript" src="pc.js"></script>
</head>
<body>
<pre id="test">
<script type="application/javascript">
  createHTML({
    bug: "1363667",
    title: "Test audio receiver getSynchronizationSources"
  });

  var waitForSyncSources = async (test) => {
    let receivers = [...test.pcRemote.getReceivers(),
                     ...test.pcLocal.getReceivers()];
    is(receivers.length, 2, "Expected number of receivers");
    // Wait for sync sources
    while (true) {
        if (receivers[0].getSynchronizationSources().length &&
            receivers[1].getSynchronizationSources().length) {
        break;
      }
      await wait(250);
    }
  };

  var testGetSynchronizationSources = async (test) => {
    await waitForSyncSources(test);
    let receivers = [...test.pcRemote.getReceivers(),
                     ...test.pcLocal.getReceivers()];
    is(receivers.length, 2,
       `Expected number of receivers is 2. (${receivers.length})`);
    for (let recv of receivers) {
      let syncSources = recv.getSynchronizationSources();
      ok(syncSources,
         "Receiver has Synchronization sources " + JSON.stringify(syncSources));
      is(syncSources.length, 1, "Each receiver has only a single sync source");
      let source = recv.getSynchronizationSources()[0];
      ok(source.audioLevel !== null,
         `Synchronization source has audio level. (${source.audioLevel})`);
      ok(source.audioLevel >= 0.0,
         `Synchronization source audio level >= 0.0 (${source.audioLevel})`);
      ok(source.audioLevel <= 1.0,
         `Synchronization source audio level <= 1.0 (${source.audioLevel})`);
      ok(source.timestamp,
         `Synchronization source has timestamp (${source.timestamp})`);
      const ageSeconds =
        (window.performance.now() + window.performance.timeOrigin -
         source.timestamp) / 1000;
      ok(ageSeconds >= 0,
         `Synchronization source timestamp is in the past`);
      ok(ageSeconds < 2.5,
         `Synchronization source timestamp is close to now`);
      is(source.voiceActivityFlag, undefined,
        "Synchronization source unsupported voiceActivity is undefined");
    }
  };

  var testSynchronizationSourceCached = async (test) => {
    await waitForSyncSources(test);
    let receivers = [...test.pcRemote.getReceivers(),
                     ...test.pcLocal.getReceivers()];
    is(receivers.length, 2,
       `Expected number of receivers is 2. (${receivers.length})`);
    let sourceSets = [[],[]];
    for (let sourceSet of sourceSets) {
      for (let recv of receivers) {
        let sources = recv.getSynchronizationSources();
        is(sources.length, 1,
           `Expected number of sources is 1. (${sources.length})`);
        sourceSet.push(sources);
      }
      // Busy wait 1s before trying again
      let endTime = performance.now() + 1000;
      while (performance.now() < endTime) {};
    }
    is(JSON.stringify(sourceSets[0]), JSON.stringify(sourceSets[1]),
       "Subsequent getSynchronizationSources calls are cached.");
  };

  var test;
  runNetworkTest(function(options) {
    test = new PeerConnectionTest(options);
    test.chain.insertAfter("PC_REMOTE_WAIT_FOR_MEDIA_FLOW",
      [testGetSynchronizationSources,
       testSynchronizationSourceCached]);
    test.setMediaConstraints([{audio: true}], [{audio: true}]);
    test.pcLocal.audioElementsOnly = true;
    return test.run();
  });
</script>
</pre>
</body>
</html>
