// Copyright 2020 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 <algorithm>
#include <deque>
#include <functional>

#include "starboard/atomic.h"
#include "starboard/common/optional.h"
#include "starboard/common/queue.h"
#include "starboard/common/scoped_ptr.h"
#include "starboard/common/string.h"
#include "starboard/nplb/player_test_util.h"
#include "starboard/shared/starboard/player/video_dmp_reader.h"
#include "starboard/string.h"
#include "starboard/testing/fake_graphics_context_provider.h"
#include "testing/gtest/include/gtest/gtest.h"

namespace starboard {
namespace nplb {
namespace {

using shared::starboard::player::video_dmp::VideoDmpReader;
using testing::FakeGraphicsContextProvider;
using ::testing::ValuesIn;

const SbTimeMonotonic kDefaultWaitForDecoderStateNeedsDataTimeout =
    5 * kSbTimeSecond;
const SbTimeMonotonic kDefaultWaitForPlayerStateTimeout = 5 * kSbTimeSecond;
const SbTimeMonotonic kDefaultWaitForCallbackEventTimeout =
    15 * kSbTimeMillisecond;

class SbPlayerWriteSampleTest
    : public ::testing::TestWithParam<SbPlayerTestConfig> {
 public:
  SbPlayerWriteSampleTest();

  void SetUp() override;
  void TearDown() override;

 protected:
  struct CallbackEvent {
    CallbackEvent() {}

    CallbackEvent(SbPlayer player, SbPlayerState state, int ticket)
        : player(player), player_state(state), ticket(ticket) {}

    CallbackEvent(SbPlayer player, SbPlayerDecoderState state, int ticket)
        : player(player), decoder_state(state), ticket(ticket) {}

    bool HasStateUpdate() const {
      return player_state.has_engaged() || decoder_state.has_engaged();
    }

    SbPlayer player = kSbPlayerInvalid;
    optional<SbPlayerState> player_state;
    optional<SbPlayerDecoderState> decoder_state;
    int ticket = SB_PLAYER_INITIAL_TICKET;
  };

  static void DecoderStatusCallback(SbPlayer player,
                                    void* context,
                                    SbMediaType type,
                                    SbPlayerDecoderState state,
                                    int ticket);

  static void PlayerStatusCallback(SbPlayer player,
                                   void* context,
                                   SbPlayerState state,
                                   int ticket);

  static void ErrorCallback(SbPlayer player,
                            void* context,
                            SbPlayerError error,
                            const char* message);

  void InitializePlayer();

  void PrepareForSeek();

  void Seek(const SbTime time);

  // When the |output_mode| is decoding to texture, then this method is used to
  // advance the decoded frames.
  void GetDecodeTargetWhenSupported();

  // Callback methods from the underlying player.
  void OnDecoderState(SbPlayer player,
                      SbMediaType media_type,
                      SbPlayerDecoderState state,
                      int ticket);
  void OnPlayerState(SbPlayer player, SbPlayerState state, int ticket);
  void OnError(SbPlayer player, SbPlayerError error, const char* message);

  // Waits for |kSbPlayerDecoderStateNeedsData| to be sent.
  void WaitForDecoderStateNeedsData(
      const SbTime timeout = kDefaultWaitForDecoderStateNeedsDataTimeout);

  // Waits for desired player state update to be sent.
  void WaitForPlayerState(
      const SbPlayerState desired_state,
      const SbTime timeout = kDefaultWaitForPlayerStateTimeout);

  // Player and Decoder methods for driving input and output.
  void WriteSingleInput(size_t index);
  void WriteEndOfStream();
  void WriteMultipleInputs(size_t start_index, size_t num_inputs_to_write);
  void DrainOutputs();

  int GetNumBuffers() const;

  SbMediaType GetTestMediaType() const { return test_media_type_; }

  // Determine if the the current event is valid based on previously received
  // player state updates, or other inputs to the player.
  void AssertPlayerStateIsValid(SbPlayerState state) const;

  bool HasReceivedPlayerState(SbPlayerState state) const {
    return player_state_set_.find(state) != player_state_set_.end();
  }

  // Checks if there are pending callback events and, if so, logs the received
  // state update in the appropriate tracking container:
  // * |decoder_state_queue_| for SbPlayerDecoderState updates.
  // * |player_state_set_| for SbPlayerState updates.
  // Executes a blocking wait for any new CallbackEvents to be enqueued.
  void TryProcessCallbackEvents(SbTime timeout);

  // Queue of events from the underlying player.
  Queue<CallbackEvent> callback_event_queue_;

  // Ordered queue of pending decoder state updates.
  std::deque<SbPlayerDecoderState> decoder_state_queue_;

  // Set of received player state updates from the underlying player. This is
  // used to check that the state updates occur in a valid order during normal
  // playback.
  std::set<SbPlayerState> player_state_set_;

  // Test instance specific configuration.
  std::string dmp_filename_;
  SbMediaType test_media_type_;
  SbPlayerOutputMode output_mode_;
  scoped_ptr<VideoDmpReader> dmp_reader_;

  FakeGraphicsContextProvider fake_graphics_context_provider_;
  SbPlayer player_ = kSbPlayerInvalid;

  bool destroy_player_called_ = false;
  bool end_of_stream_written_ = false;
  atomic_bool error_occurred_;
  int ticket_ = SB_PLAYER_INITIAL_TICKET;
};

SbPlayerWriteSampleTest::SbPlayerWriteSampleTest() {
  const char* audio_filename = std::get<0>(GetParam());
  const char* video_filename = std::get<1>(GetParam());
  output_mode_ = std::get<2>(GetParam());

  SB_DCHECK(output_mode_ != kSbPlayerOutputModeInvalid);

  if (audio_filename != NULL) {
    SB_DCHECK(video_filename == NULL);

    dmp_filename_ = audio_filename;
    test_media_type_ = kSbMediaTypeAudio;
  } else {
    SB_DCHECK(video_filename != NULL);

    dmp_filename_ = video_filename;
    test_media_type_ = kSbMediaTypeVideo;
  }
  dmp_reader_.reset(
      new VideoDmpReader(ResolveTestFileName(dmp_filename_.c_str()).c_str()));

  SB_LOG(INFO) << FormatString(
      "Initialize SbPlayerWriteSampleTest with dmp file '%s' and with output "
      "mode '%s'.",
      dmp_filename_.c_str(),
      output_mode_ == kSbPlayerOutputModeDecodeToTexture ? "Decode To Texture"
                                                         : "Punchout");
}

std::string GetSbPlayerTestConfigName(
    ::testing::TestParamInfo<SbPlayerTestConfig> info) {
  const char* audio_filename = std::get<0>(info.param);
  const char* video_filename = std::get<1>(info.param);
  SbPlayerOutputMode output_mode = std::get<2>(info.param);
  std::string name(FormatString(
      "audio_%s_video_%s_output_%s", audio_filename, video_filename,
      output_mode == kSbPlayerOutputModeDecodeToTexture ? "DecodeToTexture"
                                                        : "Punchout"));
  std::replace(name.begin(), name.end(), '.', '_');
  std::replace(name.begin(), name.end(), '(', '_');
  std::replace(name.begin(), name.end(), ')', '_');
  return name;
}

void SbPlayerWriteSampleTest::SetUp() {
  SbMediaVideoCodec video_codec = dmp_reader_->video_codec();
  SbMediaAudioCodec audio_codec = dmp_reader_->audio_codec();
  const SbMediaAudioSampleInfo* audio_sample_info = NULL;

  if (test_media_type_ == kSbMediaTypeAudio) {
    SB_DCHECK(audio_codec != kSbMediaAudioCodecNone);

    audio_sample_info = &dmp_reader_->audio_sample_info();
    video_codec = kSbMediaVideoCodecNone;
  } else {
    SB_DCHECK(video_codec != kSbMediaVideoCodecNone);

    audio_codec = kSbMediaAudioCodecNone;
  }

  player_ = CallSbPlayerCreate(
      fake_graphics_context_provider_.window(), video_codec, audio_codec,
      kSbDrmSystemInvalid, audio_sample_info, "", DummyDeallocateSampleFunc,
      DecoderStatusCallback, PlayerStatusCallback, ErrorCallback, this,
      output_mode_, fake_graphics_context_provider_.decoder_target_provider());

  ASSERT_TRUE(SbPlayerIsValid(player_));

  InitializePlayer();
}

void SbPlayerWriteSampleTest::TearDown() {
  if (!SbPlayerIsValid(player_)) {
    return;
  }

  ASSERT_FALSE(destroy_player_called_);
  destroy_player_called_ = true;
  SbPlayerDestroy(player_);

  // We expect the event to be sent already.
  ASSERT_NO_FATAL_FAILURE(WaitForPlayerState(kSbPlayerStateDestroyed, 0));
  ASSERT_FALSE(error_occurred_.load());
}

// static
void SbPlayerWriteSampleTest::DecoderStatusCallback(SbPlayer player,
                                                    void* context,
                                                    SbMediaType type,
                                                    SbPlayerDecoderState state,
                                                    int ticket) {
  SbPlayerWriteSampleTest* sb_player_write_sample_test =
      static_cast<SbPlayerWriteSampleTest*>(context);
  sb_player_write_sample_test->OnDecoderState(player, type, state, ticket);
}

// static
void SbPlayerWriteSampleTest::PlayerStatusCallback(SbPlayer player,
                                                   void* context,
                                                   SbPlayerState state,
                                                   int ticket) {
  SbPlayerWriteSampleTest* sb_player_write_sample_test =
      static_cast<SbPlayerWriteSampleTest*>(context);
  sb_player_write_sample_test->OnPlayerState(player, state, ticket);
}

// static
void SbPlayerWriteSampleTest::ErrorCallback(SbPlayer player,
                                            void* context,
                                            SbPlayerError error,
                                            const char* message) {
  SbPlayerWriteSampleTest* sb_player_write_sample_test =
      static_cast<SbPlayerWriteSampleTest*>(context);
  sb_player_write_sample_test->OnError(player, error, message);
}

void SbPlayerWriteSampleTest::InitializePlayer() {
  ASSERT_FALSE(destroy_player_called_);
  ASSERT_NO_FATAL_FAILURE(WaitForPlayerState(kSbPlayerStateInitialized));
  Seek(0);
  SbPlayerSetPlaybackRate(player_, 1.0);
  SbPlayerSetVolume(player_, 1.0);
}

void SbPlayerWriteSampleTest::PrepareForSeek() {
  ASSERT_FALSE(destroy_player_called_);
  ASSERT_FALSE(HasReceivedPlayerState(kSbPlayerStateDestroyed));
  ASSERT_TRUE(HasReceivedPlayerState(kSbPlayerStateInitialized));
  player_state_set_.clear();
  player_state_set_.insert(kSbPlayerStateInitialized);
  ticket_++;
}

void SbPlayerWriteSampleTest::Seek(const SbTime time) {
  PrepareForSeek();
  SbPlayerSeek2(player_, time, ticket_);
  ASSERT_NO_FATAL_FAILURE(WaitForDecoderStateNeedsData());
  ASSERT_TRUE(decoder_state_queue_.empty());
}

void SbPlayerWriteSampleTest::GetDecodeTargetWhenSupported() {
  if (destroy_player_called_) {
    return;
  }
#if SB_HAS(GLES2)
  fake_graphics_context_provider_.RunOnGlesContextThread([&]() {
    ASSERT_TRUE(SbPlayerIsValid(player_));
    if (output_mode_ != kSbPlayerOutputModeDecodeToTexture) {
      ASSERT_EQ(SbPlayerGetCurrentFrame(player_), kSbDecodeTargetInvalid);
      return;
    }
    ASSERT_EQ(output_mode_, kSbPlayerOutputModeDecodeToTexture);
    SbDecodeTarget frame = SbPlayerGetCurrentFrame(player_);
    if (SbDecodeTargetIsValid(frame)) {
      SbDecodeTargetRelease(frame);
    }
  });
#endif  // SB_HAS(GLES2)
}

void SbPlayerWriteSampleTest::OnDecoderState(SbPlayer player,
                                             SbMediaType type,
                                             SbPlayerDecoderState state,
                                             int ticket) {
  switch (state) {
    case kSbPlayerDecoderStateNeedsData:
      callback_event_queue_.Put(CallbackEvent(player, state, ticket));
      break;
  }
}

void SbPlayerWriteSampleTest::OnPlayerState(SbPlayer player,
                                            SbPlayerState state,
                                            int ticket) {
  callback_event_queue_.Put(CallbackEvent(player, state, ticket));
}

void SbPlayerWriteSampleTest::OnError(SbPlayer player,
                                      SbPlayerError error,
                                      const char* message) {
  SB_LOG(ERROR) << FormatString("Got SbPlayerError %d with message '%s'", error,
                                message != NULL ? message : "");
  error_occurred_.exchange(true);
}

void SbPlayerWriteSampleTest::WaitForDecoderStateNeedsData(
    const SbTime timeout) {
  optional<SbPlayerDecoderState> received_state;
  SbTimeMonotonic start = SbTimeGetMonotonicNow();
  do {
    ASSERT_FALSE(error_occurred_.load());
    GetDecodeTargetWhenSupported();
    ASSERT_NO_FATAL_FAILURE(TryProcessCallbackEvents(
        std::min(timeout, kDefaultWaitForCallbackEventTimeout)));
    if (decoder_state_queue_.empty()) {
      continue;
    }
    received_state = decoder_state_queue_.front();
    decoder_state_queue_.pop_front();
    if (received_state.value() == kSbPlayerDecoderStateNeedsData) {
      break;
    }
  } while (SbTimeGetMonotonicNow() - start < timeout);

  ASSERT_TRUE(received_state.has_engaged()) << "Did not receive any states.";
  ASSERT_EQ(kSbPlayerDecoderStateNeedsData, received_state.value())
      << "Did not receive expected state.";
}

void SbPlayerWriteSampleTest::WaitForPlayerState(
    const SbPlayerState desired_state,
    const SbTime timeout) {
  SbTimeMonotonic start = SbTimeGetMonotonicNow();
  do {
    ASSERT_FALSE(error_occurred_.load());
    GetDecodeTargetWhenSupported();
    ASSERT_NO_FATAL_FAILURE(TryProcessCallbackEvents(
        std::min(timeout, kDefaultWaitForCallbackEventTimeout)));
    if (HasReceivedPlayerState(desired_state)) {
      break;
    }
  } while (SbTimeGetMonotonicNow() - start < timeout);
  ASSERT_TRUE(HasReceivedPlayerState(desired_state))
      << "Did not received expected state.";
}

void SbPlayerWriteSampleTest::WriteSingleInput(size_t index) {
  ASSERT_FALSE(destroy_player_called_);
  ASSERT_LT(index, GetNumBuffers());
  SbPlayerSampleInfo sample_info =
      dmp_reader_->GetPlayerSampleInfo(test_media_type_, index);
  SbPlayerWriteSample2(player_, test_media_type_, &sample_info, 1);
}

void SbPlayerWriteSampleTest::WriteEndOfStream() {
  ASSERT_FALSE(destroy_player_called_);
  ASSERT_FALSE(end_of_stream_written_);
  end_of_stream_written_ = true;
  SbPlayerWriteEndOfStream(player_, test_media_type_);
}

void SbPlayerWriteSampleTest::WriteMultipleInputs(size_t start_index,
                                                  size_t num_inputs_to_write) {
  SB_DCHECK(num_inputs_to_write > 0);
  SB_DCHECK(start_index < GetNumBuffers());

  ASSERT_NO_FATAL_FAILURE(WriteSingleInput(start_index));
  ++start_index;
  --num_inputs_to_write;

  while (num_inputs_to_write > 0 && start_index < GetNumBuffers()) {
    ASSERT_NO_FATAL_FAILURE(WaitForDecoderStateNeedsData());
    ASSERT_NO_FATAL_FAILURE(WriteSingleInput(start_index));
    ++start_index;
    --num_inputs_to_write;
  }
}

void SbPlayerWriteSampleTest::DrainOutputs() {
  ASSERT_TRUE(end_of_stream_written_);
  ASSERT_NO_FATAL_FAILURE(WaitForPlayerState(kSbPlayerStateEndOfStream));
  // We should not get any new decoder events after end of stream.
  ASSERT_TRUE(decoder_state_queue_.empty());
}

int SbPlayerWriteSampleTest::GetNumBuffers() const {
  return test_media_type_ == kSbMediaTypeAudio
             ? dmp_reader_->number_of_audio_buffers()
             : dmp_reader_->number_of_video_buffers();
}

void SbPlayerWriteSampleTest::AssertPlayerStateIsValid(
    SbPlayerState state) const {
  // Note: it is possible to receive the same state that has been previously
  // received in the case of multiple Seek() calls. Prior to any Seek commands
  // issued in this test, we should reset the |player_state_set_| member.
  ASSERT_FALSE(HasReceivedPlayerState(state));

  switch (state) {
    case kSbPlayerStateInitialized:
      // No other states have been received before getting Initialized.
      ASSERT_TRUE(player_state_set_.empty());
      break;
    case kSbPlayerStatePrerolling:
      ASSERT_TRUE(HasReceivedPlayerState(kSbPlayerStateInitialized));
      ASSERT_FALSE(HasReceivedPlayerState(kSbPlayerStateDestroyed));
      break;
    case kSbPlayerStatePresenting:
      ASSERT_TRUE(HasReceivedPlayerState(kSbPlayerStatePrerolling));
      ASSERT_FALSE(HasReceivedPlayerState(kSbPlayerStateDestroyed));
      break;
    case kSbPlayerStateEndOfStream:
      ASSERT_TRUE(HasReceivedPlayerState(kSbPlayerStateInitialized));
      ASSERT_TRUE(HasReceivedPlayerState(kSbPlayerStatePrerolling));
      ASSERT_FALSE(HasReceivedPlayerState(kSbPlayerStateDestroyed));
      break;
    case kSbPlayerStateDestroyed:
      // Nothing stops the user of the player from destroying the player during
      // any of the previous states.
      ASSERT_TRUE(destroy_player_called_);
      break;
  }
}

void SbPlayerWriteSampleTest::TryProcessCallbackEvents(SbTime timeout) {
  for (;;) {
    auto event = callback_event_queue_.GetTimed(timeout);
    if (!event.HasStateUpdate()) {
      break;
    }
    if (event.ticket != ticket_) {
      continue;
    }
    ASSERT_EQ(event.player, player_);
    SB_DCHECK(event.decoder_state.has_engaged() ^
              event.player_state.has_engaged());
    if (event.decoder_state.has_engaged()) {
      // Callbacks may be in-flight at the time that the player is destroyed by
      // a call to |SbPlayerDestroy|. In this case, the callbacks are ignored.
      // However no new callbacks are expected after receiving the player status
      // |kSbPlayerStateDestroyed|.
      ASSERT_FALSE(HasReceivedPlayerState(kSbPlayerStateDestroyed));
      decoder_state_queue_.push_back(event.decoder_state.value());
      continue;
    }
    ASSERT_NO_FATAL_FAILURE(
        AssertPlayerStateIsValid(event.player_state.value()));
    player_state_set_.insert(event.player_state.value());
  }
}

TEST_P(SbPlayerWriteSampleTest, SeekAndDestroy) {
  PrepareForSeek();
  SbPlayerSeek2(player_, 1 * kSbTimeSecond, ticket_);
}

TEST_P(SbPlayerWriteSampleTest, NoInput) {
  WriteEndOfStream();
  DrainOutputs();
}

TEST_P(SbPlayerWriteSampleTest, SingleInput) {
  ASSERT_NO_FATAL_FAILURE(WriteSingleInput(0));
  ASSERT_NO_FATAL_FAILURE(WaitForDecoderStateNeedsData());
  WriteEndOfStream();
  DrainOutputs();
}

TEST_P(SbPlayerWriteSampleTest, MultipleInputs) {
  ASSERT_NO_FATAL_FAILURE(
      WriteMultipleInputs(0, std::min<size_t>(10, GetNumBuffers())));
  ASSERT_NO_FATAL_FAILURE(WaitForDecoderStateNeedsData());
  WriteEndOfStream();
  DrainOutputs();
}

INSTANTIATE_TEST_CASE_P(SbPlayerWriteSampleTests,
                        SbPlayerWriteSampleTest,
                        ValuesIn(GetSupportedSbPlayerTestConfigs()),
                        GetSbPlayerTestConfigName);

}  // namespace
}  // namespace nplb
}  // namespace starboard
