'use strict';
/* Helper functions to munge SDP and split the sending track into
 * separate tracks on the receiving end. This can be done in a number
 * of ways, the one used here uses the fact that the MID and RID header
 * extensions which are used for packet routing share the same wire
 * format. The receiver interprets the rids from the sender as mids
 * which allows receiving the different spatial resolutions on separate
 * m-lines and tracks.
 */
const extensionsToFilter = [
  'urn:ietf:params:rtp-hdrext:sdes:mid',
  'urn:ietf:params:rtp-hdrext:sdes:rtp-stream-id',
  'urn:ietf:params:rtp-hdrext:sdes:repaired-rtp-stream-id',
];

function swapRidAndMidExtensionsInSimulcastOffer(offer, rids) {
  const sections = SDPUtils.splitSections(offer.sdp);
  const dtls = SDPUtils.getDtlsParameters(sections[1], sections[0]);
  const ice = SDPUtils.getIceParameters(sections[1], sections[0]);
  const rtpParameters = SDPUtils.parseRtpParameters(sections[1]);

  // The gist of this hack is that rid and mid have the same wire format.
  const rid = rtpParameters.headerExtensions.find(ext => ext.uri === 'urn:ietf:params:rtp-hdrext:sdes:rtp-stream-id');
  rtpParameters.headerExtensions = rtpParameters.headerExtensions.filter(ext => {
    return !extensionsToFilter.includes(ext.uri);
  });
  // This tells the other side that the RID packets are actually mids.
  rtpParameters.headerExtensions.push({id: rid.id, uri: 'urn:ietf:params:rtp-hdrext:sdes:mid', direction: 'sendrecv'});

  // Filter rtx as we have no way to (re)interpret rrid.
  // Not doing this makes probing use RTX, it's not understood and ramp-up is slower.
  rtpParameters.codecs = rtpParameters.codecs.filter(c => c.name.toUpperCase() !== 'RTX');

  let sdp = SDPUtils.writeSessionBoilerplate() +
    SDPUtils.writeDtlsParameters(dtls, 'actpass') +
    SDPUtils.writeIceParameters(ice) +
    'a=group:BUNDLE ' + rids.join(' ') + '\r\n';
  const baseRtpDescription = SDPUtils.writeRtpDescription('video', rtpParameters);
  rids.forEach(rid => {
    sdp += baseRtpDescription +
        'a=mid:' + rid + '\r\n' +
        'a=msid:rid-' + rid + ' rid-' + rid + '\r\n';
  });
  return sdp;
}

function swapRidAndMidExtensionsInSimulcastAnswer(answer, localDescription, rids) {
  const sections = SDPUtils.splitSections(answer.sdp);
  const dtls = SDPUtils.getDtlsParameters(sections[1], sections[0]);
  const ice = SDPUtils.getIceParameters(sections[1], sections[0]);
  const rtpParameters = SDPUtils.parseRtpParameters(sections[1]);

  rtpParameters.headerExtensions = rtpParameters.headerExtensions.filter(ext => {
    return !extensionsToFilter.includes(ext.uri);
  });
  const localMid = SDPUtils.getMid(SDPUtils.splitSections(localDescription.sdp)[1]);
  let sdp = SDPUtils.writeSessionBoilerplate() +
    SDPUtils.writeDtlsParameters(dtls, 'active') +
    SDPUtils.writeIceParameters(ice) +
    'a=group:BUNDLE ' + localMid + '\r\n';
  sdp += SDPUtils.writeRtpDescription('video', rtpParameters);
  sdp += 'a=mid:' + localMid + '\r\n';

  rids.forEach(rid => {
    sdp += 'a=rid:' + rid + ' recv\r\n';
  });
  sdp += 'a=simulcast:recv ' + rids.join(';') + '\r\n';

  // Re-add headerextensions we filtered.
  const headerExtensions = SDPUtils.parseRtpParameters(SDPUtils.splitSections(localDescription.sdp)[1]).headerExtensions;
  headerExtensions.forEach(ext => {
    if (extensionsToFilter.includes(ext.uri)) {
      sdp += 'a=extmap:' + ext.id + ' ' + ext.uri + '\r\n';
    }
  });
  return sdp;
}

async function negotiateSimulcastAndWaitForVideo(t, rids, pc1, pc2, codec) {
  exchangeIceCandidates(pc1, pc2);

  const metadataToBeLoaded = [];
  pc2.ontrack = (e) => {
    const stream = e.streams[0];
    const v = document.createElement('video');
    v.autoplay = true;
    v.srcObject = stream;
    v.id = stream.id
    metadataToBeLoaded.push(new Promise((resolve) => {
        v.addEventListener('loadedmetadata', () => {
            resolve();
        });
    }));
  };

  // Use getUserMedia as getNoiseStream does not have enough entropy to ramp-up.
  const stream = await navigator.mediaDevices.getUserMedia({video: {width: 1280, height: 720}});
  t.add_cleanup(() => stream.getTracks().forEach(track => track.stop()));
  const transceiver = pc1.addTransceiver(stream.getVideoTracks()[0], {
    streams: [stream],
    sendEncodings: rids.map(rid => ({rid})),
  });
  if (codec) {
    preferCodec(transceiver, codec.mimeType, codec.sdpFmtpLine);
  }

  const offer = await pc1.createOffer();
  await pc1.setLocalDescription(offer),
  await pc2.setRemoteDescription({
    type: 'offer',
    sdp: swapRidAndMidExtensionsInSimulcastOffer(offer, rids),
  });
  const answer = await pc2.createAnswer();
  await pc2.setLocalDescription(answer);
  await pc1.setRemoteDescription({
    type: 'answer',
    sdp: swapRidAndMidExtensionsInSimulcastAnswer(answer, pc1.localDescription, rids),
  });
  assert_equals(metadataToBeLoaded.length, rids.length);
  return Promise.all(metadataToBeLoaded);
}
