// Copyright 2014 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 <memory>

#include "base/basictypes.h"
#include "base/test/simple_test_tick_clock.h"
#include "cobalt/media/base/wall_clock_time_source.h"
#include "testing/gtest/include/gtest/gtest.h"

namespace cobalt {
namespace media {

class WallClockTimeSourceTest : public testing::Test {
 public:
  WallClockTimeSourceTest() : tick_clock_(new base::SimpleTestTickClock()) {
    time_source_.set_tick_clock_for_testing(tick_clock_.get());
    AdvanceTimeInSeconds(1);
  }
  ~WallClockTimeSourceTest() override {}

  void AdvanceTimeInSeconds(int seconds) {
    tick_clock_->Advance(base::TimeDelta::FromSeconds(seconds));
  }

  int CurrentMediaTimeInSeconds() {
    return time_source_.CurrentMediaTime().InSeconds();
  }

  void SetMediaTimeInSeconds(int seconds) {
    return time_source_.SetMediaTime(base::TimeDelta::FromSeconds(seconds));
  }

  base::TimeTicks ConvertMediaTime(base::TimeDelta timestamp,
                                   bool* is_time_moving) {
    std::vector<base::TimeTicks> wall_clock_times;
    *is_time_moving = time_source_.GetWallClockTimes(
        std::vector<base::TimeDelta>(1, timestamp), &wall_clock_times);
    return wall_clock_times[0];
  }

  bool IsWallClockNowForMediaTimeInSeconds(int seconds) {
    bool is_time_moving = false;
    return tick_clock_->NowTicks() ==
           ConvertMediaTime(base::TimeDelta::FromSeconds(seconds),
                            &is_time_moving);
  }

  bool IsTimeStopped() {
    bool is_time_moving = false;
    // Convert any random value, it shouldn't matter for this call.
    ConvertMediaTime(base::TimeDelta::FromSeconds(1), &is_time_moving);
    return !is_time_moving;
  }

 protected:
  WallClockTimeSource time_source_;
  std::unique_ptr<base::SimpleTestTickClock> tick_clock_;

