// Copyright © 2018 Chromium authors and World Wide Web Consortium, (Massachusetts Institute of Technology, ERCIM, Keio University, Beihang).

function findSupportedChangeTypeTestTypes(cb) {
  // Changetype test media metadata.
  // type: fully specified mime type (and codecs substring if the bytestream
  //   format does not forbid codecs parameter). This is required for use with
  //   isTypeSupported, and if supported, should work with both addSourceBuffer
  //   and changeType (unless implementation has restrictions).
  //
  // relaxed_type: possibly ambiguous mime type/subtype without any codecs
  //   substring. This is the same as type minus any codecs substring.
  //
  // mime_subtype: the subtype of the mime type in type and relaxed_type. Across
  //   types registered in the bytestream format registry
  //   (https://www.w3.org/TR/mse-byte-stream-format-registry/), this is
  //   currently sufficient to describe uniquely which test media share the same
  //   bytestream format for use in implicit changeType testing.
  //
  // is_video: All test media currently is single track. This describes whether
  //   or not the track is video.
  //
  // url: Relative location of the test media file.
  //
  // The next two items enable more reliable test media splicing test logic that
  // prevents buffered range gaps at the splice points.
  // start_time: Some test media begins at a time later than 0.0 seconds. This
  //   is the start time of the media.
  // keyframe_interval: Some test media contains out-of-order PTS versus DTS
  //   coded frames. In those cases, a constant keyframe_interval is needed to
  //   prevent severely truncating out-of-order GOPs at splice points.
  let CHANGE_TYPE_MEDIA_LIST = [
    {
      type: 'video/webm; codecs="vp8"',
      relaxed_type: 'video/webm',
      mime_subtype: 'webm',
      is_video: true,
      url: 'webm/test-v-128k-320x240-24fps-8kfr.webm',
      start_time: 0.0
      // keyframe_interval: N/A since DTS==PTS so overlap-removal of
      // non-keyframe should not produce a buffered range gap.
    },
    {
      type: 'video/webm; codecs="vp9"',
      relaxed_type: 'video/webm',
      mime_subtype: 'webm',
      is_video: true,
      url: 'webm/test-vp9.webm',
      start_time: 0.0
      // keyframe_interval: N/A since DTS==PTS so overlap-removal of
      // non-keyframe should not produce a buffered range gap.
    },
    {
      type: 'video/mp4; codecs="avc1.4D4001"',
      relaxed_type: 'video/mp4',
      mime_subtype: 'mp4',
      is_video: true,
      url: 'mp4/test-v-128k-320x240-24fps-8kfr.mp4',
      start_time: 0.083333,
      keyframe_interval: 0.333333
    },
    {
      type: 'audio/webm; codecs="vorbis"',
      relaxed_type: 'audio/webm',
      mime_subtype: 'webm',
      is_video: false,
      url: 'webm/test-a-128k-44100Hz-1ch.webm',
      start_time: 0.0
      // keyframe_interval: N/A since DTS==PTS so overlap-removal of
      // non-keyframe should not produce a buffered range gap. Also, all frames
      // in this media are key-frames (it is audio).
    },
    {
      type: 'audio/mp4; codecs="mp4a.40.2"',
      relaxed_type: 'audio/mp4',
      mime_subtype: 'mp4',
      is_video: false,
      url: 'mp4/test-a-128k-44100Hz-1ch.mp4',
      start_time: 0.0
      // keyframe_interval: N/A since DTS==PTS so overlap-removal of
      // non-keyframe should not produce a buffered range gap. Also, all frames
      // in this media are key-frames (it is audio).
    },
    {
      type: 'audio/mpeg',
      relaxed_type: 'audio/mpeg',
      mime_subtype: 'mpeg',
      is_video: false,
      url: 'mp3/sound_5.mp3',
      start_time: 0.0
      // keyframe_interval: N/A since DTS==PTS so overlap-removal of
      // non-keyframe should not produce a buffered range gap. Also, all frames
      // in this media are key-frames (it is audio).
    }
  ];

  let audio_result = [];
  let video_result = [];

  for (let i = 0; i < CHANGE_TYPE_MEDIA_LIST.length; ++i) {
    let media = CHANGE_TYPE_MEDIA_LIST[i];
    if (window.MediaSource && MediaSource.isTypeSupported(media.type)) {
      if (media.is_video === true) {
        video_result.push(media);
      } else {
        audio_result.push(media);
      }
    }
  }

  cb(audio_result, video_result);
}

function appendBuffer(test, sourceBuffer, data) {
  test.expectEvent(sourceBuffer, "update");
  test.expectEvent(sourceBuffer, "updateend");
  sourceBuffer.appendBuffer(data);
}

