/*
 *  Copyright (c) 2021 The WebRTC project authors. All Rights Reserved.
 *
 *  Use of this source code is governed by a BSD-style license
 *  that can be found in the LICENSE file in the root of the source
 *  tree. An additional intellectual property rights grant can be found
 *  in the file PATENTS.  All contributing project authors may
 *  be found in the AUTHORS file in the root of the source tree.
 */

#include "test/pc/e2e/analyzer/video/default_video_quality_analyzer_frames_comparator.h"

#include <map>
#include <vector>

#include "api/test/create_frame_generator.h"
#include "api/units/timestamp.h"
#include "rtc_base/strings/string_builder.h"
#include "system_wrappers/include/clock.h"
#include "system_wrappers/include/sleep.h"
#include "test/gtest.h"
#include "test/pc/e2e/analyzer/video/default_video_quality_analyzer_cpu_measurer.h"
#include "test/pc/e2e/analyzer/video/default_video_quality_analyzer_shared_objects.h"

namespace webrtc {
namespace {

using StatsSample = ::webrtc::SamplesStatsCounter::StatsSample;

constexpr int kMaxFramesInFlightPerStream = 10;

DefaultVideoQualityAnalyzerOptions AnalyzerOptionsForTest() {
  DefaultVideoQualityAnalyzerOptions options;
  options.compute_psnr = false;
  options.compute_ssim = false;
  options.adjust_cropping_before_comparing_frames = false;
  options.max_frames_in_flight_per_stream_count = kMaxFramesInFlightPerStream;
  return options;
}

StreamCodecInfo Vp8CodecForOneFrame(uint16_t frame_id, Timestamp time) {
  StreamCodecInfo info;
  info.codec_name = "VP8";
  info.first_frame_id = frame_id;
  info.last_frame_id = frame_id;
  info.switched_on_at = time;
  info.switched_from_at = time;
  return info;
}

FrameStats FrameStatsWith10msDeltaBetweenPhasesAnd10x10Frame(
    Timestamp captured_time) {
  FrameStats frame_stats(captured_time);
  frame_stats.pre_encode_time = captured_time + TimeDelta::Millis(10);
  frame_stats.encoded_time = captured_time + TimeDelta::Millis(20);
  frame_stats.received_time = captured_time + TimeDelta::Millis(30);
  frame_stats.decode_start_time = captured_time + TimeDelta::Millis(40);
  frame_stats.decode_end_time = captured_time + TimeDelta::Millis(50);
  frame_stats.rendered_time = captured_time + TimeDelta::Millis(60);
  frame_stats.used_encoder = Vp8CodecForOneFrame(1, frame_stats.encoded_time);
  frame_stats.used_decoder =
      Vp8CodecForOneFrame(1, frame_stats.decode_end_time);
  frame_stats.rendered_frame_width = 10;
  frame_stats.rendered_frame_height = 10;
  return frame_stats;
}

FrameStats ShiftStatsOn(const FrameStats& stats, TimeDelta delta) {
  FrameStats frame_stats(stats.captured_time + delta);
  frame_stats.pre_encode_time = stats.pre_encode_time + delta;
  frame_stats.encoded_time = stats.encoded_time + delta;
  frame_stats.received_time = stats.received_time + delta;
  frame_stats.decode_start_time = stats.decode_start_time + delta;
  frame_stats.decode_end_time = stats.decode_end_time + delta;
  frame_stats.rendered_time = stats.rendered_time + delta;

  frame_stats.used_encoder = stats.used_encoder;
  frame_stats.used_decoder = stats.used_decoder;
  frame_stats.rendered_frame_width = stats.rendered_frame_width;
  frame_stats.rendered_frame_height = stats.rendered_frame_height;

  return frame_stats;
}

double GetFirstOrDie(const SamplesStatsCounter& counter) {
  EXPECT_TRUE(!counter.IsEmpty()) << "Counter has to be not empty";
  return counter.GetSamples()[0];
}

std::string ToString(const SamplesStatsCounter& counter) {
  rtc::StringBuilder out;
  for (const StatsSample& s : counter.GetTimedSamples()) {
    out << "{ time_ms=" << s.time.ms() << "; value=" << s.value << "}, ";
  }
  return out.str();
}

TEST(DefaultVideoQualityAnalyzerFramesComparatorTest,
     StatsPresentedAfterAddingOneComparison) {
  DefaultVideoQualityAnalyzerCpuMeasurer cpu_measurer;
  DefaultVideoQualityAnalyzerFramesComparator comparator(
      Clock::GetRealTimeClock(), cpu_measurer, AnalyzerOptionsForTest());

  Timestamp stream_start_time = Clock::GetRealTimeClock()->CurrentTime();
  size_t stream = 0;
  size_t sender = 0;
  size_t receiver = 1;
  size_t peers_count = 2;
  InternalStatsKey stats_key(stream, sender, receiver);

  FrameStats frame_stats =
      FrameStatsWith10msDeltaBetweenPhasesAnd10x10Frame(stream_start_time);

  comparator.Start(1);
  comparator.EnsureStatsForStream(stream, sender, peers_count,
                                  stream_start_time, stream_start_time);
  comparator.AddComparison(stats_key,
                           /*captured=*/absl::nullopt,
                           /*rendered=*/absl::nullopt,
                           FrameComparisonType::kRegular, frame_stats);
  comparator.Stop(/*last_rendered_frame_times=*/{});

  std::map<InternalStatsKey, StreamStats> stats = comparator.stream_stats();
  EXPECT_DOUBLE_EQ(GetFirstOrDie(stats.at(stats_key).transport_time_ms), 20.0);
  EXPECT_DOUBLE_EQ(
      GetFirstOrDie(stats.at(stats_key).total_delay_incl_transport_ms), 60.0);
  EXPECT_DOUBLE_EQ(GetFirstOrDie(stats.at(stats_key).encode_time_ms), 10.0);
  EXPECT_DOUBLE_EQ(GetFirstOrDie(stats.at(stats_key).decode_time_ms), 10.0);
  EXPECT_DOUBLE_EQ(GetFirstOrDie(stats.at(stats_key).receive_to_render_time_ms),
                   30.0);
  EXPECT_DOUBLE_EQ(
      GetFirstOrDie(stats.at(stats_key).resolution_of_rendered_frame), 100.0);
}

TEST(DefaultVideoQualityAnalyzerFramesComparatorTest,
     MultiFrameStatsPresentedAfterAddingTwoComparisonWith10msDelay) {
  DefaultVideoQualityAnalyzerCpuMeasurer cpu_measurer;
  DefaultVideoQualityAnalyzerFramesComparator comparator(
      Clock::GetRealTimeClock(), cpu_measurer, AnalyzerOptionsForTest());

  Timestamp stream_start_time = Clock::GetRealTimeClock()->CurrentTime();
  size_t stream = 0;
  size_t sender = 0;
  size_t receiver = 1;
  size_t peers_count = 2;
  InternalStatsKey stats_key(stream, sender, receiver);

  FrameStats frame_stats1 =
      FrameStatsWith10msDeltaBetweenPhasesAnd10x10Frame(stream_start_time);
  FrameStats frame_stats2 = FrameStatsWith10msDeltaBetweenPhasesAnd10x10Frame(
      stream_start_time + TimeDelta::Millis(15));
  frame_stats2.prev_frame_rendered_time = frame_stats1.rendered_time;

  comparator.Start(1);
  comparator.EnsureStatsForStream(stream, sender, peers_count,
                                  stream_start_time, stream_start_time);
  comparator.AddComparison(stats_key,
                           /*captured=*/absl::nullopt,
                           /*rendered=*/absl::nullopt,
                           FrameComparisonType::kRegular, frame_stats1);
  comparator.AddComparison(stats_key,
                           /*captured=*/absl::nullopt,
                           /*rendered=*/absl::nullopt,
                           FrameComparisonType::kRegular, frame_stats2);
  comparator.Stop(/*last_rendered_frame_times=*/{});

  std::map<InternalStatsKey, StreamStats> stats = comparator.stream_stats();
  EXPECT_DOUBLE_EQ(
      GetFirstOrDie(stats.at(stats_key).time_between_rendered_frames_ms), 15.0);
  EXPECT_DOUBLE_EQ(stats.at(stats_key).encode_frame_rate.GetEventsPerSecond(),
                   2.0 / 15 * 1000)
      << "There should be 2 events with interval of 15 ms";
  ;
}

TEST(DefaultVideoQualityAnalyzerFramesComparatorTest,
     FrameInFlightStatsAreHandledCorrectly) {
  DefaultVideoQualityAnalyzerCpuMeasurer cpu_measurer;
  DefaultVideoQualityAnalyzerFramesComparator comparator(
      Clock::GetRealTimeClock(), cpu_measurer, AnalyzerOptionsForTest());

  Timestamp stream_start_time = Clock::GetRealTimeClock()->CurrentTime();
  size_t stream = 0;
  size_t sender = 0;
  size_t receiver = 1;
  size_t peers_count = 2;
  InternalStatsKey stats_key(stream, sender, receiver);

  // There are 7 different timings inside frame stats: captured, pre_encode,
  // encoded, received, decode_start, decode_end, rendered. captured is always
  // set and received is set together with decode_start. So we create 6
  // different frame stats with interval of 15 ms, where for each stat next
  // timings will be set
  //   * 1st - captured
  //   * 2nd - captured, pre_encode
  //   * 3rd - captured, pre_encode, encoded
  //   * 4th - captured, pre_encode, encoded, received, decode_start
  //   * 5th - captured, pre_encode, encoded, received, decode_start, decode_end
  //   * 6th - all of them set
  std::vector<FrameStats> stats;
  // 1st stat
  FrameStats frame_stats(stream_start_time);
  stats.push_back(frame_stats);
  // 2nd stat
  frame_stats = ShiftStatsOn(frame_stats, TimeDelta::Millis(15));
  frame_stats.pre_encode_time =
      frame_stats.captured_time + TimeDelta::Millis(10);
  stats.push_back(frame_stats);
  // 3rd stat
  frame_stats = ShiftStatsOn(frame_stats, TimeDelta::Millis(15));
  frame_stats.encoded_time = frame_stats.captured_time + TimeDelta::Millis(20);
  frame_stats.used_encoder = Vp8CodecForOneFrame(1, frame_stats.encoded_time);
  stats.push_back(frame_stats);
  // 4th stat
  frame_stats = ShiftStatsOn(frame_stats, TimeDelta::Millis(15));
  frame_stats.received_time = frame_stats.captured_time + TimeDelta::Millis(30);
  frame_stats.decode_start_time =
      frame_stats.captured_time + TimeDelta::Millis(40);
  stats.push_back(frame_stats);
  // 5th stat
  frame_stats = ShiftStatsOn(frame_stats, TimeDelta::Millis(15));
  frame_stats.decode_end_time =
      frame_stats.captured_time + TimeDelta::Millis(50);
  frame_stats.used_decoder =
      Vp8CodecForOneFrame(1, frame_stats.decode_end_time);
  stats.push_back(frame_stats);
  // 6th stat
  frame_stats = ShiftStatsOn(frame_stats, TimeDelta::Millis(15));
  frame_stats.rendered_time = frame_stats.captured_time + TimeDelta::Millis(60);
  frame_stats.rendered_frame_width = 10;
  frame_stats.rendered_frame_height = 10;
  stats.push_back(frame_stats);

  comparator.Start(1);
  comparator.EnsureStatsForStream(stream, sender, peers_count,
                                  stream_start_time, stream_start_time);
  for (size_t i = 0; i < stats.size() - 1; ++i) {
    comparator.AddComparison(stats_key,
                             /*captured=*/absl::nullopt,
                             /*rendered=*/absl::nullopt,
                             FrameComparisonType::kFrameInFlight, stats[i]);
  }
  comparator.AddComparison(stats_key,
                           /*captured=*/absl::nullopt,
                           /*rendered=*/absl::nullopt,
                           FrameComparisonType::kRegular,
                           stats[stats.size() - 1]);
  comparator.Stop(/*last_rendered_frame_times=*/{});

  EXPECT_EQ(comparator.stream_stats().size(), 1lu);
  StreamStats result_stats = comparator.stream_stats().at(stats_key);

  EXPECT_DOUBLE_EQ(result_stats.transport_time_ms.GetAverage(), 20.0)
      << ToString(result_stats.transport_time_ms);
  EXPECT_EQ(result_stats.transport_time_ms.NumSamples(), 3);

  EXPECT_DOUBLE_EQ(result_stats.total_delay_incl_transport_ms.GetAverage(),
                   60.0)
      << ToString(result_stats.total_delay_incl_transport_ms);
  EXPECT_EQ(result_stats.total_delay_incl_transport_ms.NumSamples(), 1);

  EXPECT_DOUBLE_EQ(result_stats.encode_time_ms.GetAverage(), 10)
      << ToString(result_stats.encode_time_ms);
  EXPECT_EQ(result_stats.encode_time_ms.NumSamples(), 4);

  EXPECT_DOUBLE_EQ(result_stats.decode_time_ms.GetAverage(), 10)
      << ToString(result_stats.decode_time_ms);
  EXPECT_EQ(result_stats.decode_time_ms.NumSamples(), 2);

  EXPECT_DOUBLE_EQ(result_stats.receive_to_render_time_ms.GetAverage(), 30)
      << ToString(result_stats.receive_to_render_time_ms);
  EXPECT_EQ(result_stats.receive_to_render_time_ms.NumSamples(), 1);

  EXPECT_DOUBLE_EQ(result_stats.resolution_of_rendered_frame.GetAverage(), 100)
      << ToString(result_stats.resolution_of_rendered_frame);
  EXPECT_EQ(result_stats.resolution_of_rendered_frame.NumSamples(), 1);

  EXPECT_DOUBLE_EQ(result_stats.encode_frame_rate.GetEventsPerSecond(),
                   4.0 / 45 * 1000)
      << "There should be 4 events with interval of 15 ms";
}

}  // namespace
}  // namespace webrtc
