/*
 *  Copyright 2019 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.
 */
#ifndef TEST_SCENARIO_STATS_COLLECTION_H_
#define TEST_SCENARIO_STATS_COLLECTION_H_

#include <map>
#include <memory>

#include "absl/types/optional.h"
#include "call/call.h"
#include "test/logging/log_writer.h"
#include "test/scenario/performance_stats.h"

namespace webrtc {
namespace test {

struct VideoQualityAnalyzerConfig {
  double psnr_coverage = 1;
  rtc::Thread* thread = nullptr;
};

class VideoLayerAnalyzer {
 public:
  void HandleCapturedFrame(const VideoFramePair& sample);
  void HandleRenderedFrame(const VideoFramePair& sample);
  void HandleFramePair(VideoFramePair sample,
                       double psnr,
                       RtcEventLogOutput* writer);
  VideoQualityStats stats_;
  Timestamp last_capture_time_ = Timestamp::MinusInfinity();
  Timestamp last_render_time_ = Timestamp::MinusInfinity();
  Timestamp last_freeze_time_ = Timestamp::MinusInfinity();
  int skip_count_ = 0;
};

class VideoQualityAnalyzer {
 public:
  explicit VideoQualityAnalyzer(
      VideoQualityAnalyzerConfig config = VideoQualityAnalyzerConfig(),
      std::unique_ptr<RtcEventLogOutput> writer = nullptr);
  ~VideoQualityAnalyzer();
  void HandleFramePair(VideoFramePair sample);
  std::vector<VideoQualityStats> layer_stats() const;
  VideoQualityStats& stats();
  void PrintHeaders();
  void PrintFrameInfo(const VideoFramePair& sample);
  std::function<void(const VideoFramePair&)> Handler();

 private:
  void HandleFramePair(VideoFramePair sample, double psnr);
  const VideoQualityAnalyzerConfig config_;
  std::map<int, VideoLayerAnalyzer> layer_analyzers_;
  const std::unique_ptr<RtcEventLogOutput> writer_;
  absl::optional<VideoQualityStats> cached_;
};

class CallStatsCollector {
 public:
  void AddStats(Call::Stats sample);
  CollectedCallStats& stats() { return stats_; }

 private:
  CollectedCallStats stats_;
};
class AudioReceiveStatsCollector {
 public:
  void AddStats(AudioReceiveStream::Stats sample);
  CollectedAudioReceiveStats& stats() { return stats_; }

 private:
  CollectedAudioReceiveStats stats_;
};
class VideoSendStatsCollector {
 public:
  void AddStats(VideoSendStream::Stats sample, Timestamp at_time);
  CollectedVideoSendStats& stats() { return stats_; }

 private:
  CollectedVideoSendStats stats_;
  Timestamp last_update_ = Timestamp::MinusInfinity();
  size_t last_fec_bytes_ = 0;
};
class VideoReceiveStatsCollector {
 public:
  void AddStats(VideoReceiveStream::Stats sample);
  CollectedVideoReceiveStats& stats() { return stats_; }

 private:
  CollectedVideoReceiveStats stats_;
};

struct CallStatsCollectors {
  CallStatsCollector call;
  AudioReceiveStatsCollector audio_receive;
  VideoSendStatsCollector video_send;
  VideoReceiveStatsCollector video_receive;
};

}  // namespace test
}  // namespace webrtc

#endif  // TEST_SCENARIO_STATS_COLLECTION_H_
