/*
 *  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.
 */

#include "modules/audio_coding/neteq/statistics_calculator.h"

#include <assert.h>
#include <string.h>  // memset

#include <algorithm>

#include "modules/audio_coding/neteq/delay_manager.h"
#include "rtc_base/checks.h"
#include "rtc_base/numerics/safe_conversions.h"
#include "system_wrappers/include/metrics.h"

namespace webrtc {

namespace {
size_t AddIntToSizeTWithLowerCap(int a, size_t b) {
  const size_t ret = b + a;
  // If a + b is negative, resulting in a negative wrap, cap it to zero instead.
  static_assert(sizeof(size_t) >= sizeof(int),
                "int must not be wider than size_t for this to work");
  return (a < 0 && ret > b) ? 0 : ret;
}

constexpr int kInterruptionLenMs = 150;
}  // namespace

// Allocating the static const so that it can be passed by reference to
// RTC_DCHECK.
const size_t StatisticsCalculator::kLenWaitingTimes;

StatisticsCalculator::PeriodicUmaLogger::PeriodicUmaLogger(
    const std::string& uma_name,
    int report_interval_ms,
    int max_value)
    : uma_name_(uma_name),
      report_interval_ms_(report_interval_ms),
      max_value_(max_value),
      timer_(0) {}

StatisticsCalculator::PeriodicUmaLogger::~PeriodicUmaLogger() = default;

void StatisticsCalculator::PeriodicUmaLogger::AdvanceClock(int step_ms) {
  timer_ += step_ms;
  if (timer_ < report_interval_ms_) {
    return;
  }
  LogToUma(Metric());
  Reset();
  timer_ -= report_interval_ms_;
  RTC_DCHECK_GE(timer_, 0);
}

void StatisticsCalculator::PeriodicUmaLogger::LogToUma(int value) const {
  RTC_HISTOGRAM_COUNTS_SPARSE(uma_name_, value, 1, max_value_, 50);
}

StatisticsCalculator::PeriodicUmaCount::PeriodicUmaCount(
    const std::string& uma_name,
    int report_interval_ms,
    int max_value)
    : PeriodicUmaLogger(uma_name, report_interval_ms, max_value) {}

StatisticsCalculator::PeriodicUmaCount::~PeriodicUmaCount() {
  // Log the count for the current (incomplete) interval.
  LogToUma(Metric());
}

void StatisticsCalculator::PeriodicUmaCount::RegisterSample() {
  ++counter_;
}

int StatisticsCalculator::PeriodicUmaCount::Metric() const {
  return counter_;
}

void StatisticsCalculator::PeriodicUmaCount::Reset() {
  counter_ = 0;
}

StatisticsCalculator::PeriodicUmaAverage::PeriodicUmaAverage(
    const std::string& uma_name,
    int report_interval_ms,
    int max_value)
    : PeriodicUmaLogger(uma_name, report_interval_ms, max_value) {}

StatisticsCalculator::PeriodicUmaAverage::~PeriodicUmaAverage() {
  // Log the average for the current (incomplete) interval.
  LogToUma(Metric());
}

void StatisticsCalculator::PeriodicUmaAverage::RegisterSample(int value) {
  sum_ += value;
  ++counter_;
}

int StatisticsCalculator::PeriodicUmaAverage::Metric() const {
  return counter_ == 0 ? 0 : static_cast<int>(sum_ / counter_);
}

void StatisticsCalculator::PeriodicUmaAverage::Reset() {
  sum_ = 0.0;
  counter_ = 0;
}

StatisticsCalculator::StatisticsCalculator()
    : preemptive_samples_(0),
      accelerate_samples_(0),
      added_zero_samples_(0),
      expanded_speech_samples_(0),
      expanded_noise_samples_(0),
      discarded_packets_(0),
      lost_timestamps_(0),
      timestamps_since_last_report_(0),
      secondary_decoded_samples_(0),
      discarded_secondary_packets_(0),
      delayed_packet_outage_counter_(
          "WebRTC.Audio.DelayedPacketOutageEventsPerMinute",
          60000,  // 60 seconds report interval.
          100),
      excess_buffer_delay_("WebRTC.Audio.AverageExcessBufferDelayMs",
                           60000,  // 60 seconds report interval.
                           1000),
      buffer_full_counter_("WebRTC.Audio.JitterBufferFullPerMinute",
                           60000,  // 60 seconds report interval.
                           100) {}

StatisticsCalculator::~StatisticsCalculator() = default;

void StatisticsCalculator::Reset() {
  preemptive_samples_ = 0;
  accelerate_samples_ = 0;
  added_zero_samples_ = 0;
  expanded_speech_samples_ = 0;
  expanded_noise_samples_ = 0;
  secondary_decoded_samples_ = 0;
  discarded_secondary_packets_ = 0;
  waiting_times_.clear();
}

void StatisticsCalculator::ResetMcu() {
  discarded_packets_ = 0;
  lost_timestamps_ = 0;
  timestamps_since_last_report_ = 0;
}

void StatisticsCalculator::ExpandedVoiceSamples(size_t num_samples,
                                                bool is_new_concealment_event) {
  expanded_speech_samples_ += num_samples;
  ConcealedSamplesCorrection(rtc::dchecked_cast<int>(num_samples), true);
  lifetime_stats_.concealment_events += is_new_concealment_event;
}

void StatisticsCalculator::ExpandedNoiseSamples(size_t num_samples,
                                                bool is_new_concealment_event) {
  expanded_noise_samples_ += num_samples;
  ConcealedSamplesCorrection(rtc::dchecked_cast<int>(num_samples), false);
  lifetime_stats_.concealment_events += is_new_concealment_event;
}

void StatisticsCalculator::ExpandedVoiceSamplesCorrection(int num_samples) {
  expanded_speech_samples_ =
      AddIntToSizeTWithLowerCap(num_samples, expanded_speech_samples_);
  ConcealedSamplesCorrection(num_samples, true);
}

void StatisticsCalculator::ExpandedNoiseSamplesCorrection(int num_samples) {
  expanded_noise_samples_ =
      AddIntToSizeTWithLowerCap(num_samples, expanded_noise_samples_);
  ConcealedSamplesCorrection(num_samples, false);
}

void StatisticsCalculator::DecodedOutputPlayed() {
  decoded_output_played_ = true;
}

void StatisticsCalculator::EndExpandEvent(int fs_hz) {
  RTC_DCHECK_GE(lifetime_stats_.concealed_samples,
                concealed_samples_at_event_end_);
  const int event_duration_ms =
      1000 *
      (lifetime_stats_.concealed_samples - concealed_samples_at_event_end_) /
      fs_hz;
  if (event_duration_ms >= kInterruptionLenMs && decoded_output_played_) {
    lifetime_stats_.interruption_count++;
    lifetime_stats_.total_interruption_duration_ms += event_duration_ms;
    RTC_HISTOGRAM_COUNTS("WebRTC.Audio.AudioInterruptionMs", event_duration_ms,
                         /*min=*/150, /*max=*/5000, /*bucket_count=*/50);
  }
  concealed_samples_at_event_end_ = lifetime_stats_.concealed_samples;
}

void StatisticsCalculator::ConcealedSamplesCorrection(int num_samples,
                                                      bool is_voice) {
  if (num_samples < 0) {
    // Store negative correction to subtract from future positive additions.
    // See also the function comment in the header file.
    concealed_samples_correction_ -= num_samples;
    if (!is_voice) {
      silent_concealed_samples_correction_ -= num_samples;
    }
    return;
  }

  const size_t canceled_out =
      std::min(static_cast<size_t>(num_samples), concealed_samples_correction_);
  concealed_samples_correction_ -= canceled_out;
  lifetime_stats_.concealed_samples += num_samples - canceled_out;

  if (!is_voice) {
    const size_t silent_canceled_out = std::min(
        static_cast<size_t>(num_samples), silent_concealed_samples_correction_);
    silent_concealed_samples_correction_ -= silent_canceled_out;
    lifetime_stats_.silent_concealed_samples +=
        num_samples - silent_canceled_out;
  }
}

void StatisticsCalculator::PreemptiveExpandedSamples(size_t num_samples) {
  preemptive_samples_ += num_samples;
  operations_and_state_.preemptive_samples += num_samples;
  lifetime_stats_.inserted_samples_for_deceleration += num_samples;
}

void StatisticsCalculator::AcceleratedSamples(size_t num_samples) {
  accelerate_samples_ += num_samples;
  operations_and_state_.accelerate_samples += num_samples;
  lifetime_stats_.removed_samples_for_acceleration += num_samples;
}

void StatisticsCalculator::AddZeros(size_t num_samples) {
  added_zero_samples_ += num_samples;
}

void StatisticsCalculator::PacketsDiscarded(size_t num_packets) {
  operations_and_state_.discarded_primary_packets += num_packets;
}

void StatisticsCalculator::SecondaryPacketsDiscarded(size_t num_packets) {
  discarded_secondary_packets_ += num_packets;
  lifetime_stats_.fec_packets_discarded += num_packets;
}

void StatisticsCalculator::SecondaryPacketsReceived(size_t num_packets) {
  lifetime_stats_.fec_packets_received += num_packets;
}

void StatisticsCalculator::LostSamples(size_t num_samples) {
  lost_timestamps_ += num_samples;
}

void StatisticsCalculator::IncreaseCounter(size_t num_samples, int fs_hz) {
  const int time_step_ms =
      rtc::CheckedDivExact(static_cast<int>(1000 * num_samples), fs_hz);
  delayed_packet_outage_counter_.AdvanceClock(time_step_ms);
  excess_buffer_delay_.AdvanceClock(time_step_ms);
  buffer_full_counter_.AdvanceClock(time_step_ms);
  timestamps_since_last_report_ += static_cast<uint32_t>(num_samples);
  if (timestamps_since_last_report_ >
      static_cast<uint32_t>(fs_hz * kMaxReportPeriod)) {
    lost_timestamps_ = 0;
    timestamps_since_last_report_ = 0;
    discarded_packets_ = 0;
  }
  lifetime_stats_.total_samples_received += num_samples;
}

void StatisticsCalculator::JitterBufferDelay(size_t num_samples,
                                             uint64_t waiting_time_ms,
                                             uint64_t target_delay_ms) {
  lifetime_stats_.jitter_buffer_delay_ms += waiting_time_ms * num_samples;
  lifetime_stats_.jitter_buffer_target_delay_ms +=
      target_delay_ms * num_samples;
  lifetime_stats_.jitter_buffer_emitted_count += num_samples;
}

void StatisticsCalculator::SecondaryDecodedSamples(int num_samples) {
  secondary_decoded_samples_ += num_samples;
}

void StatisticsCalculator::FlushedPacketBuffer() {
  operations_and_state_.packet_buffer_flushes++;
  buffer_full_counter_.RegisterSample();
}

void StatisticsCalculator::ReceivedPacket() {
  ++lifetime_stats_.jitter_buffer_packets_received;
}

void StatisticsCalculator::RelativePacketArrivalDelay(size_t delay_ms) {
  lifetime_stats_.relative_packet_arrival_delay_ms += delay_ms;
}

void StatisticsCalculator::LogDelayedPacketOutageEvent(int num_samples,
                                                       int fs_hz) {
  int outage_duration_ms = num_samples / (fs_hz / 1000);
  RTC_HISTOGRAM_COUNTS("WebRTC.Audio.DelayedPacketOutageEventMs",
                       outage_duration_ms, 1 /* min */, 2000 /* max */,
                       100 /* bucket count */);
  delayed_packet_outage_counter_.RegisterSample();
  lifetime_stats_.delayed_packet_outage_samples += num_samples;
}

void StatisticsCalculator::StoreWaitingTime(int waiting_time_ms) {
  excess_buffer_delay_.RegisterSample(waiting_time_ms);
  RTC_DCHECK_LE(waiting_times_.size(), kLenWaitingTimes);
  if (waiting_times_.size() == kLenWaitingTimes) {
    // Erase first value.
    waiting_times_.pop_front();
  }
  waiting_times_.push_back(waiting_time_ms);
  operations_and_state_.last_waiting_time_ms = waiting_time_ms;
}

void StatisticsCalculator::GetNetworkStatistics(int fs_hz,
                                                size_t num_samples_in_buffers,
                                                size_t samples_per_packet,
                                                NetEqNetworkStatistics* stats) {
  RTC_DCHECK_GT(fs_hz, 0);
  RTC_DCHECK(stats);

  stats->added_zero_samples = added_zero_samples_;
  stats->current_buffer_size_ms =
      static_cast<uint16_t>(num_samples_in_buffers * 1000 / fs_hz);

  stats->packet_loss_rate =
      CalculateQ14Ratio(lost_timestamps_, timestamps_since_last_report_);

  stats->accelerate_rate =
      CalculateQ14Ratio(accelerate_samples_, timestamps_since_last_report_);

  stats->preemptive_rate =
      CalculateQ14Ratio(preemptive_samples_, timestamps_since_last_report_);

  stats->expand_rate =
      CalculateQ14Ratio(expanded_speech_samples_ + expanded_noise_samples_,
                        timestamps_since_last_report_);

  stats->speech_expand_rate = CalculateQ14Ratio(expanded_speech_samples_,
                                                timestamps_since_last_report_);

  stats->secondary_decoded_rate = CalculateQ14Ratio(
      secondary_decoded_samples_, timestamps_since_last_report_);

  const size_t discarded_secondary_samples =
      discarded_secondary_packets_ * samples_per_packet;
  stats->secondary_discarded_rate =
      CalculateQ14Ratio(discarded_secondary_samples,
                        static_cast<uint32_t>(discarded_secondary_samples +
                                              secondary_decoded_samples_));

  if (waiting_times_.size() == 0) {
    stats->mean_waiting_time_ms = -1;
    stats->median_waiting_time_ms = -1;
    stats->min_waiting_time_ms = -1;
    stats->max_waiting_time_ms = -1;
  } else {
    std::sort(waiting_times_.begin(), waiting_times_.end());
    // Find mid-point elements. If the size is odd, the two values
    // |middle_left| and |middle_right| will both be the one middle element; if
    // the size is even, they will be the the two neighboring elements at the
    // middle of the list.
    const int middle_left = waiting_times_[(waiting_times_.size() - 1) / 2];
    const int middle_right = waiting_times_[waiting_times_.size() / 2];
    // Calculate the average of the two. (Works also for odd sizes.)
    stats->median_waiting_time_ms = (middle_left + middle_right) / 2;
    stats->min_waiting_time_ms = waiting_times_.front();
    stats->max_waiting_time_ms = waiting_times_.back();
    double sum = 0;
    for (auto time : waiting_times_) {
      sum += time;
    }
    stats->mean_waiting_time_ms = static_cast<int>(sum / waiting_times_.size());
  }

  // Reset counters.
  ResetMcu();
  Reset();
}

NetEqLifetimeStatistics StatisticsCalculator::GetLifetimeStatistics() const {
  return lifetime_stats_;
}

NetEqOperationsAndState StatisticsCalculator::GetOperationsAndState() const {
  return operations_and_state_;
}

uint16_t StatisticsCalculator::CalculateQ14Ratio(size_t numerator,
                                                 uint32_t denominator) {
  if (numerator == 0) {
    return 0;
  } else if (numerator < denominator) {
    // Ratio must be smaller than 1 in Q14.
    assert((numerator << 14) / denominator < (1 << 14));
    return static_cast<uint16_t>((numerator << 14) / denominator);
  } else {
    // Will not produce a ratio larger than 1, since this is probably an error.
    return 1 << 14;
  }
}

}  // namespace webrtc
