// Copyright 2019 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 "starboard/media.h"

#include "starboard/common/optional.h"
#include "starboard/common/spin_lock.h"
#include "starboard/configuration_constants.h"
#include "starboard/nplb/player_creation_param_helpers.h"
#include "starboard/nplb/player_test_util.h"
#include "starboard/player.h"
#include "starboard/shared/starboard/media/media_support_internal.h"
#include "starboard/shared/starboard/media/media_util.h"
#include "starboard/shared/starboard/player/video_dmp_reader.h"
#include "starboard/testing/fake_graphics_context_provider.h"
#include "testing/gtest/include/gtest/gtest.h"

namespace starboard {
namespace nplb {
namespace {

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

const SbTime kDuration = kSbTimeSecond / 2;
const SbTime kSmallWaitInterval = 10 * kSbTimeMillisecond;

class SbMediaSetAudioWriteDurationTest
    : public ::testing::TestWithParam<const char*> {
 public:
  SbMediaSetAudioWriteDurationTest()
      : dmp_reader_(ResolveTestFileName(GetParam()).c_str()) {}

  void TryToWritePendingSample() {
    {
      starboard::ScopedSpinLock lock(&pending_decoder_status_lock_);
      if (!pending_decoder_status_.has_engaged()) {
        return;
      }
    }

    // If we have played the full duration required, then stop.
    if ((last_input_timestamp_ - first_input_timestamp_) >= total_duration_) {
      return;
    }

    // Check if we're about to input too far beyond the current playback time.
    SbPlayerInfo2 info;
    SbPlayerGetInfo2(pending_decoder_status_->player, &info);
    if ((last_input_timestamp_ - info.current_media_timestamp) > kDuration) {
      // Postpone writing samples.
      return;
    }

    SbPlayerSampleInfo player_sample_info =
        dmp_reader_.GetPlayerSampleInfo(kSbMediaTypeAudio, index_++);

    SbPlayerSampleInfo sample_info = {};
    sample_info.buffer = player_sample_info.buffer;
    sample_info.buffer_size = player_sample_info.buffer_size;
    sample_info.timestamp = player_sample_info.timestamp;
    sample_info.drm_info = NULL;
    sample_info.type = kSbMediaTypeAudio;
    sample_info.audio_sample_info = dmp_reader_.audio_sample_info();

    SbPlayer player = pending_decoder_status_->player;
    SbMediaType type = pending_decoder_status_->type;
    int ticket = pending_decoder_status_->ticket;
    {
      starboard::ScopedSpinLock lock(&pending_decoder_status_lock_);
      pending_decoder_status_ = nullopt;
    }

    SbPlayerWriteSample2(player, kSbMediaTypeAudio, &sample_info, 1);
    last_input_timestamp_ = player_sample_info.timestamp;
  }

  void PlayerStatus(SbPlayer player, SbPlayerState state, int ticket) {
    player_state_ = state;
  }

  void StorePendingDecoderStatus(SbPlayer player,
                                 SbMediaType type,
                                 int ticket) {
    starboard::ScopedSpinLock lock(&pending_decoder_status_lock_);
    SB_DCHECK(!pending_decoder_status_.has_engaged());
    PendingDecoderStatus pending_decoder_status = {};
    pending_decoder_status.player = player;
    pending_decoder_status.type = type;
    pending_decoder_status.ticket = ticket;
    pending_decoder_status_ = pending_decoder_status;
  }

  SbPlayer CreatePlayer() {
    SbMediaAudioSampleInfo audio_sample_info = dmp_reader_.audio_sample_info();
    SbMediaAudioCodec kAudioCodec = dmp_reader_.audio_codec();
    SbDrmSystem kDrmSystem = kSbDrmSystemInvalid;

    last_input_timestamp_ =
        dmp_reader_.GetPlayerSampleInfo(kSbMediaTypeAudio, 0).timestamp;
    first_input_timestamp_ = last_input_timestamp_;

    SbPlayerCreationParam creation_param = CreatePlayerCreationParam(
        audio_sample_info.codec, kSbMediaVideoCodecNone);
    creation_param.audio_sample_info = audio_sample_info;
    creation_param.output_mode =
        SbPlayerGetPreferredOutputMode(&creation_param);
    EXPECT_NE(creation_param.output_mode, kSbPlayerOutputModeInvalid);

    SbPlayer player = SbPlayerCreate(
        fake_graphics_context_provider_.window(), &creation_param,
        DummyDeallocateSampleFunc, DecoderStatusFunc, PlayerStatusFunc,
        DummyErrorFunc, this /* context */,
        fake_graphics_context_provider_.decoder_target_provider());

    EXPECT_TRUE(SbPlayerIsValid(player));
    return player;
  }

  void WaitForPlayerState(SbPlayerState desired_state) {
    SbTime start_of_wait = SbTimeGetMonotonicNow();
    const SbTime kMaxWaitTime = 3 * kSbTimeSecond;
    while (player_state_ != desired_state &&
           (SbTimeGetMonotonicNow() - start_of_wait) < kMaxWaitTime) {
      SbThreadSleep(kSmallWaitInterval);
      TryToWritePendingSample();
    }
    ASSERT_EQ(desired_state, player_state_);
  }

 protected:
  struct PendingDecoderStatus {
    SbPlayer player;
    SbMediaType type;
    int ticket;
  };

  FakeGraphicsContextProvider fake_graphics_context_provider_;
  VideoDmpReader dmp_reader_;
  SbPlayerState player_state_ = kSbPlayerStateInitialized;
  SbTime last_input_timestamp_ = 0;
  SbTime first_input_timestamp_ = 0;
  int index_ = 0;
  SbTime total_duration_ = kDuration;
  // Guard access to |pending_decoder_status_|.
  mutable SbAtomic32 pending_decoder_status_lock_ =
      starboard::kSpinLockStateReleased;
  optional<PendingDecoderStatus> pending_decoder_status_;

 private:
  static void DecoderStatusFunc(SbPlayer player,
                                void* context,
                                SbMediaType type,
                                SbPlayerDecoderState state,
                                int ticket) {
    if (state != kSbPlayerDecoderStateNeedsData) {
      return;
    }
    static_cast<SbMediaSetAudioWriteDurationTest*>(context)
        ->StorePendingDecoderStatus(player, type, ticket);
  }

  static void PlayerStatusFunc(SbPlayer player,
                               void* context,
                               SbPlayerState state,
                               int ticket) {
    static_cast<SbMediaSetAudioWriteDurationTest*>(context)->PlayerStatus(
        player, state, ticket);
  }
};

TEST_P(SbMediaSetAudioWriteDurationTest, WriteLimitedInput) {
  ASSERT_NE(dmp_reader_.audio_codec(), kSbMediaAudioCodecNone);
  ASSERT_GT(dmp_reader_.number_of_audio_buffers(), 0);

  SbMediaSetAudioWriteDuration(kDuration);

  SbPlayer player = CreatePlayer();
  WaitForPlayerState(kSbPlayerStateInitialized);

  // Seek to preroll.
  SbPlayerSeek2(player, first_input_timestamp_, /* ticket */ 1);

  WaitForPlayerState(kSbPlayerStatePresenting);

  // Wait until the playback time is > 0.
  const SbTime kMaxWaitTime = 5 * kSbTimeSecond;
  SbTime start_of_wait = SbTimeGetMonotonicNow();
  SbPlayerInfo2 info = {};

  while (SbTimeGetMonotonicNow() - start_of_wait < kMaxWaitTime &&
         info.current_media_timestamp == 0) {
    SbThreadSleep(kSbTimeMillisecond * 500);
    SbPlayerGetInfo2(player, &info);
  }

  EXPECT_GT(info.current_media_timestamp, 0);

  SbPlayerDestroy(player);
}

TEST_P(SbMediaSetAudioWriteDurationTest, WriteContinuedLimitedInput) {
  ASSERT_NE(dmp_reader_.audio_codec(), kSbMediaAudioCodecNone);
  ASSERT_GT(dmp_reader_.number_of_audio_buffers(), 0);

  SbMediaSetAudioWriteDuration(kDuration);

  // This directly impacts the runtime of the test.
  total_duration_ = 15 * kSbTimeSecond;

  SbPlayer player = CreatePlayer();
  WaitForPlayerState(kSbPlayerStateInitialized);

  // Seek to preroll.
  SbPlayerSeek2(player, first_input_timestamp_, /* ticket */ 1);

  WaitForPlayerState(kSbPlayerStatePresenting);

  // Wait for the player to play far enough. It may not play all the way to
  // the end, but it should leave off no more than |kDuration|.
  SbTime min_ending_playback_time = total_duration_ - kDuration;
  SbTime start_of_wait = SbTimeGetMonotonicNow();
  const SbTime kMaxWaitTime = total_duration_ + 5 * kSbTimeSecond;
  SbPlayerInfo2 info;
  SbPlayerGetInfo2(player, &info);
  while (info.current_media_timestamp < min_ending_playback_time &&
         (SbTimeGetMonotonicNow() - start_of_wait) < kMaxWaitTime) {
    SbPlayerGetInfo2(player, &info);
    SbThreadSleep(kSmallWaitInterval);
    TryToWritePendingSample();
  }
  EXPECT_GE(info.current_media_timestamp, min_ending_playback_time);
  SbPlayerDestroy(player);
}

std::vector<const char*> GetSupportedTests() {
  const char* kFilenames[] = {"beneath_the_canopy_aac_stereo.dmp",
                              "beneath_the_canopy_opus_stereo.dmp"};

  static std::vector<const char*> test_params;

  if (!test_params.empty()) {
    return test_params;
  }

  for (auto filename : kFilenames) {
    VideoDmpReader dmp_reader(ResolveTestFileName(filename).c_str());
    SB_DCHECK(dmp_reader.number_of_audio_buffers() > 0);

    const SbMediaAudioSampleInfo* audio_sample_info =
        &dmp_reader.audio_sample_info();
    if (SbMediaIsAudioSupported(dmp_reader.audio_codec(), nullptr,
                                dmp_reader.audio_bitrate())) {
      test_params.push_back(filename);
    }
  }
  SB_DCHECK(!test_params.empty());
  return test_params;
}

INSTANTIATE_TEST_CASE_P(SbMediaSetAudioWriteDurationTests,
                        SbMediaSetAudioWriteDurationTest,
                        ValuesIn(GetSupportedTests()));
}  // namespace
}  // namespace nplb
}  // namespace starboard