function trimBuffered(test, mediaElement, sourceBuffer, minimumPreviousDuration, newDuration, skip_duration_prechecks) {
  if (!skip_duration_prechecks) {
    assert_less_than(newDuration, minimumPreviousDuration);
    assert_less_than(minimumPreviousDuration, mediaElement.duration);
  }
  test.expectEvent(sourceBuffer, "update");
  test.expectEvent(sourceBuffer, "updateend");
  sourceBuffer.remove(newDuration, Infinity);
}

function trimDuration(test, mediaElement, mediaSource, newDuration, skip_duration_prechecks) {
  if (!skip_duration_prechecks) {
    assert_less_than(newDuration, mediaElement.duration);
  }
  test.expectEvent(mediaElement, "durationchange");
  mediaSource.duration = newDuration;
}

function runChangeTypeTest(test, mediaElement, mediaSource, metadataA, typeA, dataA, metadataB, typeB, dataB,
                           implicit_changetype, negative_test) {
  // Some streams, like the MP4 video stream, contain presentation times for
  // frames out of order versus their decode times. If we overlap-append the
  // latter part of such a stream's GOP presentation interval, a significant
  // portion of decode-dependent non-keyframes with earlier presentation
  // intervals could be removed and a presentation time buffered range gap could
  // be introduced. Therefore, we test overlap appends with the overlaps
  // occurring very near to a keyframe's presentation time to reduce the
  // possibility of such a gap. None of the test media is SAP-Type-2, so we
  // don't take any extra care to avoid gaps that may occur when
  // splice-overlapping such GOP sequences that aren't SAP-Type-1.
  // TODO(wolenetz): https://github.com/w3c/media-source/issues/160 could
  // greatly simplify this problem by allowing us play through these small gaps.
  //
  // typeA and typeB may be underspecified for use with isTypeSupported, but
  // this helper does not use isTypeSupported. typeA and typeB must work (even
  // if missing codec specific substrings) with addSourceBuffer (just typeA) and
  // changeType (both typeA and typeB).
  //
  // See also mediaSourceChangeTypeTest's options argument for the meanings of
  // implicit_changetype and negative_test.

  function findSafeOffset(targetTime, overlappedMediaMetadata, overlappedStartTime, overlappingMediaMetadata) {
    assert_greater_than_equal(targetTime, overlappedStartTime);

    let offset = targetTime;
    if ("start_time" in overlappingMediaMetadata) {
      offset -= overlappingMediaMetadata["start_time"];
    }

    // If the media being overlapped is not out-of-order decode, then we can
    // safely use the supplied times.
    if (!("keyframe_interval" in overlappedMediaMetadata)) {
      return { "offset": offset, "adjustedTime": targetTime };
    }

    // Otherwise, we're overlapping media that needs care to prevent introducing
    // a gap. Adjust offset and adjustedTime to make the overlapping media start
    // at the next overlapped media keyframe at or after targetTime.
    let gopsToRetain = Math.ceil((targetTime - overlappedStartTime) / overlappedMediaMetadata["keyframe_interval"]);
    let adjustedTime = overlappedStartTime + gopsToRetain * overlappedMediaMetadata["keyframe_interval"];

    assert_greater_than_equal(adjustedTime, targetTime);
    offset += adjustedTime - targetTime;
    return { "offset": offset, "adjustedTime": adjustedTime };
  }

  // Note, none of the current negative changeType tests should fail the initial addSourceBuffer.
  let sourceBuffer = mediaSource.addSourceBuffer(typeA);

  // Add error event listeners to sourceBuffer. The caller of this helper may
  // also have installed error event listeners on mediaElement.
  if (negative_test) {
    sourceBuffer.addEventListener("error", test.step_func_done());
  } else {
    sourceBuffer.addEventListener("error", test.unreached_func("Unexpected event 'error'"));
  }

  // In either negative test or not, the first appendBuffer should succeed.
  appendBuffer(test, sourceBuffer, dataA);
  let lastStart = metadataA["start_time"];
  if (lastStart == null) {
    lastStart = 0.0;
  }

  // changeType A->B and append the first media of B effectively at 0.5 seconds
  // (or at the first keyframe in A at or after 0.5 seconds if it has
  // keyframe_interval defined).
  test.waitForExpectedEvents(() => {
    let safeOffset = findSafeOffset(0.5, metadataA, lastStart, metadataB);
    lastStart = safeOffset["adjustedTime"];
    if (!implicit_changetype) {
      try { sourceBuffer.changeType(typeB); } catch(err) {
        if (negative_test)
          test.done();
        else
          throw err;
      }
    }
    sourceBuffer.timestampOffset = safeOffset["offset"];
    appendBuffer(test, sourceBuffer, dataB);
  });

  // changeType B->B and append B starting at 1.0 seconds (or at the first
  // keyframe in B at or after 1.0 seconds if it has keyframe_interval defined).
  test.waitForExpectedEvents(() => {
    assert_less_than(lastStart, 1.0);
    let safeOffset = findSafeOffset(1.0, metadataB, lastStart, metadataB);
    lastStart = safeOffset["adjustedTime"];
    if (!implicit_changetype) {
      try { sourceBuffer.changeType(typeB); } catch(err) {
        if (negative_test)
          test.done();
        else
          throw err;
      }
    }
    sourceBuffer.timestampOffset = safeOffset["offset"];
    appendBuffer(test, sourceBuffer, dataB);
  });

  // changeType B->A and append A starting at 1.5 seconds (or at the first
  // keyframe in B at or after 1.5 seconds if it has keyframe_interval defined).
  test.waitForExpectedEvents(() => {
    assert_less_than(lastStart, 1.5);
    let safeOffset = findSafeOffset(1.5, metadataB, lastStart, metadataA);
    // Retain the previous lastStart because the next block will append data
    // which begins between that start time and this block's start time.
    if (!implicit_changetype) {
      try { sourceBuffer.changeType(typeA); } catch(err) {
        if (negative_test)
          test.done();
        else
          throw err;
      }
    }
    sourceBuffer.timestampOffset = safeOffset["offset"];
    appendBuffer(test, sourceBuffer, dataA);
  });

  // changeType A->A and append A starting at 1.3 seconds (or at the first
  // keyframe in B at or after 1.3 seconds if it has keyframe_interval defined).
  test.waitForExpectedEvents(() => {
    assert_less_than(lastStart, 1.3);
    // Our next append will begin by overlapping some of metadataB, then some of
    // metadataA.
    let safeOffset = findSafeOffset(1.3, metadataB, lastStart, metadataA);
    if (!implicit_changetype) {
      try { sourceBuffer.changeType(typeA); } catch(err) {
        if (negative_test)
          test.done();
        else
          throw err;
      }
    }
    sourceBuffer.timestampOffset = safeOffset["offset"];
    appendBuffer(test, sourceBuffer, dataA);
  });

  // Trim duration to 2 seconds, then play through to end.
  test.waitForExpectedEvents(() => {
    // If negative testing, then skip fragile assertions.
    trimBuffered(test, mediaElement, sourceBuffer, 2.1, 2, negative_test);
  });

  test.waitForExpectedEvents(() => {
    // If negative testing, then skip fragile assertions.
    trimDuration(test, mediaElement, mediaSource, 2, negative_test);
  });

  test.waitForExpectedEvents(() => {
    assert_equals(mediaElement.currentTime, 0);
    test.expectEvent(mediaSource, "sourceended");
    test.expectEvent(mediaElement, "play");
    test.expectEvent(mediaElement, "ended");
    mediaSource.endOfStream();
    mediaElement.play();
  });

  test.waitForExpectedEvents(() => {
    if (negative_test)
      assert_unreached("Received 'ended' while negative testing.");
    else
      test.done();
  });
}

