var MediaSourceTest = {};
var mediaSource = new WebKitMediaSource();

MediaSourceTest.SegmentHelper = function(segmentInfo, fullDuration)
{
    this.MediaSegmentsToLoad = 0;
    this.sourceBuffer = null;

    this.videoTag = null;
    this.segmentInfo = segmentInfo;
    this.initSegment = null;
    this.mediaSegments = [];

    // Limit how many media segments we load based on time.
    var maxDuration = 3;
    for (var i in this.segmentInfo.media) {
        if (!fullDuration && this.segmentInfo.media[i].timecode > maxDuration)
            break;
        this.MediaSegmentsToLoad++;
    }

    // Require 3 or more segments for testing. This guarantees that there are at least 3 random
    // access points in the content.
    if (this.MediaSegmentsToLoad < 3)
        consoleWrite("Need more media segments for testing. " + this.MediaSegmentsToLoad + " is not enough");
};

MediaSourceTest.SegmentHelper.prototype.init = function(videoTag, doneCallback)
{
    if (!videoTag) {
        doneCallback(false);
        return;
    }

    this.videoTag = videoTag;
    var t = this;
    var getDataCallback = function(data) { t.getInitSegmentDone_(doneCallback, data); };
    this.getData_(this.segmentInfo.url,
                  this.segmentInfo.init.offset, this.segmentInfo.init.size,
                  getDataCallback);
};

MediaSourceTest.SegmentHelper.prototype.getInitSegmentDone_ = function(doneCallback, data)
{
    if (!data) {
        doneCallback(false);
        return;
    }

    this.initSegment = data;

    this.downloadMediaSegment_(0, doneCallback);
};

MediaSourceTest.SegmentHelper.prototype.downloadMediaSegment_ = function(index, doneCallback)
{
    var t = this;
    var getDataCallback = function(data) { t.downloadMediaSegmentDone_(index, doneCallback, data); };
    this.getData_(this.segmentInfo.url,
                  this.segmentInfo.media[index].offset,
                  this.segmentInfo.media[index].size,
                  getDataCallback);
};

MediaSourceTest.SegmentHelper.prototype.downloadMediaSegmentDone_ = function(index, doneCallback, data)
{
    if (!data) {
        doneCallback(false);
        return;
    }

    this.mediaSegments.push(data);

    if (this.mediaSegments.length == this.MediaSegmentsToLoad) {
        doneCallback(true);
        return;
    }

    this.downloadMediaSegment_(index + 1, doneCallback);
};


MediaSourceTest.SegmentHelper.prototype.getData_ = function (url, start, length, callback)
{
    var request = new XMLHttpRequest();
    request.open("GET", url, true);

    if (start && start < 0) {
        failTest("Invalid start parameter " + start);
        return;
    }

    if (length && length <= 0) {
        failTest("Invalid length parameter " + length);
        return;
    }

    var expectedStatus = 200;
    if (start >= 0) {
        var startOffset = start;
        var rangeString = 'bytes=' + startOffset + '-';
        if (length && length > 0) {
            var endOffset = startOffset + length - 1;
            rangeString += endOffset;
        }

        expectedStatus = 206;
        request.setRequestHeader('Range', rangeString);
    }

    request.responseType = 'arraybuffer';
    request.onload = function()
    {
        if (request.status != expectedStatus) {
            failTest("Unexpected status code " + request.status + " for " + url);
            callback(null);
            return;
        }

        callback(new Uint8Array(request.response));
    };
    request.send();
};

MediaSourceTest.SegmentHelper.prototype.addSourceBuffer = function()
{
    this.sourceBuffer = mediaSource.addSourceBuffer(this.segmentInfo.type);
};

MediaSourceTest.SegmentHelper.prototype.appendInitSegment = function()
{
    this.sourceBuffer.append(this.initSegment);
};

MediaSourceTest.SegmentHelper.prototype.appendMediaSegment = function(index)
{
    this.sourceBuffer.append(this.mediaSegments[index]);
};

