// 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 = strlen(id_ptr);
  std::string id(id_ptr, id_len);

  const char* settings_ptr = id_ptr + id_len + 1;
  size_t settings_len = strlen(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