// options.use_relaxed_mime_types : boolean (defaults to false).
//   If true, the initial addSourceBuffer and any changeType calls will use the
//   relaxed_type in metadataA and metadataB instead of the full type in the
//   metadata.
// options.implicit_changetype : boolean (defaults to false).
//   If true, no changeType calls will be used. Instead, the test media files
//   are expected to begin with an initialization segment and end at a segment
//   boundary (no abort() call is issued by this test to reset the
//   SourceBuffer's parser).
// options.negative_test : boolean (defaults to false).
//   If true, the test is expected to hit error amongst one of the following
//   areas: addSourceBuffer, appendBuffer (synchronous or asynchronous error),
//   changeType, playback to end of buffered media. If 'ended' is received
//   without error otherwise already occurring, then fail the test. Otherwise,
//   pass the test on receipt of error. Continue to consider timeouts as test
//   failures.
function mediaSourceChangeTypeTest(metadataA, metadataB, description, options = {}) {
  mediasource_test((test, mediaElement, mediaSource) => {
    let typeA = metadataA.type;
    let typeB = metadataB.type;
    if (options.hasOwnProperty("use_relaxed_mime_types") &&
        options.use_relaxed_mime_types === true) {
      typeA = metadataA.relaxed_type;
      typeB = metadataB.relaxed_type;
    }
    let implicit_changetype = options.hasOwnProperty("implicit_changetype") &&
        options.implicit_changetype === true;
    let negative_test = options.hasOwnProperty("negative_test") &&
        options.negative_test === true;

    mediaElement.pause();
    if (negative_test) {
      mediaElement.addEventListener("error", test.step_func_done());
    } else {
      mediaElement.addEventListener("error",
          test.unreached_func("Unexpected event 'error'"));
    }
    MediaSourceUtil.loadBinaryData(test, metadataA.url, (dataA) => {
      MediaSourceUtil.loadBinaryData(test, metadataB.url, (dataB) => {
        runChangeTypeTest(
            test, mediaElement, mediaSource,
            metadataA, typeA, dataA, metadataB, typeB, dataB,
            implicit_changetype, negative_test);
      });
    });
  }, description);
}