  DISALLOW_COPY_AND_ASSIGN(WallClockTimeSourceTest);
};

TEST_F(WallClockTimeSourceTest, InitialTimeIsZero) {
  EXPECT_EQ(0, CurrentMediaTimeInSeconds());
  EXPECT_TRUE(IsTimeStopped());
}

TEST_F(WallClockTimeSourceTest, InitialTimeIsNotTicking) {
  EXPECT_EQ(0, CurrentMediaTimeInSeconds());
  EXPECT_TRUE(IsTimeStopped());
  AdvanceTimeInSeconds(100);
  EXPECT_EQ(0, CurrentMediaTimeInSeconds());
  EXPECT_TRUE(IsTimeStopped());
}

TEST_F(WallClockTimeSourceTest, InitialPlaybackRateIsOne) {
  time_source_.StartTicking();

  EXPECT_EQ(0, CurrentMediaTimeInSeconds());
  EXPECT_TRUE(IsWallClockNowForMediaTimeInSeconds(0));
  AdvanceTimeInSeconds(100);
  EXPECT_EQ(100, CurrentMediaTimeInSeconds());
  EXPECT_TRUE(IsWallClockNowForMediaTimeInSeconds(100));
}

TEST_F(WallClockTimeSourceTest, SetMediaTime) {
  EXPECT_EQ(0, CurrentMediaTimeInSeconds());
  EXPECT_TRUE(IsTimeStopped());
  SetMediaTimeInSeconds(10);
  EXPECT_EQ(10, CurrentMediaTimeInSeconds());
  EXPECT_TRUE(IsTimeStopped());
  std::vector<base::TimeTicks> wall_clock_times;
  time_source_.GetWallClockTimes(std::vector<base::TimeDelta>(),
                                 &wall_clock_times);
  EXPECT_EQ(base::TimeTicks(), wall_clock_times[0]);
}

TEST_F(WallClockTimeSourceTest, SetPlaybackRate) {
  time_source_.StartTicking();

  time_source_.SetPlaybackRate(0.5);
  EXPECT_EQ(0, CurrentMediaTimeInSeconds());
  EXPECT_TRUE(IsWallClockNowForMediaTimeInSeconds(0));
  AdvanceTimeInSeconds(10);
  EXPECT_EQ(5, CurrentMediaTimeInSeconds());
  EXPECT_TRUE(IsWallClockNowForMediaTimeInSeconds(5));

  time_source_.SetPlaybackRate(2);
  EXPECT_EQ(5, CurrentMediaTimeInSeconds());
  EXPECT_TRUE(IsWallClockNowForMediaTimeInSeconds(5));
  AdvanceTimeInSeconds(10);
  EXPECT_EQ(25, CurrentMediaTimeInSeconds());
  EXPECT_TRUE(IsWallClockNowForMediaTimeInSeconds(25));
}

TEST_F(WallClockTimeSourceTest, StopTicking) {
  time_source_.StartTicking();

  EXPECT_EQ(0, CurrentMediaTimeInSeconds());
  EXPECT_TRUE(IsWallClockNowForMediaTimeInSeconds(0));
  AdvanceTimeInSeconds(10);
  EXPECT_EQ(10, CurrentMediaTimeInSeconds());
  EXPECT_TRUE(IsWallClockNowForMediaTimeInSeconds(10));

  time_source_.StopTicking();

  AdvanceTimeInSeconds(10);
  EXPECT_EQ(10, CurrentMediaTimeInSeconds());
  EXPECT_TRUE(IsTimeStopped());
}

TEST_F(WallClockTimeSourceTest, ConvertsTimestampsWhenStopped) {
  const base::TimeDelta kOneSecond = base::TimeDelta::FromSeconds(1);
  bool is_time_moving = false;
  EXPECT_EQ(base::TimeTicks(),
            ConvertMediaTime(base::TimeDelta(), &is_time_moving));
  EXPECT_FALSE(is_time_moving);
  EXPECT_NE(base::TimeTicks(), ConvertMediaTime(kOneSecond, &is_time_moving));
  EXPECT_FALSE(is_time_moving);
  time_source_.StartTicking();
  time_source_.StopTicking();
  EXPECT_EQ(tick_clock_->NowTicks(),
            ConvertMediaTime(base::TimeDelta(), &is_time_moving));
  EXPECT_FALSE(is_time_moving);
  EXPECT_EQ(tick_clock_->NowTicks() + kOneSecond,
            ConvertMediaTime(kOneSecond, &is_time_moving));
  EXPECT_FALSE(is_time_moving);
}

TEST_F(WallClockTimeSourceTest, EmptyMediaTimestampsReturnMediaWallClockTime) {
  std::vector<base::TimeTicks> wall_clock_times;
  bool is_time_moving = time_source_.GetWallClockTimes(
      std::vector<base::TimeDelta>(), &wall_clock_times);
  EXPECT_FALSE(is_time_moving);
  EXPECT_EQ(base::TimeTicks(), wall_clock_times[0]);

  wall_clock_times.clear();
  time_source_.StartTicking();
  is_time_moving = time_source_.GetWallClockTimes(
      std::vector<base::TimeDelta>(), &wall_clock_times);
  EXPECT_TRUE(is_time_moving);
  EXPECT_EQ(tick_clock_->NowTicks(), wall_clock_times[0]);

  wall_clock_times.clear();
  time_source_.StopTicking();
  is_time_moving = time_source_.GetWallClockTimes(
      std::vector<base::TimeDelta>(), &wall_clock_times);
  EXPECT_FALSE(is_time_moving);
  EXPECT_EQ(tick_clock_->NowTicks(), wall_clock_times[0]);

  // Setting media time should clear reference time.
  SetMediaTimeInSeconds(5);
  wall_clock_times.clear();
  is_time_moving = time_source_.GetWallClockTimes(
      std::vector<base::TimeDelta>(), &wall_clock_times);
  EXPECT_FALSE(is_time_moving);
  EXPECT_EQ(base::TimeTicks(), wall_clock_times[0]);
}

}  // namespace media
}  // namespace cobalt