MediaSourceTest.SegmentHelper.prototype.appendAllMediaSegments = function()
{
    for (var i = 0; i < this.mediaSegments.length; i++)
        this.appendMediaSegment(i);
};

MediaSourceTest.SegmentHelper.prototype.appendUntilEndOfStream = function(startIndex)
{
    if (!this.sourceBuffer) {
        failTest("MediaSource API is not available");
        return;
    }

    for (var index = startIndex; index < this.mediaSegments.length; index++)
        this.appendMediaSegment(index);

    mediaSource.endOfStream();
};

MediaSourceTest.SegmentHelper.prototype.getTimeForMediaSegment = function(index)
{
    return this.segmentInfo.media[index].timecode;
};

MediaSourceTest.SegmentHelper.prototype.getMediaSegmentIndexForTimestamp = function(timestamp)
{
    if (timestamp <= this.getTimeForMediaSegment(0))
        return 0;

    for (var index = 1; index < this.mediaSegments.length; index++) {
        if (timestamp < this.getTimeForMediaSegment(index)) {
            return index - 1;
        }
    }

    return this.mediaSegments.length - 1;
};


MediaSourceTest.setSrcToMediaSourceTestURL = function(videoTag)
{
    if (!mediaSource) {
        failTest("MediaSource is not available");
        return;
    }

    videoTag.src = webkitURL.createObjectURL(mediaSource);
};

MediaSourceTest.mediaErrorString = function(videoTag)
{
    var errorString = "UNKNOWN";
    switch(videoTag.error.code) {
        case MediaError.MEDIA_ERR_ABORTED:
            errorString = "MEDIA_ERR_ABORTED";
            break;
        case MediaError.MEDIA_ERR_NETWORK:
            errorString = "MEDIA_ERR_NETWORK";
            break;
        case MediaError.MEDIA_ERR_DECODE:
            errorString = "MEDIA_ERR_DECODE";
            break;
        case MediaError.MEDIA_ERR_SRC_NOT_SUPPORTED:
            errorString = "MEDIA_ERR_SRC_NOT_SUPPORTED";
            break;
    }

    return errorString;
};

MediaSourceTest.defaultOnErrorChecks = function(event)
{
    var videoTag = event.target;

    consoleWrite("EVENT(error) : " + MediaSourceTest.mediaErrorString(videoTag));

    if (mediaSource.readyState != "closed") {
        consoleWrite("Unexpected source state. Expected 'closed'" +
                     " got " + mediaSource.readyState);
    }
};

MediaSourceTest.runNext_ = function(videoTag, testCaseIndex, tests, testWrapperFunction)
{
    if (testCaseIndex >= tests.length) {
        endTest();
        return;
    }

    var onOpenFunction = tests[testCaseIndex];
    var functionName = onOpenFunction.name;
    var runNextFunction = function()
    {
        MediaSourceTest.runNext_(videoTag, testCaseIndex + 1, tests, testWrapperFunction);
    };

    var errorEventHandler = function(event)
    {
        event.target.removeEventListener('error', errorEventHandler);
        MediaSourceTest.defaultOnErrorChecks(event);
        runNextFunction();
    };
    videoTag.addEventListener('error', errorEventHandler);

    consoleWrite("");
    consoleWrite("running " + functionName);

    if (testWrapperFunction) {
        onOpenFunction = testWrapperFunction(onOpenFunction);
    }

    onOpenFunction(runNextFunction, videoTag);
};

MediaSourceTest.startTesting = function(videoTag, tests)
{
    MediaSourceTest.runNext_(videoTag, 0, tests);
};

MediaSourceTest.startSourceOpenTesting = function(videoTag, tests)
{
    // Wrapper function that executes the test function when the
    // source open event has fired.
    var testWrapperFunction = function(testFunction)
    {
        return function(runNextFunction, videoTag)
        {
            MediaSourceTest.runOnSourceOpen(videoTag, function()
            {
                testFunction(runNextFunction, videoTag);
            });
        };
    };
    MediaSourceTest.runNext_(videoTag, 0, tests, testWrapperFunction);
};

