<!doctype html>
<html>
<head>
  <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
  <title>RTCPeerConnection Connection Test</title>
  <script src="RTCPeerConnection-helper.js"></script>
</head>
<body>
  <div id="log"></div>
  <div>
    <video id="local-view" muted autoplay="autoplay"></video>
    <video id="remote-view" muted autoplay="autoplay"/>
    </video>
  </div>

  <!-- These files are in place when executing on W3C. -->
  <script src="/resources/testharness.js"></script>
  <script src="/resources/testharnessreport.js"></script>
  <script type="text/javascript">
  var test = async_test('Can set up a basic WebRTC call without announcing ssrcs.');

  var gFirstConnection = null;
  var gSecondConnection = null;

  // if the remote video gets video data that implies the negotiation
  // as well as the ICE and DTLS connection are up.
  document.getElementById('remote-view')
      .addEventListener('loadedmetadata', function() {
    // Call negotiated: done.
    test.done();
  });

  function getNoiseStreamOkCallback(localStream) {
    gFirstConnection = new RTCPeerConnection(null);
    gFirstConnection.onicecandidate = onIceCandidateToFirst;
    localStream.getTracks().forEach(function(track) {
      gFirstConnection.addTrack(track, localStream);
    });
    gFirstConnection.createOffer().then(onOfferCreated, failed('createOffer'));

    var videoTag = document.getElementById('local-view');
    videoTag.srcObject = localStream;
  };

  var onOfferCreated = test.step_func(function(offer) {
    gFirstConnection.setLocalDescription(offer);

    // remove all a=ssrc: lines, the msid-semantic line and any a=msid:.
    var sdp = offer.sdp.replace(/^a=ssrc:.*$\r\n/gm, '')
      .replace(/^a=msid-semantic.*$\r\n/gm, '')
      .replace(/^a=msid:.*$\r\n/gm, '');

    // This would normally go across the application's signaling solution.
    // In our case, the "signaling" is to call this function.
    receiveCall(sdp);
  });

  function receiveCall(offerSdp) {
    gSecondConnection = new RTCPeerConnection(null);
    gSecondConnection.onicecandidate = onIceCandidateToSecond;
    gSecondConnection.ontrack = onRemoteTrack;

    var parsedOffer = new RTCSessionDescription({ type: 'offer',
                                                  sdp: offerSdp });
    gSecondConnection.setRemoteDescription(parsedOffer);

    gSecondConnection.createAnswer().then(onAnswerCreated,
                                   failed('createAnswer'));
  };

  var onAnswerCreated = test.step_func(function(answer) {
    gSecondConnection.setLocalDescription(answer);

    // remove all a=ssrc: lines, the msid-semantic line and any a=msid:.
    var sdp = answer.sdp.replace(/^a=ssrc:.*$\r\n/gm, '')
      .replace(/^a=msid-semantic.*$\r\n/gm, '')
      .replace(/^a=msid:.*$\r\n/gm, '');

    // Similarly, this would go over the application's signaling solution.
    handleAnswer(sdp);
  });

  function handleAnswer(answerSdp) {
    var parsedAnswer = new RTCSessionDescription({ type: 'answer',
                                                   sdp: answerSdp });
    gFirstConnection.setRemoteDescription(parsedAnswer);
  };

  var onIceCandidateToFirst = test.step_func(function(event) {
    // If event.candidate is null = no more candidates.
    if (event.candidate) {
      gSecondConnection.addIceCandidate(event.candidate);
    }
  });

  var onIceCandidateToSecond = test.step_func(function(event) {
    if (event.candidate) {
      gFirstConnection.addIceCandidate(event.candidate);
    }
  });

  var onRemoteTrack = test.step_func(function(event) {
    var videoTag = document.getElementById('remote-view');
    if (!videoTag.srcObject)
      videoTag.srcObject = new MediaStream();
    videoTag.srcObject.addTrack(event.track);
  });

  // Returns a suitable error callback.
  function failed(function_name) {
    return test.unreached_func('WebRTC called error callback for ' + function_name);
  }

  // This function starts the test.
  test.step(function() {
    getNoiseStream({ video: true, audio: true })
      .then(test.step_func(getNoiseStreamOkCallback), failed('getNoiseStream'));
  });
</script>

</body>
</html>
