/*
 *  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/base/common.h"
#include "webrtc/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_
