/*
 *  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 MODULES_AUDIO_CODING_NETEQ_STATISTICS_CALCULATOR_H_
#define MODULES_AUDIO_CODING_NETEQ_STATISTICS_CALCULATOR_H_

#include <deque>
#include <string>

#include "modules/audio_coding/neteq/include/neteq.h"
#include "rtc_base/constructor_magic.h"

namespace webrtc {

class DelayManager;

// This class handles various network statistics in NetEq.
class StatisticsCalculator {
 public:
  StatisticsCalculator();

  virtual ~StatisticsCalculator();

  // Resets most of the counters.
  void Reset();

  // Resets the counters that are not handled by Reset().
  void ResetMcu();

  // Reports that |num_samples| samples were produced through expansion, and
  // that the expansion produced other than just noise samples.
  void ExpandedVoiceSamples(size_t num_samples, bool is_new_concealment_event);

  // Reports that |num_samples| samples were produced through expansion, and
  // that the expansion produced only noise samples.
  void ExpandedNoiseSamples(size_t num_samples, bool is_new_concealment_event);

  // Corrects the statistics for number of samples produced through non-noise
  // expansion by adding |num_samples| (negative or positive) to the current
  // value. The result is capped to zero to avoid negative values.
  void ExpandedVoiceSamplesCorrection(int num_samples);

  // Same as ExpandedVoiceSamplesCorrection but for noise samples.
  void ExpandedNoiseSamplesCorrection(int num_samples);

  // Reports that |num_samples| samples were produced through preemptive
  // expansion.
  void PreemptiveExpandedSamples(size_t num_samples);

  // Reports that |num_samples| samples were removed through accelerate.
  void AcceleratedSamples(size_t num_samples);

  // Reports that |num_samples| zeros were inserted into the output.
  void AddZeros(size_t num_samples);

  // Reports that |num_packets| packets were discarded.
  virtual void PacketsDiscarded(size_t num_packets);

  // Reports that |num_packets| packets samples were discarded.
  virtual void SecondaryPacketsDiscarded(size_t num_samples);

  // Reports that |num_samples| were lost.
  void LostSamples(size_t num_samples);

  // Increases the report interval counter with |num_samples| at a sample rate
  // of |fs_hz|. This is how the StatisticsCalculator gets notified that current
  // time is increasing.
  void IncreaseCounter(size_t num_samples, int fs_hz);

  // Update jitter buffer delay counter.
  void JitterBufferDelay(size_t num_samples, uint64_t waiting_time_ms);

  // Stores new packet waiting time in waiting time statistics.
  void StoreWaitingTime(int waiting_time_ms);

  // Reports that |num_samples| samples were decoded from secondary packets.
  void SecondaryDecodedSamples(int num_samples);

  // Reports that the packet buffer was flushed.
  void FlushedPacketBuffer();

  // Reports that the jitter buffer received a packet.
  void ReceivedPacket();

  // Reports that a received packet was delayed by |delay_ms| milliseconds.
  virtual void RelativePacketArrivalDelay(size_t delay_ms);

  // Logs a delayed packet outage event of |num_samples| expanded at a sample
  // rate of |fs_hz|. A delayed packet outage event is defined as an expand
  // period caused not by an actual packet loss, but by a delayed packet.
  virtual void LogDelayedPacketOutageEvent(int num_samples, int fs_hz);

  // Returns the current network statistics in |stats|. The current sample rate
  // is |fs_hz|, the total number of samples in packet buffer and sync buffer
  // yet to play out is |num_samples_in_buffers|, and the number of samples per
  // packet is |samples_per_packet|. The method does not populate
  // |preferred_buffer_size_ms|, |jitter_peaks_found| or |clockdrift_ppm|; use
  // the PopulateDelayManagerStats method for those.
  void GetNetworkStatistics(int fs_hz,
                            size_t num_samples_in_buffers,
                            size_t samples_per_packet,
                            NetEqNetworkStatistics* stats);

  // Populates |preferred_buffer_size_ms|, |jitter_peaks_found| and
  // |clockdrift_ppm| in |stats|. This is a convenience method, and does not
  // strictly have to be in the StatisticsCalculator class, but it makes sense
  // since all other stats fields are populated by that class.
  static void PopulateDelayManagerStats(int ms_per_packet,
                                        const DelayManager& delay_manager,
                                        NetEqNetworkStatistics* stats);

  // Returns a copy of this class's lifetime statistics. These statistics are
  // never reset.
  NetEqLifetimeStatistics GetLifetimeStatistics() const;

  NetEqOperationsAndState GetOperationsAndState() const;

 private:
  static const int kMaxReportPeriod = 60;  // Seconds before auto-reset.
  static const size_t kLenWaitingTimes = 100;

  class PeriodicUmaLogger {
   public:
    PeriodicUmaLogger(const std::string& uma_name,
                      int report_interval_ms,
                      int max_value);
    virtual ~PeriodicUmaLogger();
    void AdvanceClock(int step_ms);

   protected:
    void LogToUma(int value) const;
    virtual int Metric() const = 0;
    virtual void Reset() = 0;

    const std::string uma_name_;
    const int report_interval_ms_;
    const int max_value_;
    int timer_ = 0;
  };

  class PeriodicUmaCount final : public PeriodicUmaLogger {
   public:
    PeriodicUmaCount(const std::string& uma_name,
                     int report_interval_ms,
                     int max_value);
    ~PeriodicUmaCount() override;
    void RegisterSample();

   protected:
    int Metric() const override;
    void Reset() override;

   private:
    int counter_ = 0;
  };

  class PeriodicUmaAverage final : public PeriodicUmaLogger {
   public:
    PeriodicUmaAverage(const std::string& uma_name,
                       int report_interval_ms,
                       int max_value);
    ~PeriodicUmaAverage() override;
    void RegisterSample(int value);

   protected:
    int Metric() const override;
    void Reset() override;

   private:
    double sum_ = 0.0;
    int counter_ = 0;
  };

  // Corrects the concealed samples counter in lifetime_stats_. The value of
  // num_samples_ is added directly to the stat if the correction is positive.
  // If the correction is negative, it is cached and will be subtracted against
  // future additions to the counter. This is meant to be called from
  // Expanded{Voice,Noise}Samples{Correction}.
  void ConcealedSamplesCorrection(int num_samples, bool is_voice);

  // Calculates numerator / denominator, and returns the value in Q14.
  static uint16_t CalculateQ14Ratio(size_t numerator, uint32_t denominator);

  NetEqLifetimeStatistics lifetime_stats_;
  NetEqOperationsAndState operations_and_state_;
  size_t concealed_samples_correction_ = 0;
  size_t voice_concealed_samples_correction_ = 0;
  size_t preemptive_samples_;
  size_t accelerate_samples_;
  size_t added_zero_samples_;
  size_t expanded_speech_samples_;
  size_t expanded_noise_samples_;
  size_t discarded_packets_;
  size_t lost_timestamps_;
  uint32_t timestamps_since_last_report_;
  std::deque<int> waiting_times_;
  uint32_t secondary_decoded_samples_;
  size_t discarded_secondary_packets_;
  PeriodicUmaCount delayed_packet_outage_counter_;
  PeriodicUmaAverage excess_buffer_delay_;
  PeriodicUmaCount buffer_full_counter_;

  RTC_DISALLOW_COPY_AND_ASSIGN(StatisticsCalculator);
};

}  // namespace webrtc
#endif  // MODULES_AUDIO_CODING_NETEQ_STATISTICS_CALCULATOR_H_
