// Copyright 2017 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "media/test/test_media_source.h"

#include "base/bind.h"
#include "base/bind_helpers.h"
#include "base/threading/thread_task_runner_handle.h"
#include "media/base/test_data_util.h"
#include "media/base/timestamp_constants.h"

namespace {

// Copies parsed type and codecs from |mimetype| into |type| and |codecs|.
// This code assumes that |mimetype| is one of the following forms:
// 1. mimetype without codecs (e.g. audio/mpeg)
// 2. mimetype with codecs (e.g. video/webm; codecs="vorbis,vp8")
void SplitMime(const std::string& mimetype,
               std::string* type,
               std::string* codecs) {
  DCHECK(type);
  DCHECK(codecs);
  size_t semicolon = mimetype.find(";");
  if (semicolon == std::string::npos) {
    *type = mimetype;
    *codecs = "";
    return;
  }

  *type = mimetype.substr(0, semicolon);
  size_t codecs_param_start = mimetype.find("codecs=\"", semicolon);
  CHECK_NE(codecs_param_start, std::string::npos);
  codecs_param_start += 8;  // Skip over the codecs=".
  size_t codecs_param_end = mimetype.find("\"", codecs_param_start);
  CHECK_NE(codecs_param_end, std::string::npos);
  *codecs = mimetype.substr(codecs_param_start,
                            codecs_param_end - codecs_param_start);
}

}  // namespace