MediaSourceTest.runOnSourceOpen = function(videoTag, onOpenFunction)
{
    var eventHandlerFunction = function (event)
    {
        if (videoTag.networkState != HTMLMediaElement.NETWORK_LOADING &&
            videoTag.networkState != HTMLMediaElement.NETWORK_IDLE) {
            failTest("Unexpected network state. Expected " +
                     HTMLMediaElement.NETWORK_LOADING + " or " +
                     HTMLMediaElement.NETWORK_IDLE +
                     " got " + videoTag.readyState);
        }
        event.target.removeEventListener('webkitsourceopen', eventHandlerFunction);
        onOpenFunction();
    };

    mediaSource.addEventListener('webkitsourceopen', eventHandlerFunction);
    MediaSourceTest.setSrcToMediaSourceTestURL(videoTag);
};

MediaSourceTest.logSourceState = function(mediaSource)
{
    consoleWrite("webkitSourceState : " + mediaSource.readyState);
};

MediaSourceTest.expectSourceState = function(mediaSource, expected)
{
    if (mediaSource.readyState != expected) {
        failTest("Unexpected source state. Expected " + expected +
                 " got " + mediaSource.readyState);
    }
};

MediaSourceTest.expectReadyState = function(videoTag, expected)
{
    if (videoTag.readyState != expected) {
        failTest("Unexpected ready state. Expected " +
                 MediaSourceTest.getReadyStateName(expected) +
                 " got " + MediaSourceTest.getReadyStateName(videoTag.readyState));
    }
};

MediaSourceTest.roundedEquals_ = function(expected, actual)
{
    return expected.toFixed(3) == actual.toFixed(3);
};

MediaSourceTest.expectDuration = function(videoTag, mediaSource, expected)
{
    if (!this.roundedEquals_(expected, videoTag.duration))
        failTest("Unexpected duration. Expected " + expected + " got " + videoTag.duration);
    if (!this.roundedEquals_(expected, mediaSource.duration))
        failTest("Unexpected duration. Expected " + expected + " got " + mediaSource.duration);
};

MediaSourceTest.expectBufferedRange = function(sourceBuffer, expected)
{
    if (sourceBuffer.buffered.length != expected.length)
        failTest("Unexpected number of buffered regions. Expected " + expected.length + " got " + sourceBuffer.buffered.length);

    for (var i = 0; i < expected.length; i++) {
        var expectedStart = expected[i][0];
        var expectedEnd = expected[i][1];
        var actualStart = sourceBuffer.buffered.start(i);
        var actualEnd = sourceBuffer.buffered.end(i);
        if (!this.roundedEquals_(expectedStart, actualStart) ||
            !this.roundedEquals_(expectedEnd, actualEnd)) {
            failTest("Unexpected buffered region. Expected (" + expectedStart + ", " + expectedEnd + ") got ("
                     + actualStart + ", " + actualEnd +")");
        }
    }
};

MediaSourceTest.getReadyStateName = function(state)
{
    var stateName = "UNKNOWN";
    switch (state) {
        case HTMLMediaElement.HAVE_NOTHING:
            stateName = "HAVE_NOTHING";
            break;
        case HTMLMediaElement.HAVE_METADATA:
            stateName = "HAVE_METADATA";
            break;
        case HTMLMediaElement.HAVE_CURRENT_DATA:
            stateName = "HAVE_CURRENT_DATA";
            break;
        case HTMLMediaElement.HAVE_FUTURE_DATA:
            stateName = "HAVE_FUTURE_DATA";
            break;
        case HTMLMediaElement.HAVE_ENOUGH_DATA:
            stateName = "HAVE_ENOUGH_DATA";
            break;
    }
    return stateName;
};
