/*
 * Copyright (C) 2013 Google Inc. All Rights Reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are
 * met:
 *
 *     * Redistributions of source code must retain the above copyright
 * notice, this list of conditions and the following disclaimer.
 *     * Redistributions in binary form must reproduce the above
 * copyright notice, this list of conditions and the following disclaimer
 * in the documentation and/or other materials provided with the
 * distribution.
 *     * Neither the name of Google Inc. nor the names of its
 * contributors may be used to endorse or promote products derived from
 * this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

// Modifications Copyright 2017 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.

#include "cobalt/dom/source_buffer.h"

#include <algorithm>
#include <limits>
#include <memory>
#include <vector>

#include "base/compiler_specific.h"
#include "base/logging.h"
#include "base/time/time.h"
#include "cobalt/base/tokens.h"
#include "cobalt/dom/dom_exception.h"
#include "cobalt/dom/media_source.h"
#include "cobalt/media/base/ranges.h"
#include "cobalt/media/base/timestamp_constants.h"

namespace cobalt {
namespace dom {

namespace {

static base::TimeDelta DoubleToTimeDelta(double time) {
  DCHECK(!std::isnan(time));
  DCHECK_NE(time, -std::numeric_limits<double>::infinity());

  if (time == std::numeric_limits<double>::infinity()) {
    return media::kInfiniteDuration;
  }

  // Don't use base::TimeDelta::Max() here, as we want the largest finite time
  // delta.
  base::TimeDelta max_time = base::TimeDelta::FromInternalValue(
      std::numeric_limits<int64_t>::max() - 1);
  double max_time_in_seconds = max_time.InSecondsF();

  if (time >= max_time_in_seconds) {
    return max_time;
  }

  return base::TimeDelta::FromSecondsD(time);
}

}  // namespace

SourceBuffer::SourceBuffer(const std::string& id, MediaSource* media_source,
                           media::ChunkDemuxer* chunk_demuxer,
                           EventQueue* event_queue)
    : id_(id),
      chunk_demuxer_(chunk_demuxer),
      media_source_(media_source),
      track_defaults_(new TrackDefaultList(NULL)),
      event_queue_(event_queue),
      mode_(kSourceBufferAppendModeSegments),
      updating_(false),
      timestamp_offset_(0),
      audio_tracks_(new AudioTrackList(media_source->GetMediaElement())),
      video_tracks_(new VideoTrackList(media_source->GetMediaElement())),
      append_window_start_(0),
      append_window_end_(std::numeric_limits<double>::infinity()),
      first_initialization_segment_received_(false),
      pending_append_data_offset_(0),
      pending_remove_start_(-1),
      pending_remove_end_(-1) {
  DCHECK(!id_.empty());
  DCHECK(media_source_);
  DCHECK(chunk_demuxer);
  DCHECK(event_queue);

  chunk_demuxer_->SetTracksWatcher(
      id_,
      base::Bind(&SourceBuffer::InitSegmentReceived, base::Unretained(this)));
}

void SourceBuffer::set_mode(SourceBufferAppendMode mode,
                            script::ExceptionState* exception_state) {
  if (media_source_ == NULL) {
    DOMException::Raise(DOMException::kInvalidStateErr, exception_state);
    return;
  }
  if (updating_) {
    DOMException::Raise(DOMException::kInvalidStateErr, exception_state);
    return;
  }

  media_source_->OpenIfInEndedState();

  if (chunk_demuxer_->IsParsingMediaSegment(id_)) {
    DOMException::Raise(DOMException::kInvalidStateErr, exception_state);
    return;
  }

  chunk_demuxer_->SetSequenceMode(id_, mode == kSourceBufferAppendModeSequence);

  mode_ = mode;
}

scoped_refptr<TimeRanges> SourceBuffer::buffered(
    script::ExceptionState* exception_state) const {
  if (media_source_ == NULL) {
    DOMException::Raise(DOMException::kInvalidStateErr, exception_state);
    return NULL;
  }

  scoped_refptr<TimeRanges> time_ranges = new TimeRanges;
  media::Ranges<base::TimeDelta> ranges =
      chunk_demuxer_->GetBufferedRanges(id_);
  for (size_t i = 0; i < ranges.size(); i++) {
    time_ranges->Add(ranges.start(i).InSecondsF(), ranges.end(i).InSecondsF());
  }
  return time_ranges;
}

void SourceBuffer::set_timestamp_offset(
    double offset, script::ExceptionState* exception_state) {
  if (media_source_ == NULL) {
    DOMException::Raise(DOMException::kInvalidStateErr, exception_state);
    return;
  }
  if (updating_) {
    DOMException::Raise(DOMException::kInvalidStateErr, exception_state);
    return;
  }

  media_source_->OpenIfInEndedState();

  if (chunk_demuxer_->IsParsingMediaSegment(id_)) {
    DOMException::Raise(DOMException::kInvalidStateErr, exception_state);
    return;
  }

  timestamp_offset_ = offset;

  chunk_demuxer_->SetGroupStartTimestampIfInSequenceMode(
      id_, DoubleToTimeDelta(timestamp_offset_));
}

void SourceBuffer::set_append_window_start(
    double start, script::ExceptionState* exception_state) {
  if (media_source_ == NULL) {
    DOMException::Raise(DOMException::kInvalidStateErr, exception_state);
    return;
  }
  if (updating_) {
    DOMException::Raise(DOMException::kInvalidStateErr, exception_state);
    return;
  }

  if (start < 0 || start >= append_window_end_) {
    exception_state->SetSimpleException(script::kSimpleTypeError);
    return;
  }

  append_window_start_ = start;
}

void SourceBuffer::set_append_window_end(
    double end, script::ExceptionState* exception_state) {
  if (media_source_ == NULL) {
    DOMException::Raise(DOMException::kInvalidStateErr, exception_state);
    return;
  }
  if (updating_) {
    DOMException::Raise(DOMException::kInvalidStateErr, exception_state);
    return;
  }

  if (std::isnan(end)) {
    exception_state->SetSimpleException(script::kSimpleTypeError);
    return;
  }
  // 4. If the new value is less than or equal to appendWindowStart then throw a
  //    TypeError exception and abort these steps.
  if (end <= append_window_start_) {
    exception_state->SetSimpleException(script::kSimpleTypeError);
    return;
  }

  append_window_end_ = end;
}

void SourceBuffer::AppendBuffer(const script::Handle<script::ArrayBuffer>& data,
                                script::ExceptionState* exception_state) {
  AppendBufferInternal(static_cast<const unsigned char*>(data->Data()),
                       data->ByteLength(), exception_state);
}

void SourceBuffer::AppendBuffer(
    const script::Handle<script::ArrayBufferView>& data,
    script::ExceptionState* exception_state) {
  AppendBufferInternal(static_cast<const unsigned char*>(data->RawData()),
                       data->ByteLength(), exception_state);
}

void SourceBuffer::Abort(script::ExceptionState* exception_state) {
  if (media_source_ == NULL) {
    DOMException::Raise(DOMException::kInvalidStateErr, exception_state);
    return;
  }
  if (!media_source_->IsOpen()) {
    DOMException::Raise(DOMException::kInvalidStateErr, exception_state);
    return;
  }

  if (pending_remove_start_ != -1) {
    DCHECK(updating_);
    DOMException::Raise(DOMException::kInvalidStateErr, exception_state);
    return;
  }

  AbortIfUpdating();

  base::TimeDelta timestamp_offset = DoubleToTimeDelta(timestamp_offset_);
  chunk_demuxer_->ResetParserState(id_, DoubleToTimeDelta(append_window_start_),
                                   DoubleToTimeDelta(append_window_end_),
                                   &timestamp_offset);
  timestamp_offset_ = timestamp_offset.InSecondsF();

  set_append_window_start(0, exception_state);
  set_append_window_end(std::numeric_limits<double>::infinity(),
                        exception_state);
}

void SourceBuffer::Remove(double start, double end,
                          script::ExceptionState* exception_state) {
  if (media_source_ == NULL) {
    DOMException::Raise(DOMException::kInvalidStateErr, exception_state);
    return;
  }
  if (updating_) {
    DOMException::Raise(DOMException::kInvalidStateErr, exception_state);
    return;
  }

  if (start < 0 || std::isnan(media_source_->duration(NULL)) ||
      start > media_source_->duration(NULL)) {
    exception_state->SetSimpleException(script::kSimpleTypeError);
    return;
  }

  if (end <= start || std::isnan(end)) {
    exception_state->SetSimpleException(script::kSimpleTypeError);
    return;
  }

  media_source_->OpenIfInEndedState();

  updating_ = true;

  ScheduleEvent(base::Tokens::updatestart());

  pending_remove_start_ = start;
  pending_remove_end_ = end;
  remove_timer_.Start(FROM_HERE, base::TimeDelta(), this,
                      &SourceBuffer::OnRemoveTimer);
}

void SourceBuffer::set_track_defaults(
    const scoped_refptr<TrackDefaultList>& track_defaults,
    script::ExceptionState* exception_state) {
  if (media_source_ == NULL) {
    DOMException::Raise(DOMException::kInvalidStateErr, exception_state);
    return;
  }
  if (updating_) {
    DOMException::Raise(DOMException::kInvalidStateErr, exception_state);
    return;
  }

  track_defaults_ = track_defaults;
}

void SourceBuffer::OnRemovedFromMediaSource() {
  if (media_source_ == NULL) {
    return;
  }

  if (pending_remove_start_ != -1) {
    CancelRemove();
  } else {
    AbortIfUpdating();
  }

  DCHECK(media_source_);

  // TODO: Implement track support.
  // if (media_source_->GetMediaElement()->audio_tracks().length() > 0 ||
  //     media_source_->GetMediaElement()->audio_tracks().length() > 0) {
  //   RemoveMediaTracks();
  // }

  chunk_demuxer_->RemoveId(id_);
  chunk_demuxer_ = NULL;
  media_source_ = NULL;
  event_queue_ = NULL;
}

double SourceBuffer::GetHighestPresentationTimestamp() const {
  DCHECK(media_source_ != NULL);

  return chunk_demuxer_->GetHighestPresentationTimestamp(id_).InSecondsF();
}

void SourceBuffer::TraceMembers(script::Tracer* tracer) {
  EventTarget::TraceMembers(tracer);

  tracer->Trace(event_queue_);
  tracer->Trace(media_source_);
  tracer->Trace(track_defaults_);
  tracer->Trace(audio_tracks_);
  tracer->Trace(video_tracks_);
}

void SourceBuffer::InitSegmentReceived(std::unique_ptr<MediaTracks> tracks) {
  SB_UNREFERENCED_PARAMETER(tracks);

  if (!first_initialization_segment_received_) {
    media_source_->SetSourceBufferActive(this, true);
    first_initialization_segment_received_ = true;
  }

  // TODO: Implement track support.
}

void SourceBuffer::ScheduleEvent(base::Token event_name) {
  scoped_refptr<Event> event = new Event(event_name);
  event->set_target(this);
  event_queue_->Enqueue(event);
}

bool SourceBuffer::PrepareAppend(size_t new_data_size,
                                 script::ExceptionState* exception_state) {
  if (media_source_ == NULL) {
    DOMException::Raise(DOMException::kInvalidStateErr, exception_state);
    return false;
  }
  if (updating_) {
    DOMException::Raise(DOMException::kInvalidStateErr, exception_state);
    return false;
  }

  DCHECK(media_source_->GetMediaElement());
  if (media_source_->GetMediaElement()->error()) {
    DOMException::Raise(DOMException::kInvalidStateErr, exception_state);
    return false;
  }

  media_source_->OpenIfInEndedState();

  if (!EvictCodedFrames(new_data_size)) {
    DOMException::Raise(DOMException::kQuotaExceededErr, exception_state);
    return false;
  }

  return true;
}

bool SourceBuffer::EvictCodedFrames(size_t new_data_size) {
  DCHECK(media_source_);
  DCHECK(media_source_->GetMediaElement());
  double current_time = media_source_->GetMediaElement()->current_time(NULL);
  return chunk_demuxer_->EvictCodedFrames(
      id_, base::TimeDelta::FromSecondsD(current_time), new_data_size);
}

void SourceBuffer::AppendBufferInternal(
    const unsigned char* data, size_t size,
    script::ExceptionState* exception_state) {
  if (!PrepareAppend(size, exception_state)) {
    return;
  }

  DCHECK(data || size == 0);
  if (data) {
    pending_append_data_.insert(pending_append_data_.end(), data, data + size);
  }
  pending_append_data_offset_ = 0;

  updating_ = true;

  ScheduleEvent(base::Tokens::updatestart());

  append_timer_.Start(FROM_HERE, base::TimeDelta(), this,
                      &SourceBuffer::OnAppendTimer);
}

void SourceBuffer::OnAppendTimer() {
  const size_t kMaxAppendSize = 128 * 1024;

  DCHECK(updating_);

  DCHECK_GE(pending_append_data_.size(), pending_append_data_offset_);
  size_t append_size =
      pending_append_data_.size() - pending_append_data_offset_;
  append_size = std::min(append_size, kMaxAppendSize);

  uint8 dummy[1];
  const uint8* data_to_append =
      append_size > 0 ? &pending_append_data_[0] + pending_append_data_offset_
                      : dummy;

  base::TimeDelta timestamp_offset = DoubleToTimeDelta(timestamp_offset_);
  bool success = chunk_demuxer_->AppendData(
      id_, data_to_append, append_size, DoubleToTimeDelta(append_window_start_),
      DoubleToTimeDelta(append_window_end_), &timestamp_offset);

  if (timestamp_offset != DoubleToTimeDelta(timestamp_offset_)) {
    timestamp_offset_ = timestamp_offset.InSecondsF();
  }

  if (!success) {
    pending_append_data_.clear();
    pending_append_data_offset_ = 0;
    AppendError();
  } else {
    pending_append_data_offset_ += append_size;

    if (pending_append_data_offset_ < pending_append_data_.size()) {
      append_timer_.Start(FROM_HERE, base::TimeDelta(), this,
                          &SourceBuffer::OnAppendTimer);
      return;
    }

    updating_ = false;
    pending_append_data_.clear();
    pending_append_data_offset_ = 0;

    ScheduleEvent(base::Tokens::update());
    ScheduleEvent(base::Tokens::updateend());
  }
}

void SourceBuffer::AppendError() {
  base::TimeDelta timestamp_offset = DoubleToTimeDelta(timestamp_offset_);
  chunk_demuxer_->ResetParserState(id_, DoubleToTimeDelta(append_window_start_),
                                   DoubleToTimeDelta(append_window_end_),
                                   &timestamp_offset);
  timestamp_offset_ = timestamp_offset.InSecondsF();

  updating_ = false;

  ScheduleEvent(base::Tokens::error());
  ScheduleEvent(base::Tokens::updateend());
  media_source_->EndOfStreamAlgorithm(kMediaSourceEndOfStreamErrorDecode);
}

void SourceBuffer::OnRemoveTimer() {
  DCHECK(updating_);
  DCHECK_GE(pending_remove_start_, 0);
  DCHECK_LT(pending_remove_start_, pending_remove_end_);

  chunk_demuxer_->Remove(id_, DoubleToTimeDelta(pending_remove_start_),
                         DoubleToTimeDelta(pending_remove_end_));

  updating_ = false;
  pending_remove_start_ = -1;
  pending_remove_end_ = -1;

  ScheduleEvent(base::Tokens::update());
  ScheduleEvent(base::Tokens::updateend());
}

void SourceBuffer::CancelRemove() {
  DCHECK(updating_);
  DCHECK_NE(pending_remove_start_, -1);
  remove_timer_.Stop();
  pending_remove_start_ = -1;
  pending_remove_end_ = -1;
  updating_ = false;
}

void SourceBuffer::AbortIfUpdating() {
  if (!updating_) {
    return;
  }

  DCHECK_EQ(pending_remove_start_, -1);

  append_timer_.Stop();
  pending_append_data_.clear();
  pending_append_data_offset_ = 0;

  updating_ = false;

  ScheduleEvent(base::Tokens::abort());
  ScheduleEvent(base::Tokens::updateend());
}

void SourceBuffer::RemoveMediaTracks() { NOTREACHED(); }

}  // namespace dom
}  // namespace cobalt