namespace media {

constexpr char kSourceId[] = "SourceId";

TestMediaSource::TestMediaSource(const std::string& filename,
                                 const std::string& mimetype,
                                 size_t initial_append_size,
                                 bool initial_sequence_mode)
    : current_position_(0),
      initial_append_size_(initial_append_size),
      initial_sequence_mode_(initial_sequence_mode),
      mimetype_(mimetype),
      chunk_demuxer_(new ChunkDemuxer(
          base::Bind(&TestMediaSource::DemuxerOpened, base::Unretained(this)),
          base::DoNothing(),
          base::BindRepeating(&TestMediaSource::OnEncryptedMediaInitData,
                              base::Unretained(this)),
          &media_log_)),
      owned_chunk_demuxer_(chunk_demuxer_) {
  file_data_ = ReadTestDataFile(filename);

  if (initial_append_size_ == kAppendWholeFile)
    initial_append_size_ = file_data_->data_size();

  CHECK_GT(initial_append_size_, 0u);
  CHECK_LE(initial_append_size_, file_data_->data_size());
}

TestMediaSource::TestMediaSource(const std::string& filename,
                                 size_t initial_append_size,
                                 bool initial_sequence_mode)
    : TestMediaSource(filename,
                      GetMimeTypeForFile(filename),
                      initial_append_size,
                      initial_sequence_mode) {}

TestMediaSource::TestMediaSource(scoped_refptr<DecoderBuffer> data,
                                 const std::string& mimetype,
                                 size_t initial_append_size,
                                 bool initial_sequence_mode)
    : file_data_(data),
      current_position_(0),
      initial_append_size_(initial_append_size),
      initial_sequence_mode_(initial_sequence_mode),
      mimetype_(mimetype),
      chunk_demuxer_(new ChunkDemuxer(
          base::Bind(&TestMediaSource::DemuxerOpened, base::Unretained(this)),
          base::DoNothing(),
          base::BindRepeating(&TestMediaSource::OnEncryptedMediaInitData,
                              base::Unretained(this)),
          &media_log_)),
      owned_chunk_demuxer_(chunk_demuxer_) {
  if (initial_append_size_ == kAppendWholeFile)
    initial_append_size_ = file_data_->data_size();

  CHECK_GT(initial_append_size_, 0u);
  CHECK_LE(initial_append_size_, file_data_->data_size());
}

TestMediaSource::~TestMediaSource() = default;

std::unique_ptr<Demuxer> TestMediaSource::GetDemuxer() {
  return std::move(owned_chunk_demuxer_);
}

void TestMediaSource::SetAppendWindow(base::TimeDelta timestamp_offset,
                                      base::TimeDelta append_window_start,
                                      base::TimeDelta append_window_end) {
  last_timestamp_offset_ = timestamp_offset;
  append_window_start_ = append_window_start;
  append_window_end_ = append_window_end;
}

void TestMediaSource::Seek(base::TimeDelta seek_time,
                           size_t new_position,
                           size_t seek_append_size) {
  chunk_demuxer_->StartWaitingForSeek(seek_time);

  chunk_demuxer_->ResetParserState(kSourceId, base::TimeDelta(),
                                   kInfiniteDuration, &last_timestamp_offset_);

  CHECK_LT(new_position, file_data_->data_size());
  current_position_ = new_position;

  AppendData(seek_append_size);
}

void TestMediaSource::Seek(base::TimeDelta seek_time) {
  chunk_demuxer_->StartWaitingForSeek(seek_time);
}

void TestMediaSource::SetSequenceMode(bool sequence_mode) {
  CHECK(!chunk_demuxer_->IsParsingMediaSegment(kSourceId));
  chunk_demuxer_->SetSequenceMode(kSourceId, sequence_mode);
}

void TestMediaSource::AppendData(size_t size) {
  CHECK(chunk_demuxer_);
  CHECK_LT(current_position_, file_data_->data_size());
  CHECK_LE(current_position_ + size, file_data_->data_size());

  bool success = chunk_demuxer_->AppendData(
      kSourceId, file_data_->data() + current_position_, size,
      append_window_start_, append_window_end_, &last_timestamp_offset_);
  current_position_ += size;

  VerifyExpectedAppendResult(success);

  if (do_eos_after_next_append_) {
    do_eos_after_next_append_ = false;
    if (success)
      EndOfStream();
  }
}

bool TestMediaSource::AppendAtTime(base::TimeDelta timestamp_offset,
                                   const uint8_t* pData,
                                   int size) {
  CHECK(!chunk_demuxer_->IsParsingMediaSegment(kSourceId));
  bool success =
      chunk_demuxer_->AppendData(kSourceId, pData, size, append_window_start_,
                                 append_window_end_, &timestamp_offset);
  last_timestamp_offset_ = timestamp_offset;
  return success;
}

void TestMediaSource::AppendAtTimeWithWindow(
    base::TimeDelta timestamp_offset,
    base::TimeDelta append_window_start,
    base::TimeDelta append_window_end,
    const uint8_t* pData,
    int size) {
  CHECK(!chunk_demuxer_->IsParsingMediaSegment(kSourceId));
  VerifyExpectedAppendResult(
      chunk_demuxer_->AppendData(kSourceId, pData, size, append_window_start,
                                 append_window_end, &timestamp_offset));
  last_timestamp_offset_ = timestamp_offset;
}

void TestMediaSource::SetMemoryLimits(size_t limit_bytes) {
  chunk_demuxer_->SetMemoryLimitsForTest(DemuxerStream::AUDIO, limit_bytes);
  chunk_demuxer_->SetMemoryLimitsForTest(DemuxerStream::VIDEO, limit_bytes);
}

bool TestMediaSource::EvictCodedFrames(base::TimeDelta currentMediaTime,
                                       size_t newDataSize) {
  return chunk_demuxer_->EvictCodedFrames(kSourceId, currentMediaTime,
                                          newDataSize);
}

void TestMediaSource::RemoveRange(base::TimeDelta start, base::TimeDelta end) {
  chunk_demuxer_->Remove(kSourceId, start, end);
}

void TestMediaSource::EndOfStream() {
  chunk_demuxer_->MarkEndOfStream(PIPELINE_OK);
}

void TestMediaSource::UnmarkEndOfStream() {
  chunk_demuxer_->UnmarkEndOfStream();
}

void TestMediaSource::Shutdown() {
  if (!chunk_demuxer_)
    return;
  chunk_demuxer_->ResetParserState(kSourceId, base::TimeDelta(),
                                   kInfiniteDuration, &last_timestamp_offset_);
  chunk_demuxer_->Shutdown();
  chunk_demuxer_ = NULL;
}

void TestMediaSource::DemuxerOpened() {
  base::ThreadTaskRunnerHandle::Get()->PostTask(
      FROM_HERE, base::BindOnce(&TestMediaSource::DemuxerOpenedTask,
                                base::Unretained(this)));
}

void TestMediaSource::DemuxerOpenedTask() {
  ChunkDemuxer::Status status = AddId();
  if (status != ChunkDemuxer::kOk) {
    CHECK(demuxer_failure_cb_);
    demuxer_failure_cb_.Run(DEMUXER_ERROR_COULD_NOT_OPEN);
    return;
  }
  chunk_demuxer_->SetTracksWatcher(
      kSourceId, base::Bind(&TestMediaSource::InitSegmentReceived,
                            base::Unretained(this)));

  chunk_demuxer_->SetParseWarningCallback(
      kSourceId,
      base::Bind(&TestMediaSource::OnParseWarningMock, base::Unretained(this)));

  SetSequenceMode(initial_sequence_mode_);
  AppendData(initial_append_size_);
}

ChunkDemuxer::Status TestMediaSource::AddId() {
  std::string type;
  std::string codecs;
  SplitMime(mimetype_, &type, &codecs);
  return chunk_demuxer_->AddId(kSourceId, type, codecs);
}

void TestMediaSource::ChangeType(const std::string& mimetype) {
  chunk_demuxer_->ResetParserState(kSourceId, base::TimeDelta(),
                                   kInfiniteDuration, &last_timestamp_offset_);
  std::string type;
  std::string codecs;
  SplitMime(mimetype, &type, &codecs);
  mimetype_ = mimetype;
  chunk_demuxer_->ChangeType(kSourceId, type, codecs);
}

void TestMediaSource::OnEncryptedMediaInitData(
    EmeInitDataType init_data_type,
    const std::vector<uint8_t>& init_data) {
  CHECK(!init_data.empty());
  CHECK(encrypted_media_init_data_cb_);
  encrypted_media_init_data_cb_.Run(init_data_type, init_data);
}

void TestMediaSource::InitSegmentReceived(std::unique_ptr<MediaTracks> tracks) {
  CHECK(tracks.get());
  EXPECT_GT(tracks->tracks().size(), 0u);
  CHECK(chunk_demuxer_);
  // Verify that track ids are unique.
  std::set<MediaTrack::Id> track_ids;
  for (const auto& track : tracks->tracks()) {
    EXPECT_EQ(track_ids.end(), track_ids.find(track->id()));
    track_ids.insert(track->id());
  }
  InitSegmentReceivedMock(tracks);
}

void TestMediaSource::VerifyExpectedAppendResult(bool append_result) {
  if (expected_append_result_ == ExpectedAppendResult::kSuccessOrFailure)
    return;  // |append_result| is ignored in this case.

  ASSERT_EQ(expected_append_result_ == ExpectedAppendResult::kSuccess,
            append_result);
}

}  // namespace media
