// 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/shared/starboard/player/filter/video_frame_cadence_pattern_generator.h"

#include <initializer_list>
#include <list>

#include "starboard/common/ref_counted.h"
#include "starboard/shared/starboard/player/filter/video_frame_internal.h"
#include "starboard/shared/starboard/player/filter/video_frame_rate_estimator.h"
#include "starboard/time.h"
#include "testing/gtest/include/gtest/gtest.h"

#if SB_HAS(PLAYER_FILTER_TESTS)

namespace starboard {
namespace shared {
namespace starboard {
namespace player {
namespace filter {
namespace testing {
namespace {

using Frames = VideoFrameRateEstimator::Frames;

auto kInvalidFrameRate = VideoFrameRateEstimator::kInvalidFrameRate;
constexpr double kFrameRateEpisilon = 0.05;

void SkipFrames(size_t frames_to_skip,
                Frames* frames,
                VideoFrameRateEstimator* estimator) {
  ASSERT_TRUE(frames);
  ASSERT_TRUE(estimator);
  ASSERT_LE(frames_to_skip, frames->size());

  while (frames_to_skip > 0) {
    --frames_to_skip;
    frames->pop_front();
    estimator->Update(*frames);
  }
}

Frames CreateFrames(const std::initializer_list<SbTime>& timestamps) {
  Frames frames;
  for (auto timestamp : timestamps) {
    frames.push_back(new VideoFrame(timestamp));
  }
  return frames;
}

TEST(VideoFrameRateEstimatorTest, Default) {
  VideoFrameRateEstimator estimator;
  EXPECT_EQ(estimator.frame_rate(), kInvalidFrameRate);

  estimator.Reset();
  EXPECT_EQ(estimator.frame_rate(), kInvalidFrameRate);
}

TEST(VideoFrameRateEstimatorTest, SingleFrame) {
  VideoFrameRateEstimator estimator;

  auto frames = CreateFrames({0});
  estimator.Update(frames);
  EXPECT_EQ(estimator.frame_rate(), kInvalidFrameRate);
}

TEST(VideoFrameRateEstimatorTest, TwoFrames) {
  VideoFrameRateEstimator estimator;

  auto frames = CreateFrames({0, 33333});
  estimator.Update(frames);
  ASSERT_NEAR(estimator.frame_rate(), 30, kFrameRateEpisilon);
}

TEST(VideoFrameRateEstimatorTest, Perfect30fps) {
  VideoFrameRateEstimator estimator;

  auto frames = CreateFrames({0, 33333, 66666, 100000, 133333, 166666, 200000});
  estimator.Update(frames);
  ASSERT_NEAR(estimator.frame_rate(), 30, kFrameRateEpisilon);
}

TEST(VideoFrameRateEstimatorTest, Imperfect30fps) {
  VideoFrameRateEstimator estimator;

  auto frames = CreateFrames({0, 34000, 67000, 100000, 133000, 167000, 200000});
  estimator.Update(frames);
  ASSERT_NEAR(estimator.frame_rate(), 30, kFrameRateEpisilon);
}

TEST(VideoFrameRateEstimatorTest, 60fps) {
  VideoFrameRateEstimator estimator;

  auto frames = CreateFrames({0, 16666, 33333, 50000, 66666, 83333, 100000});
  estimator.Update(frames);
  ASSERT_NEAR(estimator.frame_rate(), 60, kFrameRateEpisilon);
}

TEST(VideoFrameRateEstimatorTest, 60fpsStartedFromNonZero) {
  VideoFrameRateEstimator estimator;

  auto frames = CreateFrames({50000, 66666, 83333, 100000});
  estimator.Update(frames);
  ASSERT_NEAR(estimator.frame_rate(), 60, kFrameRateEpisilon);
}

TEST(VideoFrameRateEstimatorTest, 30fpsMultipleUpdates) {
  VideoFrameRateEstimator estimator;

  auto frames = CreateFrames({0, 33333, 66666, 100000, 133333, 166666, 200000});
  estimator.Update(frames);
  ASSERT_NEAR(estimator.frame_rate(), 30, kFrameRateEpisilon);

  SkipFrames(3, &frames, &estimator);
  ASSERT_NEAR(estimator.frame_rate(), 30, kFrameRateEpisilon);

  SkipFrames(4, &frames, &estimator);
  ASSERT_NEAR(estimator.frame_rate(), 30, kFrameRateEpisilon);

  ASSERT_TRUE(frames.empty());
  frames = CreateFrames({233333});
  estimator.Update(frames);
  ASSERT_NEAR(estimator.frame_rate(), 30, kFrameRateEpisilon);
  SkipFrames(1, &frames, &estimator);

  frames = CreateFrames({266666, 300000, 333333, 366666, 400000});
  estimator.Update(frames);
  ASSERT_NEAR(estimator.frame_rate(), 30, kFrameRateEpisilon);
}

TEST(VideoFrameRateEstimatorTest, 30fpsTo60fpsTransitionWithOneFrame) {
  VideoFrameRateEstimator estimator;

  auto frames = CreateFrames({0, 33333, 66666, 100000});
  estimator.Update(frames);
  ASSERT_NEAR(estimator.frame_rate(), 30, kFrameRateEpisilon);

  SkipFrames(3, &frames, &estimator);
  ASSERT_NEAR(estimator.frame_rate(), 30, kFrameRateEpisilon);

  SkipFrames(1, &frames, &estimator);

  frames = CreateFrames({116666});
  estimator.Update(frames);
  ASSERT_NEAR(estimator.frame_rate(), 60, kFrameRateEpisilon);
}

TEST(VideoFrameRateEstimatorTest, 30fpsTo60fpsTransitionWithReset) {
  VideoFrameRateEstimator estimator;

  auto frames = CreateFrames({0, 33333, 66666, 100000});
  estimator.Update(frames);
  ASSERT_NEAR(estimator.frame_rate(), 30, kFrameRateEpisilon);

  estimator.Reset();

  frames = CreateFrames({116666});
  estimator.Update(frames);
  EXPECT_EQ(estimator.frame_rate(), kInvalidFrameRate);

  frames = CreateFrames({116666, 133333});
  estimator.Update(frames);
  ASSERT_NEAR(estimator.frame_rate(), 60, kFrameRateEpisilon);
}

TEST(VideoFrameRateEstimatorTest, 30fpsTo60fpsTransitionWithMultipleFrames) {
  VideoFrameRateEstimator estimator;

  auto frames = CreateFrames({0, 33333, 66666, 100000, 116666, 133333, 150000});
  estimator.Update(frames);
  ASSERT_NEAR(estimator.frame_rate(), 30, kFrameRateEpisilon);

  SkipFrames(3, &frames, &estimator);
  ASSERT_NEAR(estimator.frame_rate(), 30, kFrameRateEpisilon);

  SkipFrames(1, &frames, &estimator);
  ASSERT_NEAR(estimator.frame_rate(), 60, kFrameRateEpisilon);

  SkipFrames(2, &frames, &estimator);
  ASSERT_NEAR(estimator.frame_rate(), 60, kFrameRateEpisilon);

  SkipFrames(1, &frames, &estimator);
  ASSERT_NEAR(estimator.frame_rate(), 60, kFrameRateEpisilon);
}

TEST(VideoFrameRateEstimatorTest, 30fpsTo60fpsTo30fps) {
  VideoFrameRateEstimator estimator;

  auto frames = CreateFrames({0, 33333, 66666, 100000, 116666, 150000});
  estimator.Update(frames);
  ASSERT_NEAR(estimator.frame_rate(), 30, kFrameRateEpisilon);

  SkipFrames(3, &frames, &estimator);
  ASSERT_NEAR(estimator.frame_rate(), 30, kFrameRateEpisilon);

  SkipFrames(1, &frames, &estimator);
  ASSERT_NEAR(estimator.frame_rate(), 60, kFrameRateEpisilon);

  SkipFrames(1, &frames, &estimator);
  ASSERT_NEAR(estimator.frame_rate(), 30, kFrameRateEpisilon);
}

TEST(VideoFrameRateEstimatorTest, EndOfStream) {
  VideoFrameRateEstimator estimator;

  auto frames = CreateFrames({0});
  frames.push_back(VideoFrame::CreateEOSFrame());
  estimator.Update(frames);
  ASSERT_EQ(estimator.frame_rate(), kInvalidFrameRate);

  frames = CreateFrames({0, 33333});
  frames.push_back(VideoFrame::CreateEOSFrame());
  estimator.Update(frames);
  ASSERT_NEAR(estimator.frame_rate(), 30, kFrameRateEpisilon);

  frames = CreateFrames({0, 33333, 66666, 100000, 116666, 150000});
  estimator.Update(frames);
  SkipFrames(5, &frames, &estimator);
  frames = CreateFrames({183333});
  frames.push_back(VideoFrame::CreateEOSFrame());
  estimator.Update(frames);
  SkipFrames(1, &frames, &estimator);
  estimator.Update(frames);
  ASSERT_NEAR(estimator.frame_rate(), 30, kFrameRateEpisilon);
}

}  // namespace
}  // namespace testing
}  // namespace filter
}  // namespace player
}  // namespace starboard
}  // namespace shared
}  // namespace starboard

#endif  // SB_HAS(PLAYER_FILTER_TESTS)
