// 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,
    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),
      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_);
  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);

  const size_t kMaxAppendSize = 128 * 1024;

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

  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
