// Copyright 2024 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/nplb/player_test_fixture.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 ::testing::ValuesIn;

typedef SbPlayerTestFixture::GroupedSamples GroupedSamples;
typedef testing::FakeGraphicsContextProvider FakeGraphicsContextProvider;

class SbPlayerGetMediaTimeTest
    : public ::testing::TestWithParam<SbPlayerTestConfig> {
 protected:
  FakeGraphicsContextProvider fake_graphics_context_provider_;
};

TEST_P(SbPlayerGetMediaTimeTest, SunnyDay) {
  const int64_t kDurationToPlay = 1'000'000;  // 1 second

  SbPlayerTestFixture player_fixture(GetParam(),
                                     &fake_graphics_context_provider_);
  if (HasFatalFailure()) {
    return;
  }

  int64_t media_time_before_write = player_fixture.GetCurrentMediaTime();
  ASSERT_EQ(media_time_before_write, 0);

  GroupedSamples samples;
  if (player_fixture.HasAudio()) {
    samples.AddAudioSamples(
        0, player_fixture.ConvertDurationToAudioBufferCount(kDurationToPlay));
    samples.AddAudioEOS();
  }
  if (player_fixture.HasVideo()) {
    samples.AddVideoSamples(
        0, player_fixture.ConvertDurationToVideoBufferCount(kDurationToPlay));
    samples.AddVideoEOS();
  }
  ASSERT_NO_FATAL_FAILURE(player_fixture.Write(samples));
  ASSERT_NO_FATAL_FAILURE(player_fixture.WaitForPlayerPresenting());

  int64_t start_system_time = CurrentMonotonicTime();
  int64_t start_media_time = player_fixture.GetCurrentMediaTime();

  ASSERT_NO_FATAL_FAILURE(player_fixture.WaitForPlayerEndOfStream());

  int64_t end_system_time = CurrentMonotonicTime();
  int64_t end_media_time = player_fixture.GetCurrentMediaTime();

  const int64_t kDurationDifferenceAllowance = 500'000;  // 500 ms
  EXPECT_NEAR(end_media_time, kDurationToPlay, kDurationDifferenceAllowance);
  EXPECT_NEAR(end_system_time - start_system_time + start_media_time,
              kDurationToPlay, kDurationDifferenceAllowance);

  SB_DLOG(INFO) << "The expected media time should be " << kDurationToPlay
                << ", the actual media time is " << end_media_time
                << ", with difference "
                << std::abs(end_media_time - kDurationToPlay) << ".";
  SB_DLOG(INFO) << "The expected total playing time should be "
                << kDurationToPlay << ", the actual playing time is "
                << end_system_time - start_system_time + start_media_time
                << ", with difference "
                << std::abs(end_system_time - start_system_time +
                            start_media_time - kDurationToPlay)
                << ".";
}

TEST_P(SbPlayerGetMediaTimeTest, TimeAfterSeek) {
  const int kSamplesToWrite = 8;

  SbPlayerTestFixture player_fixture(GetParam(),
                                     &fake_graphics_context_provider_);
  if (HasFatalFailure()) {
    return;
  }

  GroupedSamples samples;
  if (player_fixture.HasAudio()) {
    samples.AddAudioSamples(0, kSamplesToWrite);
    samples.AddAudioEOS();
  }
  if (player_fixture.HasVideo()) {
    samples.AddVideoSamples(0, kSamplesToWrite);
    samples.AddVideoEOS();
  }
  ASSERT_NO_FATAL_FAILURE(player_fixture.Write(samples));
  ASSERT_NO_FATAL_FAILURE(player_fixture.WaitForPlayerPresenting());

  const int64_t seek_to_time = 1'000'000;  // 1 second
  ASSERT_NO_FATAL_FAILURE(player_fixture.Seek(seek_to_time));

  const int64_t kDurationToPlay = 1'000'000;  // 1 second
  samples = GroupedSamples();
  if (player_fixture.HasAudio()) {
    samples.AddAudioSamples(
        0,
        player_fixture.ConvertDurationToAudioBufferCount(seek_to_time) +
            player_fixture.ConvertDurationToAudioBufferCount(kDurationToPlay));
    samples.AddAudioEOS();
  }
  if (player_fixture.HasVideo()) {
    samples.AddVideoSamples(
        0,
        player_fixture.ConvertDurationToVideoBufferCount(seek_to_time) +
            player_fixture.ConvertDurationToVideoBufferCount(kDurationToPlay));
    samples.AddVideoEOS();
  }
  ASSERT_NO_FATAL_FAILURE(player_fixture.Write(samples));
  ASSERT_NO_FATAL_FAILURE(player_fixture.WaitForPlayerPresenting());

  int64_t start_system_time = CurrentMonotonicTime();
  int64_t start_media_time = player_fixture.GetCurrentMediaTime();

  ASSERT_NO_FATAL_FAILURE(player_fixture.WaitForPlayerEndOfStream());

  int64_t end_system_time = CurrentMonotonicTime();
  int64_t end_media_time = player_fixture.GetCurrentMediaTime();

  const int64_t kDurationDifferenceAllowance = 500'000;  // 500 ms
  EXPECT_NEAR(end_media_time, kDurationToPlay + seek_to_time,
              kDurationDifferenceAllowance);
  EXPECT_NEAR(
      end_system_time - start_system_time + start_media_time - seek_to_time,
      kDurationToPlay, kDurationDifferenceAllowance);

  SB_DLOG(INFO) << "The expected media time should be "
                << kDurationToPlay + seek_to_time
                << ", the actual media time is " << end_media_time
                << ", with difference "
                << std::abs(end_media_time - kDurationToPlay - seek_to_time)
                << ".";
  SB_DLOG(INFO) << "The expected total playing time should be "
                << kDurationToPlay << ", the actual playing time is "
                << end_system_time - start_system_time + start_media_time -
                       seek_to_time
                << ", with difference "
                << std::abs(end_system_time - start_system_time +
                            start_media_time - seek_to_time - kDurationToPlay)
                << ".";
}

std::vector<SbPlayerTestConfig> GetSupportedTestConfigs() {
  static std::vector<SbPlayerTestConfig> supported_configs;
  if (supported_configs.size() > 0) {
    return supported_configs;
  }

  const std::vector<const char*>& key_systems = GetKeySystems();
  for (auto key_system : key_systems) {
    std::vector<SbPlayerTestConfig> configs =
        GetSupportedSbPlayerTestConfigs(key_system);
    supported_configs.insert(supported_configs.end(), configs.begin(),
                             configs.end());
  }
  return supported_configs;
}

INSTANTIATE_TEST_CASE_P(SbPlayerGetMediaTimeTests,
                        SbPlayerGetMediaTimeTest,
                        ValuesIn(GetSupportedTestConfigs()),
                        GetSbPlayerTestConfigName);

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