'use strict';

// Test is based on the following editor draft:
// https://w3c.github.io/webrtc-pc/archives/20170605/webrtc.html

// Code using this helper should also include RTCPeerConnection-helper.js
// in the main HTML file

// The following helper functions are called from RTCPeerConnection-helper.js:
//   getTrackFromUserMedia
//   exchangeOfferAnswer

// Create a RTCDTMFSender using getUserMedia()
// Connect the PeerConnection to another PC and wait until it is
// properly connected, so that DTMF can be sent.
function createDtmfSender(pc = new RTCPeerConnection()) {
  let dtmfSender;
  return getTrackFromUserMedia('audio')
  .then(([track, mediaStream]) => {
    const sender = pc.addTrack(track, mediaStream);
    dtmfSender = sender.dtmf;
    assert_true(dtmfSender instanceof RTCDTMFSender,
                'Expect audio sender.dtmf to be set to a RTCDTMFSender');
    // Note: spec bug open - https://github.com/w3c/webrtc-pc/issues/1774
    // on whether sending should be possible before negotiation.
    const pc2 = new RTCPeerConnection();
    Object.defineProperty(pc, 'otherPc', { value: pc2 });
    exchangeIceCandidates(pc, pc2);
    return exchangeOfferAnswer(pc, pc2);
  }).then(() => {
    if (!('canInsertDTMF' in dtmfSender)) {
      return Promise.resolve();
    }
    // Wait until dtmfSender.canInsertDTMF becomes true.
    // Up to 150 ms has been observed in test. Wait 1 second
    // in steps of 10 ms.
    // Note: Using a short timeout and rejected promise in order to
    // make test return a clear error message on failure.
    return new Promise((resolve, reject) => {
      let counter = 0;
      step_timeout(function checkCanInsertDTMF() {
        if (dtmfSender.canInsertDTMF) {
          resolve();
        } else {
          if (counter >= 100) {
            reject('Waited too long for canInsertDTMF');
            return;
          }
          ++counter;
          step_timeout(checkCanInsertDTMF, 10);
        }
      }, 0);
    });
  }).then(() => {
    return dtmfSender;
  });
}

/*
  Create an RTCDTMFSender and test tonechange events on it.
    testFunc
      Test function that is going to manipulate the DTMFSender.
      It will be called with:
        t - the test object
        sender - the created RTCDTMFSender
        pc - the associated RTCPeerConnection as second argument.
    toneChanges
      Array of expected tonechange events fired. The elements
      are array of 3 items:
        expectedTone
          The expected character in event.tone
        expectedToneBuffer
          The expected new value of dtmfSender.toneBuffer
        expectedDuration
          The rough time since beginning or last tonechange event
          was fired.
    desc
      Test description.
 */
function test_tone_change_events(testFunc, toneChanges, desc) {
  // Convert to cumulative time
  let cumulativeTime = 0;
  const cumulativeToneChanges = toneChanges.map(c => {
    cumulativeTime += c[2];
    return [c[0], c[1], cumulativeTime];
  });

  // Wait for same duration as last expected duration + 100ms
  // before passing test in case there are new tone events fired,
  // in which case the test should fail.
  const lastWait = toneChanges.pop()[2] + 100;

  promise_test(async t => {
    const pc = new RTCPeerConnection();
    const dtmfSender = await createDtmfSender(pc);
    const start = Date.now();

    const allEventsReceived = new Promise(resolve => {
      const onToneChange = t.step_func(ev => {
        assert_true(ev instanceof RTCDTMFToneChangeEvent,
          'Expect tone change event object to be an RTCDTMFToneChangeEvent');

        const { tone } = ev;
        assert_equals(typeof tone, 'string',
          'Expect event.tone to be the tone string');

        assert_greater_than(cumulativeToneChanges.length, 0,
          'More tonechange event is fired than expected');

        const [
          expectedTone, expectedToneBuffer, expectedTime
        ] = cumulativeToneChanges.shift();

        assert_equals(tone, expectedTone,
          `Expect current event.tone to be ${expectedTone}`);

        assert_equals(dtmfSender.toneBuffer, expectedToneBuffer,
          `Expect dtmfSender.toneBuffer to be updated to ${expectedToneBuffer}`);

        // We check that the cumulative delay is at least the expected one, but
        // system load may cause random delays, so we do not put any
        // realistic upper bound on the timing of the events.
        assert_between_inclusive(Date.now() - start, expectedTime,
                                 expectedTime + 4000,
          `Expect tonechange event for "${tone}" to be fired approximately after ${expectedTime} milliseconds`);
        if (cumulativeToneChanges.length === 0) {
          resolve();
        }
      });

      dtmfSender.addEventListener('tonechange', onToneChange);
    });

    testFunc(t, dtmfSender, pc);
    await allEventsReceived;
    const wait = ms => new Promise(resolve => t.step_timeout(resolve, ms));
    await wait(lastWait);
  }, desc);
}

// Get the one and only tranceiver from pc.getTransceivers().
// Assumes that there is only one tranceiver in pc.
function getTransceiver(pc) {
  const transceivers = pc.getTransceivers();
  assert_equals(transceivers.length, 1,
    'Expect there to be only one tranceiver in pc');

  return transceivers[0];
}
