// Copyright 2018 The Cobalt Authors. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

// The demo simply plays a video using get parameters in the form of:
//   .../multi-video-demo.html?audio=filename_in_same_folder&video=filename_in_same_folder&instances=2

var kAudioChunkSize = 512 * 1024;
var kVideoChunkSize = 2 * 1024 * 1024;

var kEndOfStreamOffset = -1;

class Player {
  constructor(audio_url, video_url) {
    this.audio_offset = 0;
    this.audio_url = audio_url;
    this.video_offset = 0;
    this.video_url = video_url;
    this.video_tag = this.createVideoElement();
    this.status = this.createStatusElement(this.video_tag);

    this.video_tag.src = '';
    this.video_tag.load();
    this.mediasource = new MediaSource;
    this.mediasource.addEventListener('sourceopen', this.onsourceopen.bind(this));
    this.video_tag.src = window.URL.createObjectURL(this.mediasource);
  }

  onsourceopen() {
    if (this.video_url.endsWith('.mp4')) {
        this.video_source_buffer = this.mediasource.addSourceBuffer(
                                       'video/mp4; codecs="avc1.640028"');
      } else {
        this.video_source_buffer = this.mediasource.addSourceBuffer(
                                       'video/webm; codecs="vp9"');
      }

      this.audio_source_buffer = this.mediasource.addSourceBuffer(
                                     'audio/mp4; codecs="mp4a.40.2"');
      this.tryToDownloadAudioData();
  }

  downloadAndAppend(url, begin, end, source_buffer, callback) {
    var xhr = new XMLHttpRequest;
    xhr.open('GET', url, true);
    xhr.responseType = 'arraybuffer';
    xhr.addEventListener('load', function(e) {
      var data = new Uint8Array(e.target.response);
      var onupdateend = function() {
        source_buffer.removeEventListener('updateend', onupdateend);
        callback(data.length);
      };
      source_buffer.addEventListener('updateend', onupdateend);
      source_buffer.appendBuffer(data);
      console.log('append ' + data.length + ' bytes from '
                  + url);
    });
    xhr.setRequestHeader('Range', ('bytes=' + begin +'-' + end));
    xhr.send();
  }

  isTrackNeedAudioData() {
    if (this.audio_offset == kEndOfStreamOffset) {
      return false;
    }
    var buffer_range_size = this.audio_source_buffer.buffered.length;
    if (buffer_range_size == 0) {
      return true;
    }
    var start = this.audio_source_buffer.buffered.start(buffer_range_size - 1);
    var end = this.audio_source_buffer.buffered.end(buffer_range_size - 1);
    console.log('audio ' + start + '/' + end + ' ' + this.video_tag.currentTime)
    return end - this.video_tag.currentTime <= 20;
  }

  isTrackNeedVideoData() {
    if (this.video_offset == kEndOfStreamOffset) {
      return false;
    }
    var buffer_range_size = this.video_source_buffer.buffered.length;
    if (buffer_range_size == 0) {
      return true;
    }
    var start = this.video_source_buffer.buffered.start(buffer_range_size - 1);
    var end = this.video_source_buffer.buffered.end(buffer_range_size - 1);
    console.log('video ' + start + '/' + end + ' ' + this.video_tag.currentTime)
    return end - this.video_tag.currentTime <= 20;
  }

  tryToDownloadAudioData() {
    if (!this.isTrackNeedAudioData()) {
      if (this.isTrackNeedVideoData()) {
        this.tryToDownloadVideoData();
      } else {
        window.setTimeout(this.tryToDownloadAudioData.bind(this), 1000);
      }
      return;
    }

    this.downloadAndAppend(
        this.audio_url, this.audio_offset,
        this.audio_offset + kAudioChunkSize - 1, this.audio_source_buffer,
        this.onAudioDataDownloaded.bind(this));
  }

  onAudioDataDownloaded(length) {
    if (length != kAudioChunkSize) {
      this.audio_offset = kEndOfStreamOffset;
    }
    if (this.audio_offset != kEndOfStreamOffset) {
      this.audio_offset += kAudioChunkSize;
    }
    this.tryToDownloadVideoData();
  }

  tryToDownloadVideoData() {
    if (!this.isTrackNeedVideoData()) {
      if (this.isTrackNeedAudioData()) {
        this.tryToDownloadAudioData();
      } else {
        window.setTimeout(this.tryToDownloadVideoData.bind(this), 1000);
      }
      return;
    }

    this.downloadAndAppend(
        this.video_url, this.video_offset,
        this.video_offset + kVideoChunkSize - 1, this.video_source_buffer,
        this.onVideoDataDownloaded.bind(this));
  }

  onVideoDataDownloaded(length) {
    if (length != kVideoChunkSize) {
      this.video_offset = kEndOfStreamOffset;
    }
    if (this.video_offset != kEndOfStreamOffset) {
      this.video_offset += kVideoChunkSize;
    }
    this.tryToDownloadAudioData();
  }

  createVideoElement() {
    var video = document.createElement('video');
    video.autoplay = true;
    video.style.width = '320px';
    video.style.height = '240px';
    document.body.appendChild(video);

    return video;
  }

  createStatusElement(video) {
    var status = document.createElement('div');
    document.body.appendChild(status);
    video.addEventListener('timeupdate', function () {
      status.textContent = 'time: ' + video.currentTime.toFixed(2);
    });

    return status;
  }
}

function main() {
  var get_parameters = window.location.search.substr(1).split('&');
  var audio_url, video_url, instances = 2;
  for (var param of get_parameters) {
    splitted = param.split('=');
    if (splitted[0] == 'audio') {
      audio_url = splitted[1];
    } else if (splitted[0] == 'video') {
      video_url = splitted[1];
    } else if (splitted[0] == 'instances') {
      instances = splitted[1];
    }
  }

  if (audio_url && video_url) {
    for (var i = 0; i < instances; ++i) {
      new Player(audio_url, video_url);
    }
  } else {
    status.textContent = "invalid get parameters " +
                         window.location.search.substr(1);
  }
}

main();
