<!doctype html>
<title>canPlayType</title>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<audio id="audio"></audio>
<video id="video"></video>
<div id="log"></div>
<script>
let VIDEO_ELEM = document.getElementById('video');
let AUDIO_ELEM = document.getElementById('audio');

function t(type, expected) {
  assert_equals(canPlayType(type), expected, type);
}

function mime(type, codecs) {
  if (codecs.length) {
    return type + '; codecs="' + codecs.join(', ') + '"';
  }
  return type;
}

test(function() {
  assert_equals(mime('video/webm', []), 'video/webm');
  assert_equals(mime('video/webm', ['vp8']), 'video/webm; codecs="vp8"');
  assert_equals(mime('video/webm', ['vp8', 'vorbis']), 'video/webm; codecs="vp8, vorbis"');
}, 'utility code');

function canPlayType(type) {
  let audioCanPlay = AUDIO_ELEM.canPlayType(type);
  let videoCanPlay = VIDEO_ELEM.canPlayType(type);
  assert_equals(audioCanPlay, videoCanPlay,
                'audio.canPlayType() and video.canPlayType() agree');
  assert_in_array(audioCanPlay, ['', 'maybe', 'probably'],
                  'return value is one of "", "maybe" and "probably"');
  return audioCanPlay;
}

test(function() {
  t('application/octet-stream', '');
  t('application/octet-stream; codecs="vorbis"', '');
  t('application/octet-stream; codecs="vp8, vorbis"', '');
  t('application/octet-stream; codecs="mp4a.40.2"', '');
  t('application/octet-stream; codecs="theora, vorbis"', '');
  t('application/octet-stream; codecs="avc1.42E01E, mp4a.40.2"', '');
}, 'application/octet-stream not supported');

test(function() {
  t('application/marks-fantasmagorical-format', '');
  t('video/x-new-fictional-format', '');
  t('video/x-new-fictional-format;codecs="kittens,bunnies"', '');
}, 'fictional formats and codecs not supported');

function type_codecs_test(type, audioCodecs, videoCodecs) {
  var typeSupported = false;
  var codecSupported = false;

  // Test 'type' without codecs.
  // Spec: Generally, a user agent should never return "probably" for a type
  // that allows the codecs parameter if that parameter is not present.
  test(function() {
    t(type, 'maybe');
    t(type + ';', 'maybe');
    t(type + ';codecs', 'maybe');
    t(type + ';codecs=', 'maybe');
    typeSupported = true;
  }, type + ' (optional)');

  function test_codec(codec) {
    var typeWithCodec = mime(type, [codec]);
    test(function() {
      t(typeWithCodec, 'probably');
      codecSupported = true;
    }, typeWithCodec + ' (optional)');
  }

  // Test each audio and video codec separately.
  audioCodecs.forEach(test_codec);
  videoCodecs.forEach(test_codec);

  // Test different pairings and orderings of audio+video codecs.
  if (audioCodecs.length > 0 && videoCodecs.length > 0) {
    test(function() {
      audioCodecs.forEach(function(ac) {
        videoCodecs.forEach(function(vc) {
          var canPlayBoth = canPlayType(mime(type, [ac, vc]));
          if (canPlayBoth) {
            t(mime(type, [ac]), canPlayBoth);
            t(mime(type, [vc]), canPlayBoth);
          }
        });
      });
    }, type + ' codecs subset');

    test(function() {
      audioCodecs.forEach(function(ac) {
        videoCodecs.forEach(function(vc) {
          assert_equals(canPlayType(mime(type, [ac, vc])),
                        canPlayType(mime(type, [vc, ac])));
        });
      });
    }, type + ' codecs order');
  }

  test(function() {
    t(mime(type, ['bogus']), '');
  }, type + ' with bogus codec');

  test(function() {
    // At least one known codec must be supported if the container format is.
    assert_equals(typeSupported, codecSupported);
  }, type + ' with and without codecs');
}

type_codecs_test('audio/mp4', ['mp4a.40.2'], []);
type_codecs_test('audio/ogg', ['opus', 'vorbis'], []);
type_codecs_test('audio/wav', ['1'], []);
type_codecs_test('audio/webm', ['opus', 'vorbis'], []);
type_codecs_test('video/3gpp', ['samr'], ['mp4v.20.8']);
type_codecs_test('video/mp4', ['mp4a.40.2'], ['avc1.42E01E', 'avc1.4D401E', 'avc1.58A01E', 'avc1.64001E', 'mp4v.20.8', 'mp4v.20.240']);
type_codecs_test('video/ogg', ['opus', 'vorbis'], ['theora']);
type_codecs_test('video/webm', ['opus', 'vorbis'], ['vp8', 'vp8.0', 'vp9', 'vp9.0']);
</script>
