// Copyright 2020 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 "media/mojo/services/playback_events_recorder.h"

#include "base/metrics/user_metrics.h"
#include "base/test/simple_test_tick_clock.h"
#include "base/test/task_environment.h"
#include "testing/gtest/include/gtest/gtest.h"

namespace media {

constexpr base::TimeDelta kSecond = base::Seconds(1);

class PlaybackEventsRecorderTest : public testing::Test {
 public:
  PlaybackEventsRecorderTest()
      : task_environment_(base::test::TaskEnvironment::MainThreadType::IO,
                          base::test::TaskEnvironment::TimeSource::MOCK_TIME) {
    time_base_ = base::TimeTicks::Now();

    base::SetRecordActionTaskRunner(
        task_environment_.GetMainThreadTaskRunner());
    action_callback_ = base::BindRepeating(
        &PlaybackEventsRecorderTest::OnAction, base::Unretained(this));
    base::AddActionCallback(action_callback_);
  }

  ~PlaybackEventsRecorderTest() override {
    base::RemoveActionCallback(action_callback_);
  }

 protected:
  struct Event {
    base::TimeTicks time;
    std::string name;

    bool operator==(const Event& other) const {
      return time == other.time && name == other.name;
    }
  };

  void OnAction(const std::string& name, base::TimeTicks time) {
    recorded_events_.push_back({time, name});
  }

  void ExpectEvents(const std::vector<Event>& expected) {
    EXPECT_EQ(recorded_events_.size(), expected.size());
    size_t end = std::min(recorded_events_.size(), expected.size());
    for (size_t i = 0; i < end; ++i) {
      SCOPED_TRACE(i);
      EXPECT_EQ(recorded_events_[i].time, expected[i].time);
      EXPECT_EQ(recorded_events_[i].name, expected[i].name);
    }
  }

  base::test::TaskEnvironment task_environment_;

  base::SimpleTestTickClock test_clock_;
  base::TimeTicks time_base_;

  base::ActionCallback action_callback_;
  PlaybackEventsRecorder recorder_;
  std::vector<Event> recorded_events_;
};

TEST_F(PlaybackEventsRecorderTest, PlayPause) {
  recorder_.OnNaturalSizeChanged(gfx::Size(640, 480));
  recorder_.OnPlaying();
  task_environment_.AdvanceClock(2 * kSecond);
  recorder_.OnPaused();

  ExpectEvents({
      // VideoResolution value should be encoded as (640 << 16) + 480.
      {time_base_, "WebEngine.Media.VideoResolution:41943520"},
      {time_base_, "WebEngine.Media.Playing"},
      {time_base_ + 2 * kSecond, "WebEngine.Media.Pause"},
  });
}

TEST_F(PlaybackEventsRecorderTest, Error) {
  recorder_.OnPlaying();
  task_environment_.AdvanceClock(2 * kSecond);
  recorder_.OnError(PIPELINE_ERROR_DECODE);

  ExpectEvents({
      {time_base_, "WebEngine.Media.Playing"},
      {time_base_ + 2 * kSecond, "WebEngine.Media.Error:3"},
  });
}

TEST_F(PlaybackEventsRecorderTest, Buffering) {
  recorder_.OnPlaying();
  recorder_.OnBufferingComplete();
  task_environment_.AdvanceClock(2 * kSecond);
  recorder_.OnBuffering();
  task_environment_.AdvanceClock(3 * kSecond);
  recorder_.OnBufferingComplete();

  ExpectEvents({
      {time_base_, "WebEngine.Media.Playing"},
      {time_base_ + 5 * kSecond,
       "WebEngine.Media.PlayTimeBeforeAutoPause:2000"},
      {time_base_ + 5 * kSecond, "WebEngine.Media.AutoPauseTime:3000"},
  });
}

TEST_F(PlaybackEventsRecorderTest, Bitrate) {
  recorder_.OnPlaying();
  recorder_.OnBufferingComplete();

  PipelineStatistics stats;
  recorder_.OnPipelineStatistics(stats);

  for (int i = 0; i < 5; ++i) {
    stats.audio_bytes_decoded += 5000;
    stats.video_bytes_decoded += 10000;

    task_environment_.AdvanceClock(kSecond);
    recorder_.OnPipelineStatistics(stats);
  }

  ExpectEvents({
      {time_base_, "WebEngine.Media.Playing"},
      {time_base_ + 5 * kSecond, "WebEngine.Media.AudioBitrate:40"},
      {time_base_ + 5 * kSecond, "WebEngine.Media.VideoBitrate:80"},
  });
}

TEST_F(PlaybackEventsRecorderTest, BitrateAfterPause) {
  recorder_.OnPlaying();
  recorder_.OnBufferingComplete();

  PipelineStatistics stats;
  recorder_.OnPipelineStatistics(stats);

  for (int i = 0; i < 3; ++i) {
    stats.audio_bytes_decoded += 5000;
    stats.video_bytes_decoded += 10000;

    task_environment_.AdvanceClock(kSecond);
    recorder_.OnPipelineStatistics(stats);
  }

  recorder_.OnPaused();
  task_environment_.AdvanceClock(10 * kSecond);
  recorder_.OnPlaying();

  for (int i = 0; i < 3; ++i) {
    stats.audio_bytes_decoded += 5000;
    stats.video_bytes_decoded += 10000;

    task_environment_.AdvanceClock(kSecond);
    recorder_.OnPipelineStatistics(stats);
  }

  ExpectEvents({
      {time_base_, "WebEngine.Media.Playing"},
      {time_base_ + 3 * kSecond, "WebEngine.Media.Pause"},
      {time_base_ + 13 * kSecond, "WebEngine.Media.Playing"},
      {time_base_ + 16 * kSecond, "WebEngine.Media.AudioBitrate:40"},
      {time_base_ + 16 * kSecond, "WebEngine.Media.VideoBitrate:80"},
  });
}

TEST_F(PlaybackEventsRecorderTest, BitrateAfterBuffering) {
  recorder_.OnPlaying();
  recorder_.OnBufferingComplete();

  PipelineStatistics stats;
  recorder_.OnPipelineStatistics(stats);

  for (int i = 0; i < 3; ++i) {
    stats.audio_bytes_decoded += 5000;
    stats.video_bytes_decoded += 10000;

    task_environment_.AdvanceClock(kSecond);
    recorder_.OnPipelineStatistics(stats);
  }

  recorder_.OnBuffering();
  task_environment_.AdvanceClock(10 * kSecond);
  recorder_.OnBufferingComplete();

  for (int i = 0; i < 3; ++i) {
    stats.audio_bytes_decoded += 5000;
    stats.video_bytes_decoded += 10000;

    task_environment_.AdvanceClock(kSecond);
    recorder_.OnPipelineStatistics(stats);
  }

  ExpectEvents({
      {time_base_, "WebEngine.Media.Playing"},
      {time_base_ + 13 * kSecond,
       "WebEngine.Media.PlayTimeBeforeAutoPause:3000"},
      {time_base_ + 13 * kSecond, "WebEngine.Media.AutoPauseTime:10000"},
      {time_base_ + 16 * kSecond, "WebEngine.Media.AudioBitrate:40"},
      {time_base_ + 16 * kSecond, "WebEngine.Media.VideoBitrate:80"},
  });
}
}  // namespace media
