/*
 *  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 "absl/strings/string_view.h"
#include "api/neteq/neteq.h"

namespace webrtc {

class DelayManager;

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

  virtual ~StatisticsCalculator();

  StatisticsCalculator(const StatisticsCalculator&) = delete;
  StatisticsCalculator& operator=(const StatisticsCalculator&) = delete;

  // 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);

  void DecodedOutputPlayed();

  // Mark end of expand event; triggers some stats to be reported.
  void EndExpandEvent(int fs_hz);

  // 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` comfort noise samples were generated.
  void GeneratedNoiseSamples(size_t num_samples);

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

  // Reports that `num_packets` secondary (FEC) packets were discarded.
  virtual void SecondaryPacketsDiscarded(size_t num_packets);

  // Reports that `num_packets` secondary (FEC) packets were received.
  virtual void SecondaryPacketsReceived(size_t num_packets);

  // 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,
                         uint64_t target_delay_ms,
                         uint64_t unlimited_target_delay_ms,
                         uint64_t processing_delay_us);

  // 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 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(size_t samples_per_packet,
                            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(absl::string_view 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(absl::string_view 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(absl::string_view 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 silent_concealed_samples_correction_ = 0;
  size_t preemptive_samples_;
  size_t accelerate_samples_;
  size_t expanded_speech_samples_;
  size_t expanded_noise_samples_;
  size_t concealed_samples_at_event_end_ = 0;
  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_;
  bool decoded_output_played_ = false;
};

}  // namespace webrtc
#endif  // MODULES_AUDIO_CODING_NETEQ_STATISTICS_CALCULATOR_H_
