/*
 *  Copyright (c) 2015 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 WEBRTC_MODULES_REMOTE_BITRATE_ESTIMATOR_TEST_METRIC_RECORDER_H_
#define WEBRTC_MODULES_REMOTE_BITRATE_ESTIMATOR_TEST_METRIC_RECORDER_H_

#include <map>
#include <set>
#include <string>
#include <vector>

#include "webrtc/rtc_base/gtest_prod_util.h"

namespace webrtc {
namespace testing {
namespace bwe {

class ChokeFilter;
class PacketSender;

class LinkShare {
 public:
  explicit LinkShare(ChokeFilter* choke_filter);

  void PauseFlow(int flow_id);   // Increases available capacity per flow.
  void ResumeFlow(int flow_id);  // Decreases available capacity per flow.

  uint32_t TotalAvailableKbps();
  // If the given flow is paused, its output is zero.
  uint32_t AvailablePerFlowKbps(int flow_id);

 private:
  ChokeFilter* choke_filter_;
  std::set<int> running_flows_;
};

struct PlotInformation {
  PlotInformation()
      : prefix(),
        last_plot_ms(0),
        time_ms(0),
        value(0.0),
        plot_interval_ms(0) {}
  template <typename T>
  void Update(int64_t now_ms, T new_value) {
    time_ms = now_ms;
    value = static_cast<double>(new_value);
  }
  std::string prefix;
  bool plot;
  int64_t last_plot_ms;
  int64_t time_ms;
  double value;
  int64_t plot_interval_ms;
};

class MetricRecorder {
 public:
  MetricRecorder(const std::string algorithm_name,
                 int flow_id,
                 PacketSender* packet_sender,
                 LinkShare* link_share);

  void SetPlotInformation(const std::vector<std::string>& prefixes,
                          bool plot_delay,
                          bool plot_loss);

  template <typename T>
  void PlotLine(int windows_id,
                const std::string& prefix,
                int64_t time_ms,
                T y);

  void PlotDynamics(int metric);
  void PlotAllDynamics();

  void UpdateTimeMs(int64_t time_ms);
  void UpdateThroughput(int64_t bitrate_kbps, size_t payload_size);
  void UpdateSendingEstimateKbps(int64_t bitrate_kbps);
  void UpdateDelayMs(int64_t delay_ms);
  void UpdateLoss(float loss_ratio);
  void UpdateObjective();

  void PlotThroughputHistogram(const std::string& title,
                               const std::string& bwe_name,
                               size_t num_flows,
                               int64_t extra_offset_ms,
                               const std::string optimum_id) const;

  void PlotThroughputHistogram(const std::string& title,
                               const std::string& bwe_name,
                               size_t num_flows,
                               int64_t extra_offset_ms) const;

  void PlotDelayHistogram(const std::string& title,
                          const std::string& bwe_name,
                          size_t num_flows,
                          int64_t one_way_path_delay_ms) const;

  void PlotLossHistogram(const std::string& title,
                         const std::string& bwe_name,
                         size_t num_flows,
                         float global_loss_ratio) const;

  void PlotObjectiveHistogram(const std::string& title,
                              const std::string& bwe_name,
                              size_t num_flows) const;

  void set_start_computing_metrics_ms(int64_t start_computing_metrics_ms) {
    start_computing_metrics_ms_ = start_computing_metrics_ms;
  }

  void set_plot_available_capacity(bool plot) {
    plot_information_[kTotalAvailable].plot = plot;
  }

  void PauseFlow();                         // Plot zero.
  void ResumeFlow(int64_t paused_time_ms);  // Plot zero.
  void PlotZero();

 private:
  FRIEND_TEST_ALL_PREFIXES(MetricRecorderTest, NoPackets);
  FRIEND_TEST_ALL_PREFIXES(MetricRecorderTest, RegularPackets);
  FRIEND_TEST_ALL_PREFIXES(MetricRecorderTest, VariableDelayPackets);

  uint32_t GetTotalAvailableKbps();
  uint32_t GetAvailablePerFlowKbps();
  uint32_t GetSendingEstimateKbps();
  double ObjectiveFunction() const;

  double Renormalize(double x) const;
  bool ShouldRecord(int64_t arrival_time_ms);

  void PushDelayMs(int64_t delay_ms, int64_t arrival_time_ms);
  void PushThroughputBytes(size_t throughput_bytes, int64_t arrival_time_ms);

  void UpdateEstimateError(int64_t new_value);
  double DelayStdDev() const;
  int64_t NthDelayPercentile(int n) const;
  double AverageBitrateKbps(int64_t extra_offset_ms) const;
  int64_t RunDurationMs(int64_t extra_offset_ms) const;

  enum Metrics {
    kThroughput = 0,
    kSendingEstimate,
    kDelay,
    kLoss,
    kObjective,
    kTotalAvailable,
    kAvailablePerFlow,
    kNumMetrics
  };

  std::string algorithm_name_;
  int flow_id_;
  LinkShare* link_share_;

  int64_t now_ms_;

  PlotInformation plot_information_[kNumMetrics];

  int64_t sum_delays_ms_;
  // delay_histogram_ms_[i] counts how many packets have delay = i ms.
  std::map<int64_t, size_t> delay_histogram_ms_;
  int64_t sum_delays_square_ms2_;  // Used to compute standard deviation.
  size_t sum_throughput_bytes_;
  // ((Receiving rate - available bitrate per flow) * time window)^p.
  // 0 for negative values, 1 for positive values.
  int64_t sum_lp_weighted_estimate_error_[2];
  int64_t last_unweighted_estimate_error_;
  int64_t optimal_throughput_bits_;
  int64_t last_available_bitrate_per_flow_kbps_;
  int64_t start_computing_metrics_ms_;
  bool started_computing_metrics_;
  size_t num_packets_received_;
};

}  // namespace bwe
}  // namespace testing
}  // namespace webrtc
#endif  // WEBRTC_MODULES_REMOTE_BITRATE_ESTIMATOR_TEST_METRIC_RECORDER_H_
