/*
 *  Copyright (c) 2013 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_BWE_TEST_FRAMEWORK_H_
#define WEBRTC_MODULES_REMOTE_BITRATE_ESTIMATOR_TEST_BWE_TEST_FRAMEWORK_H_

#include <assert.h>
#include <math.h>

#include <algorithm>
#include <list>
#include <memory>
#include <numeric>
#include <set>
#include <sstream>
#include <string>
#include <utility>
#include <vector>

#include "webrtc/modules/bitrate_controller/include/bitrate_controller.h"
#include "webrtc/modules/include/module_common_types.h"
#include "webrtc/modules/pacing/paced_sender.h"
#include "webrtc/modules/remote_bitrate_estimator/include/remote_bitrate_estimator.h"
#include "webrtc/modules/remote_bitrate_estimator/test/bwe_test_logging.h"
#include "webrtc/modules/remote_bitrate_estimator/test/packet.h"
#include "webrtc/modules/rtp_rtcp/include/rtp_rtcp_defines.h"
#include "webrtc/rtc_base/constructormagic.h"
#include "webrtc/rtc_base/random.h"
#include "webrtc/system_wrappers/include/clock.h"
#include "webrtc/typedefs.h"

namespace webrtc {

class RtcpBandwidthObserver;

namespace testing {
namespace bwe {

class DelayCapHelper;

class RateCounter {
 public:
  explicit RateCounter(int64_t window_size_ms)
      : window_size_us_(1000 * window_size_ms),
        recently_received_packets_(0),
        recently_received_bytes_(0),
        last_accumulated_us_(0),
        window_() {}

  RateCounter() : RateCounter(1000) {}

  void UpdateRates(int64_t send_time_us, uint32_t payload_size);

  int64_t window_size_ms() const { return (window_size_us_ + 500) / 1000; }
  uint32_t packets_per_second() const;
  uint32_t bits_per_second() const;

  double BitrateWindowS() const;

 private:
  typedef std::pair<int64_t, uint32_t> TimeSizePair;

  int64_t window_size_us_;
  uint32_t recently_received_packets_;
  uint32_t recently_received_bytes_;
  int64_t last_accumulated_us_;
  std::list<TimeSizePair> window_;
};

typedef std::set<int> FlowIds;
const FlowIds CreateFlowIds(const int *flow_ids_array, size_t num_flow_ids);
const FlowIds CreateFlowIdRange(int initial_value, int last_value);

template <typename T>
bool DereferencingComparator(const T* const& a, const T* const& b) {
  assert(a != NULL);
  assert(b != NULL);
  return *a < *b;
}

template<typename T> class Stats {
 public:
  Stats()
      : data_(),
        last_mean_count_(0),
        last_variance_count_(0),
        last_minmax_count_(0),
        mean_(0),
        variance_(0),
        min_(0),
        max_(0) {
  }

  void Push(T data_point) {
    data_.push_back(data_point);
  }

  T GetMean() {
    if (last_mean_count_ != data_.size()) {
      last_mean_count_ = data_.size();
      mean_ = std::accumulate(data_.begin(), data_.end(), static_cast<T>(0));
      assert(last_mean_count_ != 0);
      mean_ /= static_cast<T>(last_mean_count_);
    }
    return mean_;
  }
  T GetVariance() {
    if (last_variance_count_ != data_.size()) {
      last_variance_count_ = data_.size();
      T mean = GetMean();
      variance_ = 0;
      for (const auto& sample : data_) {
        T diff = (sample - mean);
        variance_ += diff * diff;
      }
      assert(last_variance_count_ != 0);
      variance_ /= static_cast<T>(last_variance_count_);
    }
    return variance_;
  }
  T GetStdDev() {
    return sqrt(static_cast<double>(GetVariance()));
  }
  T GetMin() {
    RefreshMinMax();
    return min_;
  }
  T GetMax() {
    RefreshMinMax();
    return max_;
  }

  std::string AsString() {
    std::stringstream ss;
    ss << (GetMean() >= 0 ? GetMean() : -1) << ", " <<
        (GetStdDev() >= 0 ? GetStdDev() : -1);
    return ss.str();
  }

  void Log(const std::string& units) {
    BWE_TEST_LOGGING_LOG5("", "%f %s\t+/-%f\t[%f,%f]",
        GetMean(), units.c_str(), GetStdDev(), GetMin(), GetMax());
  }

 private:
  void RefreshMinMax() {
    if (last_minmax_count_ != data_.size()) {
      last_minmax_count_ = data_.size();
      min_ = max_ = 0;
      if (data_.empty()) {
        return;
      }
      typename std::vector<T>::const_iterator it = data_.begin();
      min_ = max_ = *it;
      while (++it != data_.end()) {
        min_ = std::min(min_, *it);
        max_ = std::max(max_, *it);
      }
    }
  }

  std::vector<T> data_;
  typename std::vector<T>::size_type last_mean_count_;
  typename std::vector<T>::size_type last_variance_count_;
  typename std::vector<T>::size_type last_minmax_count_;
  T mean_;
  T variance_;
  T min_;
  T max_;
};

bool IsTimeSorted(const Packets& packets);

class PacketProcessor;

enum ProcessorType { kSender, kReceiver, kRegular };

class PacketProcessorListener {
 public:
  virtual ~PacketProcessorListener() {}

  virtual void AddPacketProcessor(PacketProcessor* processor,
                                  ProcessorType type) = 0;
  virtual void RemovePacketProcessor(PacketProcessor* processor) = 0;
};

class PacketProcessor {
 public:
  PacketProcessor(PacketProcessorListener* listener,
                  int flow_id,
                  ProcessorType type);
  PacketProcessor(PacketProcessorListener* listener,
                  const FlowIds& flow_ids,
                  ProcessorType type);
  virtual ~PacketProcessor();

  // Called after each simulation batch to allow the processor to plot any
  // internal data.
  virtual void Plot(int64_t timestamp_ms) {}

  // Run simulation for |time_ms| milliseconds, consuming packets from, and
  // producing packets into in_out. The outgoing packet list must be sorted on
  // |send_time_us_|. The simulation time |time_ms| is optional to use.
  virtual void RunFor(int64_t time_ms, Packets* in_out) = 0;

  const FlowIds& flow_ids() const { return flow_ids_; }

  uint32_t packets_per_second() const;
  uint32_t bits_per_second() const;

 protected:
  RateCounter rate_counter_;

 private:
  PacketProcessorListener* listener_;
  const FlowIds flow_ids_;

  RTC_DISALLOW_COPY_AND_ASSIGN(PacketProcessor);
};

class RateCounterFilter : public PacketProcessor {
 public:
  RateCounterFilter(PacketProcessorListener* listener,
                    int flow_id,
                    const char* name,
                    const std::string& algorithm_name);
  RateCounterFilter(PacketProcessorListener* listener,
                    const FlowIds& flow_ids,
                    const char* name,
                    const std::string& algorithm_name);
  RateCounterFilter(PacketProcessorListener* listener,
                    const FlowIds& flow_ids,
                    const char* name,
                    int64_t start_plotting_time_ms,
                    const std::string& algorithm_name);
  virtual ~RateCounterFilter();

  void LogStats();
  Stats<double> GetBitrateStats() const;
  virtual void Plot(int64_t timestamp_ms);
  virtual void RunFor(int64_t time_ms, Packets* in_out);

 private:
  Stats<double> packets_per_second_stats_;
  Stats<double> kbps_stats_;
  int64_t start_plotting_time_ms_;
  int flow_id_ = 0;
  std::string name_;
  // Algorithm name if single flow, Total link utilization if all flows.
  std::string algorithm_name_;

  RTC_DISALLOW_IMPLICIT_CONSTRUCTORS(RateCounterFilter);
};

class LossFilter : public PacketProcessor {
 public:
  LossFilter(PacketProcessorListener* listener, int flow_id);
  LossFilter(PacketProcessorListener* listener, const FlowIds& flow_ids);
  virtual ~LossFilter() {}

  void SetLoss(float loss_percent);
  virtual void RunFor(int64_t time_ms, Packets* in_out);

 private:
  Random random_;
  float loss_fraction_;

  RTC_DISALLOW_IMPLICIT_CONSTRUCTORS(LossFilter);
};

class DelayFilter : public PacketProcessor {
 public:
  DelayFilter(PacketProcessorListener* listener, int flow_id);
  DelayFilter(PacketProcessorListener* listener, const FlowIds& flow_ids);
  virtual ~DelayFilter() {}

  void SetOneWayDelayMs(int64_t one_way_delay_ms);
  virtual void RunFor(int64_t time_ms, Packets* in_out);

 private:
  int64_t one_way_delay_us_;
  int64_t last_send_time_us_;

  RTC_DISALLOW_IMPLICIT_CONSTRUCTORS(DelayFilter);
};

class JitterFilter : public PacketProcessor {
 public:
  JitterFilter(PacketProcessorListener* listener, int flow_id);
  JitterFilter(PacketProcessorListener* listener, const FlowIds& flow_ids);
  virtual ~JitterFilter() {}

  void SetMaxJitter(int64_t stddev_jitter_ms);
  virtual void RunFor(int64_t time_ms, Packets* in_out);
  void set_reorderdering(bool reordering) { reordering_ = reordering; }
  int64_t MeanUs();

 private:
  Random random_;
  int64_t stddev_jitter_us_;
  int64_t last_send_time_us_;
  bool reordering_;  // False by default.

  RTC_DISALLOW_IMPLICIT_CONSTRUCTORS(JitterFilter);
};

// Reorders two consecutive packets with a probability of reorder_percent.
class ReorderFilter : public PacketProcessor {
 public:
  ReorderFilter(PacketProcessorListener* listener, int flow_id);
  ReorderFilter(PacketProcessorListener* listener, const FlowIds& flow_ids);
  virtual ~ReorderFilter() {}

  void SetReorder(float reorder_percent);
  virtual void RunFor(int64_t time_ms, Packets* in_out);

 private:
  Random random_;
  float reorder_fraction_;

  RTC_DISALLOW_IMPLICIT_CONSTRUCTORS(ReorderFilter);
};

// Apply a bitrate choke with an infinite queue on the packet stream.
class ChokeFilter : public PacketProcessor {
 public:
  ChokeFilter(PacketProcessorListener* listener, int flow_id);
  ChokeFilter(PacketProcessorListener* listener, const FlowIds& flow_ids);
  virtual ~ChokeFilter();

  void set_capacity_kbps(uint32_t kbps);
  void set_max_delay_ms(int64_t max_queueing_delay_ms);

  uint32_t capacity_kbps();

  virtual void RunFor(int64_t time_ms, Packets* in_out);

  Stats<double> GetDelayStats() const;

 private:
  uint32_t capacity_kbps_;
  int64_t last_send_time_us_;
  std::unique_ptr<DelayCapHelper> delay_cap_helper_;

  RTC_DISALLOW_IMPLICIT_CONSTRUCTORS(ChokeFilter);
};

class TraceBasedDeliveryFilter : public PacketProcessor {
 public:
  TraceBasedDeliveryFilter(PacketProcessorListener* listener, int flow_id);
  TraceBasedDeliveryFilter(PacketProcessorListener* listener,
                           const FlowIds& flow_ids);
  TraceBasedDeliveryFilter(PacketProcessorListener* listener,
                           int flow_id,
                           const char* name);
  virtual ~TraceBasedDeliveryFilter();

  // The file should contain nanosecond timestamps corresponding to the time
  // when the network can accept another packet. The timestamps should be
  // separated by new lines, e.g., "100000000\n125000000\n321000000\n..."
  bool Init(const std::string& filename);
  virtual void Plot(int64_t timestamp_ms);
  virtual void RunFor(int64_t time_ms, Packets* in_out);

  void set_max_delay_ms(int64_t max_delay_ms);
  Stats<double> GetDelayStats() const;
  Stats<double> GetBitrateStats() const;

 private:
  void ProceedToNextSlot();

  typedef std::vector<int64_t> TimeList;
  int64_t current_offset_us_;
  TimeList delivery_times_us_;
  TimeList::const_iterator next_delivery_it_;
  int64_t local_time_us_;
  std::unique_ptr<RateCounter> rate_counter_;
  std::string name_;
  std::unique_ptr<DelayCapHelper> delay_cap_helper_;
  Stats<double> packets_per_second_stats_;
  Stats<double> kbps_stats_;

  RTC_DISALLOW_COPY_AND_ASSIGN(TraceBasedDeliveryFilter);
};

class VideoSource {
 public:
  VideoSource(int flow_id,
              float fps,
              uint32_t kbps,
              uint32_t ssrc,
              int64_t first_frame_offset_ms);
  virtual ~VideoSource() {}

  virtual void RunFor(int64_t time_ms, Packets* in_out);

  virtual int flow_id() const { return flow_id_; }
  virtual void SetBitrateBps(int bitrate_bps) {}
  uint32_t bits_per_second() const { return bits_per_second_; }
  uint32_t max_payload_size_bytes() const { return kMaxPayloadSizeBytes; }
  int64_t GetTimeUntilNextFrameMs() const;

 protected:
  virtual uint32_t NextFrameSize();
  virtual uint32_t NextPacketSize(uint32_t frame_size,
                                  uint32_t remaining_payload);

  const uint32_t kMaxPayloadSizeBytes;
  const uint32_t kTimestampBase;
  const double frame_period_ms_;
  uint32_t bits_per_second_;
  uint32_t frame_size_bytes_;

 private:
  Random random_;
  const int flow_id_;
  int64_t next_frame_ms_;
  int64_t next_frame_rand_ms_;
  int64_t now_ms_;
  RTPHeader prototype_header_;

  RTC_DISALLOW_IMPLICIT_CONSTRUCTORS(VideoSource);
};

class AdaptiveVideoSource : public VideoSource {
 public:
  AdaptiveVideoSource(int flow_id,
                      float fps,
                      uint32_t kbps,
                      uint32_t ssrc,
                      int64_t first_frame_offset_ms);
  virtual ~AdaptiveVideoSource() {}

  void SetBitrateBps(int bitrate_bps) override;

 private:
  RTC_DISALLOW_IMPLICIT_CONSTRUCTORS(AdaptiveVideoSource);
};

class PeriodicKeyFrameSource : public AdaptiveVideoSource {
 public:
  PeriodicKeyFrameSource(int flow_id,
                         float fps,
                         uint32_t kbps,
                         uint32_t ssrc,
                         int64_t first_frame_offset_ms,
                         int key_frame_interval);
  virtual ~PeriodicKeyFrameSource() {}

 protected:
  uint32_t NextFrameSize() override;
  uint32_t NextPacketSize(uint32_t frame_size,
                          uint32_t remaining_payload) override;

 private:
  int key_frame_interval_;
  uint32_t frame_counter_;
  int compensation_bytes_;
  int compensation_per_frame_;
  RTC_DISALLOW_IMPLICIT_CONSTRUCTORS(PeriodicKeyFrameSource);
};
}  // namespace bwe
}  // namespace testing
}  // namespace webrtc

#endif  // WEBRTC_MODULES_REMOTE_BITRATE_ESTIMATOR_TEST_BWE_TEST_FRAMEWORK_H_
