<!doctype html>
<!--
To run this test, you must have a webcam and a microphone or use
fake devices by specifying
  --use-fake-device-for-media-stream --use-fake-ui-for-media-stream
for Chrome or by setting the
  media.navigator.streams.fake
property to true in Firefox.
-->

<html>
<head>
  <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
  <title>RTCPeerConnection Connection Test</title>
</head>
<body>
  <div id="log"></div>
  <div>
    <video id="local-view" autoplay="autoplay"></video>
    <video id="remote-view" 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 src="/common/vendor-prefix.js"
          data-prefixed-objects=
              '[{"ancestors":["navigator"], "name":"getUserMedia"}]'
          data-prefixed-prototypes=
               '[{"ancestors":["HTMLMediaElement"],"name":"srcObject"}]'>
  </script>
  <script type="text/javascript">
  var test = async_test('Can set up a basic WebRTC call.', {timeout: 5000});

  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 getUserMediaOkCallback(localStream) {
    gFirstConnection = new RTCPeerConnection(null);
    gFirstConnection.onicecandidate = onIceCandidateToFirst;
    localStream.getTracks().forEach(function(track) {
      gFirstConnection.addTrack(track, localStream);
    });
    gFirstConnection.createOffer(onOfferCreated, failed('createOffer'));

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

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

    // This would normally go across the application's signaling solution.
    // In our case, the "signaling" is to call this function.
    receiveCall(offer.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(onAnswerCreated,
                                   failed('createAnswer'));
  };

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

    // Similarly, this would go over the application's signaling solution.
    handleAnswer(answer.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.
    gSecondConnection.addIceCandidate(event.candidate);
  });

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

  var onRemoteTrack = test.step_func(function(event) {
    var videoTag = document.getElementById('remote-view');
    if (!videoTag.srcObject) {
      videoTag.srcObject = event.streams[0];
    }
  });

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

  // This function starts the test.
  test.step(function() {
    navigator.mediaDevices.getUserMedia({ video: true, audio: true })
      .then(getUserMediaOkCallback, failed('getUserMedia'));
  });
</script>

</body>
</html>
