/*
 * 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 <utility>

#include "base/compiler_specific.h"
#include "base/logging.h"
#include "base/message_loop/message_loop.h"
#include "base/time/time.h"
#include "base/trace_event/trace_event.h"
#include "cobalt/base/polymorphic_downcast.h"
#include "cobalt/base/tokens.h"
#include "cobalt/dom/dom_settings.h"
#include "cobalt/dom/media_source.h"
#include "cobalt/web/dom_exception.h"
#include "third_party/chromium/media/base/ranges.h"
#include "third_party/chromium/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);
}

// The return value will be used in `SourceBuffer::EvictCodedFrames()` to allow
// it to evict extra data from the SourceBuffer, so it can reduce the overall
// memory used by the underlying Demuxer implementation.
// The default value is 0, i.e. do not evict extra bytes.
size_t GetEvictExtraInBytes(script::EnvironmentSettings* settings) {
  DOMSettings* dom_settings =
      base::polymorphic_downcast<DOMSettings*>(settings);
  DCHECK(dom_settings);
  DCHECK(dom_settings->media_source_settings());
  int bytes = dom_settings->media_source_settings()
                  ->GetSourceBufferEvictExtraInBytes()
                  .value_or(0);
  DCHECK_GE(bytes, 0);
  return std::max<int>(bytes, 0);
}

}  // namespace

SourceBuffer::SourceBuffer(script::EnvironmentSettings* settings,
                           const std::string& id, MediaSource* media_source,
                           bool asynchronous_reduction_enabled,
                           ChunkDemuxer* chunk_demuxer, EventQueue* event_queue)
    : web::EventTarget(settings),
      id_(id),
      asynchronous_reduction_enabled_(asynchronous_reduction_enabled),
      evict_extra_in_bytes_(GetEvictExtraInBytes(settings)),
      media_source_(media_source),
      chunk_demuxer_(chunk_demuxer),
      event_queue_(event_queue),
      audio_tracks_(
          new AudioTrackList(settings, media_source->GetMediaElement())),
      video_tracks_(
          new VideoTrackList(settings, media_source->GetMediaElement())),
      metrics_(!media_source_->MediaElementHasMaxVideoCapabilities()) {
  DCHECK(!id_.empty());
  DCHECK(media_source_);
  DCHECK(chunk_demuxer);
  DCHECK(event_queue);

  LOG(INFO) << "Evict extra in bytes is set to " << evict_extra_in_bytes_;

  chunk_demuxer_->SetTracksWatcher(
      id_,
      base::Bind(&SourceBuffer::OnInitSegmentReceived, base::Unretained(this)));
  chunk_demuxer_->SetParseWarningCallback(
      id, base::BindRepeating([](::media::SourceBufferParseWarning warning) {
        LOG(WARNING) << "Encountered SourceBufferParseWarning "
                     << static_cast<int>(warning);
      }));
}

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

  media_source_->OpenIfInEndedState();

  if (chunk_demuxer_->IsParsingMediaSegment(id_)) {
    web::DOMException::Raise(web::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) {
    web::DOMException::Raise(web::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;
}

double SourceBuffer::timestamp_offset(
    script::ExceptionState* exception_state) const {
  starboard::ScopedLock scoped_lock(timestamp_offset_mutex_);
  return timestamp_offset_;
}

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

  media_source_->OpenIfInEndedState();

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

  // We don't have to acquire |timestamp_offset_mutex_|, as no algorithms are
  // running asynchronously at this moment, which is guaranteed by the check of
  // updating() above.
  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) {
    web::DOMException::Raise(web::DOMException::kInvalidStateErr,
                             exception_state);
    return;
  }
  if (updating()) {
    web::DOMException::Raise(web::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) {
    web::DOMException::Raise(web::DOMException::kInvalidStateErr,
                             exception_state);
    return;
  }
  if (updating()) {
    web::DOMException::Raise(web::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) {
  TRACE_EVENT1("cobalt::dom", "SourceBuffer::AppendBuffer()", "size",
               data->ByteLength());
  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) {
  TRACE_EVENT1("cobalt::dom", "SourceBuffer::AppendBuffer()", "size",
               data->ByteLength());
  AppendBufferInternal(static_cast<const unsigned char*>(data->RawData()),
                       data->ByteLength(), exception_state);
}

void SourceBuffer::Abort(script::ExceptionState* exception_state) {
  TRACE_EVENT0("cobalt::dom", "SourceBuffer::Abort()");

  if (media_source_ == NULL) {
    web::DOMException::Raise(web::DOMException::kInvalidStateErr,
                             exception_state);
    return;
  }
  if (!media_source_->IsOpen()) {
    web::DOMException::Raise(web::DOMException::kInvalidStateErr,
                             exception_state);
    return;
  }

  if (active_algorithm_handle_) {
    if (!active_algorithm_handle_->algorithm()->SupportExplicitAbort()) {
      web::DOMException::Raise(web::DOMException::kInvalidStateErr,
                               exception_state);
      return;
    }
    active_algorithm_handle_->Abort();
    active_algorithm_handle_ = nullptr;
  }

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

  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) {
  TRACE_EVENT2("cobalt::dom", "SourceBuffer::Remove()", "start", start, "end",
               end);
  if (media_source_ == NULL) {
    web::DOMException::Raise(web::DOMException::kInvalidStateErr,
                             exception_state);
    return;
  }
  if (updating()) {
    web::DOMException::Raise(web::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();

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

  DCHECK_GE(start, 0);
  DCHECK_LT(start, end);

  std::unique_ptr<SourceBufferAlgorithm> algorithm(
      new SourceBufferRemoveAlgorithm(
          chunk_demuxer_, id_, DoubleToTimeDelta(start), DoubleToTimeDelta(end),
          base::Bind(asynchronous_reduction_enabled_
                         ? &SourceBuffer::ScheduleAndMaybeDispatchImmediately
                         : &SourceBuffer::ScheduleEvent,
                     base::Unretained(this)),
          base::Bind(&SourceBuffer::OnAlgorithmFinalized,
                     base::Unretained(this))));
  active_algorithm_handle_ =
      new SerializedAlgorithmRunner::Handle<SourceBufferAlgorithm>(
          std::move(algorithm));
  media_source_->GetAlgorithmRunner(std::numeric_limits<int>::max())
      ->Start(active_algorithm_handle_);
}

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

  track_defaults_ = track_defaults;
}

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

  if (active_algorithm_handle_) {
    active_algorithm_handle_->Abort();
    active_algorithm_handle_ = nullptr;
  }

  DCHECK(media_source_);

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

  // TODO: Determine if the source buffer contains an audio or video stream,
  //       maybe by implementing track support and get from the type of the
  //       track, and print the steam type along with the metrics.
  metrics_.PrintCurrentMetricsAndUpdateAccumulatedMetrics();

  chunk_demuxer_->RemoveId(id_);
  if (chunk_demuxer_->GetAllStreams().empty()) {
    metrics_.PrintAccumulatedMetrics();
  }

  chunk_demuxer_ = NULL;
  media_source_ = NULL;
  event_queue_ = NULL;

  pending_append_data_.reset();
  pending_append_data_capacity_ = 0;
}

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

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

void SourceBuffer::TraceMembers(script::Tracer* tracer) {
  web::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::OnInitSegmentReceived(std::unique_ptr<MediaTracks> tracks) {
  if (!first_initialization_segment_received_) {
    // This can be called from non-web thread when the append is async.
    if (!web_task_runner_->BelongsToCurrentThread()) {
      web_task_runner_->PostTask(
          FROM_HERE, base::Bind(&SourceBuffer::OnInitSegmentReceived, this,
                                base::Passed(&tracks)));
      return;
    }
    media_source_->SetSourceBufferActive(this, true);
    first_initialization_segment_received_ = true;
  }

  // TODO: Implement track support.
}

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

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

bool SourceBuffer::PrepareAppend(size_t new_data_size,
                                 script::ExceptionState* exception_state) {
  TRACE_EVENT1("cobalt::dom", "SourceBuffer::PrepareAppend()", "new_data_size",
               new_data_size);
  if (media_source_ == NULL) {
    web::DOMException::Raise(web::DOMException::kInvalidStateErr,
                             exception_state);
    return false;
  }
  if (updating()) {
    web::DOMException::Raise(web::DOMException::kInvalidStateErr,
                             exception_state);
    return false;
  }

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

  media_source_->OpenIfInEndedState();

  double current_time = media_source_->GetMediaElement()->current_time(NULL);
  if (!chunk_demuxer_->EvictCodedFrames(
          id_, base::TimeDelta::FromSecondsD(current_time),
          new_data_size + evict_extra_in_bytes_)) {
    web::DOMException::Raise(web::DOMException::kQuotaExceededErr,
                             exception_state);
    return false;
  }

  return true;
}

void SourceBuffer::AppendBufferInternal(
    const unsigned char* data, size_t size,
    script::ExceptionState* exception_state) {
  TRACE_EVENT1("cobalt::dom", "SourceBuffer::AppendBufferInternal()", "size",
               size);
  metrics_.StartTracking();
  if (!PrepareAppend(size, exception_state)) {
    return;
  }
  metrics_.EndTracking(0);

  DCHECK(data || size == 0);

  if (data) {
    if (pending_append_data_capacity_ < size) {
      pending_append_data_.reset();
      pending_append_data_.reset(new uint8_t[size]);
      pending_append_data_capacity_ = size;
    }
    memcpy(pending_append_data_.get(), data, size);
  }

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

  std::unique_ptr<SourceBufferAlgorithm> algorithm(
      new SourceBufferAppendAlgorithm(
          media_source_, chunk_demuxer_, id_, pending_append_data_.get(), size,
          DoubleToTimeDelta(append_window_start_),
          DoubleToTimeDelta(append_window_end_),
          DoubleToTimeDelta(timestamp_offset_),
          base::Bind(&SourceBuffer::UpdateTimestampOffset,
                     base::Unretained(this)),
          base::Bind(asynchronous_reduction_enabled_
                         ? &SourceBuffer::ScheduleAndMaybeDispatchImmediately
                         : &SourceBuffer::ScheduleEvent,
                     base::Unretained(this)),
          base::Bind(&SourceBuffer::OnAlgorithmFinalized,
                     base::Unretained(this)),
          &metrics_));
  active_algorithm_handle_ =
      new SerializedAlgorithmRunner::Handle<SourceBufferAlgorithm>(
          std::move(algorithm));
  media_source_->GetAlgorithmRunner(size)->Start(active_algorithm_handle_);
}

void SourceBuffer::OnAlgorithmFinalized() {
  DCHECK(active_algorithm_handle_);
  active_algorithm_handle_ = nullptr;
}

void SourceBuffer::UpdateTimestampOffset(base::TimeDelta timestamp_offset) {
  starboard::ScopedLock scoped_lock(timestamp_offset_mutex_);
  // The check avoids overwriting |timestamp_offset_| when there is a small
  // difference between its float and its int64_t representation .
  if (DoubleToTimeDelta(timestamp_offset_) != timestamp_offset) {
    timestamp_offset_ = timestamp_offset.InSecondsF();
  }
}

}  // namespace dom
}  // namespace cobalt
