// Copyright 2022 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_algorithm.h"

#include <algorithm>
#include <utility>

#include "base/logging.h"
#include "base/trace_event/trace_event.h"
#include "cobalt/dom/media_source.h"

namespace cobalt {
namespace dom {

SourceBufferAppendAlgorithm::SourceBufferAppendAlgorithm(
    MediaSource* media_source, ::media::ChunkDemuxer* chunk_demuxer,
    const std::string& id, const uint8_t* buffer, size_t size_in_bytes,
    size_t max_append_size_in_bytes, base::TimeDelta append_window_start,
    base::TimeDelta append_window_end, base::TimeDelta timestamp_offset,
    UpdateTimestampOffsetCB&& update_timestamp_offset_cb,
    ScheduleEventCB&& schedule_event_cb, base::OnceClosure&& finalized_cb,
    SourceBufferMetrics* metrics)
    : media_source_(media_source),
      chunk_demuxer_(chunk_demuxer),
      id_(id),
      buffer_(buffer),
      max_append_size_(max_append_size_in_bytes),
      bytes_remaining_(size_in_bytes),
      append_window_start_(append_window_start),
      append_window_end_(append_window_end),
      timestamp_offset_(timestamp_offset),
      update_timestamp_offset_cb_(std::move(update_timestamp_offset_cb)),
      schedule_event_cb_(std::move(schedule_event_cb)),
      finalized_cb_(std::move(finalized_cb)),
      metrics_(metrics) {
  DCHECK(media_source_);
  DCHECK(chunk_demuxer_);
  DCHECK_GT(static_cast<int>(max_append_size_), 0);
  if (bytes_remaining_ > 0) {
    DCHECK(buffer);
  }
  DCHECK(update_timestamp_offset_cb_);
  DCHECK(schedule_event_cb_);
  DCHECK(metrics_);
  TRACE_EVENT1("cobalt::dom", "SourceBufferAppendAlgorithm ctor",
               "bytes_remaining", bytes_remaining_);
}

void SourceBufferAppendAlgorithm::Process(bool* finished) {
  DCHECK(finished);
  DCHECK(!*finished);

  size_t append_size = std::min(bytes_remaining_, max_append_size_);

  TRACE_EVENT1("cobalt::dom", "SourceBufferAppendAlgorithm::Process()",
               "append_size", append_size);

  metrics_->StartTracking();
  succeeded_ = chunk_demuxer_->AppendData(
      id_, buffer_, append_size, append_window_start_, append_window_end_,
      &timestamp_offset_);
  update_timestamp_offset_cb_.Run(timestamp_offset_);
  metrics_->EndTracking(succeeded_ ? append_size : 0);

  if (succeeded_) {
    buffer_ += append_size;
    bytes_remaining_ -= append_size;

    if (bytes_remaining_ == 0) {
      *finished = true;
      return;
    }

    return;
  }

  chunk_demuxer_->ResetParserState(id_, append_window_start_,
                                   append_window_end_, &timestamp_offset_);
  update_timestamp_offset_cb_.Run(timestamp_offset_);
  *finished = true;
}

void SourceBufferAppendAlgorithm::Abort() {
  TRACE_EVENT0("cobalt::dom", "SourceBufferAppendAlgorithm::Abort()");
  schedule_event_cb_.Run(base::Tokens::abort());
  schedule_event_cb_.Run(base::Tokens::updateend());
}

void SourceBufferAppendAlgorithm::Finalize() {
  TRACE_EVENT1("cobalt::dom", "SourceBufferAppendAlgorithm::Finalize()",
               "succeeded", succeeded_);

  if (succeeded_) {
    schedule_event_cb_.Run(base::Tokens::update());
    schedule_event_cb_.Run(base::Tokens::updateend());
  } else {
    schedule_event_cb_.Run(base::Tokens::error());
    schedule_event_cb_.Run(base::Tokens::updateend());
    media_source_->EndOfStreamAlgorithm(kMediaSourceEndOfStreamErrorDecode);
  }

  std::move(finalized_cb_).Run();
}

SourceBufferRemoveAlgorithm::SourceBufferRemoveAlgorithm(
    ::media::ChunkDemuxer* chunk_demuxer, const std::string& id,
    base::TimeDelta pending_remove_start, base::TimeDelta pending_remove_end,
    ScheduleEventCB&& schedule_event_cb, base::OnceClosure&& finalized_cb)
    : chunk_demuxer_(chunk_demuxer),
      id_(id),
      pending_remove_start_(pending_remove_start),
      pending_remove_end_(pending_remove_end),
      schedule_event_cb_(std::move(schedule_event_cb)),
      finalized_cb_(std::move(finalized_cb)) {
  TRACE_EVENT0("cobalt::dom", "SourceBufferRemoveAlgorithm ctor");
  DCHECK(chunk_demuxer_);
  DCHECK(schedule_event_cb_);
}

void SourceBufferRemoveAlgorithm::Process(bool* finished) {
  TRACE_EVENT0("cobalt::dom", "SourceBufferRemoveAlgorithm::Process()");
  chunk_demuxer_->Remove(id_, pending_remove_start_, pending_remove_end_);
  *finished = true;
}

void SourceBufferRemoveAlgorithm::Abort() {
  TRACE_EVENT0("cobalt::dom", "SourceBufferRemoveAlgorithm::Abort()");
  // SourceBufferRemoveAlgorithm cannot be cancelled explicitly by the web app.
  // This function will only be called when the SourceBuffer is being removed
  // from the MediaSource and no events should be fired.
}

void SourceBufferRemoveAlgorithm::Finalize() {
  TRACE_EVENT0("cobalt::dom", "SourceBufferRemoveAlgorithm::Finalize()");

  schedule_event_cb_.Run(base::Tokens::update());
  schedule_event_cb_.Run(base::Tokens::updateend());
  std::move(finalized_cb_).Run();
}

}  // namespace dom
}  // namespace cobalt
