// Copyright 2013 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 "cobalt/media/base/text_renderer.h"

#include <memory>
#include <string>
#include <utility>

#include "base/bind.h"
#include "base/callback_helpers.h"
#include "base/logging.h"
#include "base/single_thread_task_runner.h"
#include "cobalt/media/base/bind_to_current_loop.h"
#include "cobalt/media/base/decoder_buffer.h"
#include "cobalt/media/base/demuxer.h"
#include "cobalt/media/base/text_cue.h"
#include "starboard/common/string.h"
#include "starboard/types.h"

namespace cobalt {
namespace media {

TextRenderer::TextRenderer(
    const scoped_refptr<base::SingleThreadTaskRunner>& task_runner,
    const AddTextTrackCB& add_text_track_cb)
    : task_runner_(task_runner),
      add_text_track_cb_(add_text_track_cb),
      state_(kUninitialized),
      pending_read_count_(0),
      weak_factory_(this) {}

TextRenderer::~TextRenderer() {
  DCHECK(task_runner_->BelongsToCurrentThread());
  text_track_state_map_.clear();
  if (!pause_cb_.is_null()) base::ResetAndReturn(&pause_cb_).Run();
}

void TextRenderer::Initialize(const base::Closure& ended_cb) {
  DCHECK(task_runner_->BelongsToCurrentThread());
  DCHECK(!ended_cb.is_null());
  DCHECK_EQ(kUninitialized, state_) << "state_ " << state_;
  DCHECK(text_track_state_map_.empty());
  DCHECK_EQ(pending_read_count_, 0);
  DCHECK(pending_eos_set_.empty());
  DCHECK(ended_cb_.is_null());

  ended_cb_ = ended_cb;
  state_ = kPaused;
}

void TextRenderer::StartPlaying() {
  DCHECK(task_runner_->BelongsToCurrentThread());
  DCHECK_EQ(state_, kPaused) << "state_ " << state_;

  for (auto itr = text_track_state_map_.begin();
       itr != text_track_state_map_.end(); ++itr) {
    TextTrackState* state = itr->second.get();
    if (state->read_state == TextTrackState::kReadPending) {
      DCHECK_GT(pending_read_count_, 0);
      continue;
    }

    Read(state, itr->first);
  }

  state_ = kPlaying;
}

void TextRenderer::Pause(const base::Closure& callback) {
  DCHECK(task_runner_->BelongsToCurrentThread());
  DCHECK(state_ == kPlaying || state_ == kEnded) << "state_ " << state_;
  DCHECK_GE(pending_read_count_, 0);

  if (pending_read_count_ == 0) {
    state_ = kPaused;
    task_runner_->PostTask(FROM_HERE, callback);
    return;
  }

  pause_cb_ = callback;
  state_ = kPausePending;
}

void TextRenderer::Flush(const base::Closure& callback) {
  DCHECK(task_runner_->BelongsToCurrentThread());
  DCHECK_EQ(pending_read_count_, 0);
  DCHECK(state_ == kPaused) << "state_ " << state_;

  for (auto itr = text_track_state_map_.begin();
       itr != text_track_state_map_.end(); ++itr) {
    pending_eos_set_.insert(itr->first);
    itr->second->text_ranges_.Reset();
  }
  DCHECK_EQ(pending_eos_set_.size(), text_track_state_map_.size());
  task_runner_->PostTask(FROM_HERE, callback);
}

void TextRenderer::AddTextStream(DemuxerStream* text_stream,
                                 const TextTrackConfig& config) {
  DCHECK(task_runner_->BelongsToCurrentThread());
  DCHECK(state_ != kUninitialized) << "state_ " << state_;
  DCHECK(text_track_state_map_.find(text_stream) ==
         text_track_state_map_.end());
  DCHECK(pending_eos_set_.find(text_stream) == pending_eos_set_.end());

  AddTextTrackDoneCB done_cb =
      BindToCurrentLoop(base::Bind(&TextRenderer::OnAddTextTrackDone,
                                   weak_factory_.GetWeakPtr(), text_stream));

  add_text_track_cb_.Run(config, done_cb);
}

void TextRenderer::RemoveTextStream(DemuxerStream* text_stream) {
  DCHECK(task_runner_->BelongsToCurrentThread());

  auto itr = text_track_state_map_.find(text_stream);
  DCHECK(itr != text_track_state_map_.end());

  TextTrackState* state = itr->second.get();
  DCHECK_EQ(state->read_state, TextTrackState::kReadIdle);
  text_track_state_map_.erase(itr);

  pending_eos_set_.erase(text_stream);
}

bool TextRenderer::HasTracks() const {
  DCHECK(task_runner_->BelongsToCurrentThread());
  return !text_track_state_map_.empty();
}

void TextRenderer::BufferReady(DemuxerStream* stream,
                               DemuxerStream::Status status,
                               const scoped_refptr<DecoderBuffer>& input) {
  DCHECK(task_runner_->BelongsToCurrentThread());
  DCHECK_NE(status, DemuxerStream::kConfigChanged);

  if (status == DemuxerStream::kAborted) {
    DCHECK(!input.get());
    DCHECK_GT(pending_read_count_, 0);
    DCHECK(pending_eos_set_.find(stream) != pending_eos_set_.end());

    auto itr = text_track_state_map_.find(stream);
    DCHECK(itr != text_track_state_map_.end());

    TextTrackState* state = itr->second.get();
    DCHECK_EQ(state->read_state, TextTrackState::kReadPending);

    --pending_read_count_;
    state->read_state = TextTrackState::kReadIdle;

    switch (state_) {
      case kPlaying:
        return;

      case kPausePending:
        if (pending_read_count_ == 0) {
          state_ = kPaused;
          base::ResetAndReturn(&pause_cb_).Run();
        }

        return;

      case kPaused:
      case kUninitialized:
      case kEnded:
        NOTREACHED();
        return;
    }

    NOTREACHED();
    return;
  }

  if (input->end_of_stream()) {
    CueReady(stream, NULL);
    return;
  }

  DCHECK_EQ(status, DemuxerStream::kOk);
  DCHECK_GE(input->side_data_size(), 2u);

  // The side data contains both the cue id and cue settings,
  // each terminated with a NUL.
  const char* id_ptr = reinterpret_cast<const char*>(input->side_data());
  size_t id_len = SbStringGetLength(id_ptr);
  std::string id(id_ptr, id_len);

  const char* settings_ptr = id_ptr + id_len + 1;
  size_t settings_len = SbStringGetLength(settings_ptr);
  std::string settings(settings_ptr, settings_len);

  // The cue payload is stored in the data-part of the input buffer.
  std::string text(input->data(), input->data() + input->data_size());

  scoped_refptr<TextCue> text_cue(
      new TextCue(input->timestamp(), input->duration(), id, settings, text));

  CueReady(stream, text_cue);
}

void TextRenderer::CueReady(DemuxerStream* text_stream,
                            const scoped_refptr<TextCue>& text_cue) {
  DCHECK(task_runner_->BelongsToCurrentThread());
  DCHECK_NE(state_, kUninitialized);
  DCHECK_GT(pending_read_count_, 0);
  DCHECK(pending_eos_set_.find(text_stream) != pending_eos_set_.end());

  auto itr = text_track_state_map_.find(text_stream);
  DCHECK(itr != text_track_state_map_.end());

  TextTrackState* state = itr->second.get();
  DCHECK_EQ(state->read_state, TextTrackState::kReadPending);
  DCHECK(state->text_track);

  --pending_read_count_;
  state->read_state = TextTrackState::kReadIdle;

  switch (state_) {
    case kPlaying: {
      if (text_cue.get()) break;

      const size_t count = pending_eos_set_.erase(text_stream);
      DCHECK_EQ(count, 1U);

      if (pending_eos_set_.empty()) {
        DCHECK_EQ(pending_read_count_, 0);
        state_ = kEnded;
        task_runner_->PostTask(FROM_HERE, ended_cb_);
        return;
      }

      DCHECK_GT(pending_read_count_, 0);
      return;
    }
    case kPausePending: {
      if (text_cue.get()) break;

      const size_t count = pending_eos_set_.erase(text_stream);
      DCHECK_EQ(count, 1U);

      if (pending_read_count_ > 0) {
        DCHECK(!pending_eos_set_.empty());
        return;
      }

      state_ = kPaused;
      base::ResetAndReturn(&pause_cb_).Run();

      return;
    }

    case kPaused:
    case kUninitialized:
    case kEnded:
      NOTREACHED();
      return;
  }

  base::TimeDelta start = text_cue->timestamp();

  if (state->text_ranges_.AddCue(start)) {
    base::TimeDelta end = start + text_cue->duration();

    state->text_track->addWebVTTCue(start, end, text_cue->id(),
                                    text_cue->text(), text_cue->settings());
  }

  if (state_ == kPlaying) {
    Read(state, text_stream);
    return;
  }

  if (pending_read_count_ == 0) {
    DCHECK_EQ(state_, kPausePending) << "state_ " << state_;
    state_ = kPaused;
    base::ResetAndReturn(&pause_cb_).Run();
  }
}

void TextRenderer::OnAddTextTrackDone(DemuxerStream* text_stream,
                                      std::unique_ptr<TextTrack> text_track) {
  DCHECK(task_runner_->BelongsToCurrentThread());
  DCHECK_NE(state_, kUninitialized);
  DCHECK(text_stream);
  DCHECK(text_track);

  std::unique_ptr<TextTrackState> state(
      new TextTrackState(std::move(text_track)));
  text_track_state_map_[text_stream] = std::move(state);
  pending_eos_set_.insert(text_stream);

  if (state_ == kPlaying)
    Read(text_track_state_map_[text_stream].get(), text_stream);
}

void TextRenderer::Read(TextTrackState* state, DemuxerStream* text_stream) {
  DCHECK_NE(state->read_state, TextTrackState::kReadPending);

  state->read_state = TextTrackState::kReadPending;
  ++pending_read_count_;

  text_stream->Read(base::Bind(&TextRenderer::BufferReady,
                               weak_factory_.GetWeakPtr(), text_stream));
}

TextRenderer::TextTrackState::TextTrackState(std::unique_ptr<TextTrack> tt)
    : read_state(kReadIdle), text_track(std::move(tt)) {}

TextRenderer::TextTrackState::~TextTrackState() {}

}  // namespace media
}  // namespace cobalt
