<!DOCTYPE HTML>
<html>
<head>
<script src="../../resources/testharness.js"></script>
<script src="../../resources/testharnessreport.js"></script>
</head>
<body>
<script>

// If a constraint is set with applyConstraints, it should come back in
// getConstraints().
promise_test(() => {
  return navigator.mediaDevices.getUserMedia({video: {width: {exact: 800}}})
      .then(s => {
    var track = s.getVideoTracks()[0];
    var constraints = track.getConstraints();
    assert_equals(Object.keys(constraints).length, 1);
    assert_true(constraints.hasOwnProperty('width'));
    assert_equals(constraints.width.exact, 800);

    return track.applyConstraints({width: {exact: 640}})
        .then(() => {
      constraints = track.getConstraints();
      assert_equals(Object.keys(constraints).length, 1);
      assert_true(constraints.hasOwnProperty('width'));
      assert_equals(constraints.width.exact, 640);
    })
  });
}, 'applyConstraints() sets the value of a constraint set by getUserMedia()');

// The deviceId constraint must be rejected, since the source of a track cannot
// be changed with applyConstraints.
promise_test(test => {
  return promise_rejects(test,
                         new OverconstrainedError('deviceId', ''),
                         navigator.mediaDevices.getUserMedia({audio: true})
      .then(s => {
    return s.getAudioTracks()[0].applyConstraints(
        { deviceId: {exact: 'mydevice-id'}});
  }));
}, 'Attempting to change the deviceId with applyConstraints() fails');

promise_test(() => {
  let track;
  return navigator.mediaDevices.getUserMedia({video: true})
      .then(s => {
    track = s.getVideoTracks()[0];
    return track.getSettings();
  }).then(settings => {
    return track.applyConstraints(
        { width: { exact: settings.width }, notKnownName: { exact: true }})
  }).then(() => {
    constraints = track.getConstraints();
    assert_equals(Object.keys(constraints).length, 1);
    assert_false(constraints.hasOwnProperty('notKnownName'));
  });
}, 'An unsupported constraint is ignored by applyConstraints()');

function constraintElementsEqual(a, b) {
  if (a === b)
    return true;
  if (!(a instanceof Object))
    return false;
  if (!(b instanceof Object))
    return false;
  if (Object.keys(a).length != Object.keys(b).length)
    return false;
  for (var p in a) {
    if (!a.hasOwnProperty(p))
      continue;  // Skip prototypes and such things.
    if (!b.hasOwnProperty(p))
      return false;
    if (a[p] instanceof Object && b[p] instanceof Object) {
      if (!constraintElementsEqual(a[p], b[p]))
         return false;
      continue;
    }
    if (a[p] !== b[p]) return false;  // Simple types.
  }
  return true;
}

promise_test(() => {
  // Construct a constraint set that covers constraints that make sense for
  // video.
  const complexConstraintSet = {
    width: { min: 30, max: 480 },
    height: { min: 30, max: 480, exact: 350 },
  };
  // These constraints are syntactically valid, but may cause rejection.
  // They are included in an "advanced" constraint.
  // The particular values chosen are picked to exercise multiple parser paths,
  // but the most important is that all legal names are represented.
  const ignorableConstraintSet = {
    frameRate: { ideal: 30.0 },
    facingMode: { ideal: "user" },
    aspectRatio: { ideal: 1.3333333, exact: 1.4444 },

    volume: 1.0,
    sampleRate: { ideal: 42, min: 31, max: 54 },
    sampleSize: 3,
    echoCancellation: { ideal: false, exact: true },
    latency: 0.22,
    channelCount: 2,
    deviceId: { ideal: ["foo", "fooz"] },
    groupId: ["bar", "baz"]
  };
  let complexConstraints = complexConstraintSet;
  complexConstraints.advanced = [ ignorableConstraintSet ];

  return navigator.mediaDevices.getUserMedia({video: true})
      .then(s => {
    var track = s.getVideoTracks()[0];
    return track.applyConstraints(complexConstraints).then(() => {
      constraints = track.getConstraints();
      assert_true(constraintElementsEqual(constraints, complexConstraints),
        "Unexpected result: In: " +
        JSON.stringify(complexConstraints, null, 2) +
        " Out: " + JSON.stringify(constraints, null, 2));
    });
  });
}, 'All valid keys are returned for complex constraints');

// Syntax tests for constraints.
// These work by putting the constraints into an advanced constraint
// (so that they can be ignored), calling getUserMedia, and then
// inspecting the constraints.
// In advanced constraints, naked values mean "exact", and "exact" values
// are thus unwrapped, which is the opposite behavior from the "basic"
// constraint set (outside advanced).
function constraintSyntaxTestWithChange(name, constraints, expected_result) {
  promise_test(() => {
    return navigator.mediaDevices.getUserMedia(
        {'video': true})
        .then(s => {
      var track = s.getVideoTracks()[0];
      track.applyConstraints({ 'advanced': [ constraints ]}).then(() => {
      var constraints_out = track.getConstraints().advanced[0];
      assert_true(constraintElementsEqual(expected_result, constraints_out),
          "Unexpected result: Expected: " +
          JSON.stringify(expected_result, null, 2) +
          " Out: " + JSON.stringify(constraints_out, null, 2));
      })
    })
  }, name);
}

function constraintSyntaxTest(name, constraints) {
  constraintSyntaxTestWithChange(name, constraints, constraints);
}

constraintSyntaxTest('Simple integer', { height: 42 });
constraintSyntaxTest('Ideal integer', { height: { ideal: 42 }});
constraintSyntaxTest('Min/max integer', { height: { min: 42, max: 43 }});
constraintSyntaxTestWithChange('Exact unwrapped integer',
                               { height: { exact: 42 } }, { height: 42 });

constraintSyntaxTest('Simple double', { aspectRatio: 1.5 });
constraintSyntaxTest('Ideal double', { aspectRatio: { ideal: 1.5 }});
constraintSyntaxTest('Min/max double', { aspectRatio: { min: 1.5, max: 2.0 }});
constraintSyntaxTestWithChange(
    'Exact unwrapped double',
    { aspectRatio: { exact: 1.5 } }, { aspectRatio: 1.5 });

constraintSyntaxTest('Simple String', { facingMode: "user1" });
constraintSyntaxTest('Ideal String', { facingMode: { ideal: "user2" }});
constraintSyntaxTest('Multiple String in Brackets',
                     { facingMode: { ideal: ["user3", "left3"]}});
constraintSyntaxTest('Multiple Bracketed Naked String',
                     { facingMode: ["user4", "left4"] });
constraintSyntaxTestWithChange(
    'Single Bracketed string unwrapped',
    { 'facingMode': ["user5"]}, { facingMode: "user5" });
constraintSyntaxTest('Both Ideal and Exact string',
                     { facingMode: { ideal: "user6", exact: "left6" }});

constraintSyntaxTest('Simple boolean', { echoCancellation: true });
constraintSyntaxTest('Ideal boolean', { echoCancellation: { ideal: true }});
constraintSyntaxTestWithChange('Exact unwrapped boolean',
    { echoCancellation: { exact: true } }, { echoCancellation: true });

</script>
</body>
</html>
