<!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 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.
    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 = event.streams[0];
    }
  });

  // 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() {
    navigator.mediaDevices.getUserMedia({ video: true, audio: true })
      .then(test.step_func(getUserMediaOkCallback), failed('getUserMedia'));
  });
</script>

</body>
</html>
