/*
 *  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 <string.h>  // memset

#include <algorithm>

#include "absl/strings/string_view.h"
#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(
    absl::string_view 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(
    absl::string_view 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(
    absl::string_view 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(TickTimer* tick_timer)
    : preemptive_samples_(0),
      accelerate_samples_(0),
      expanded_speech_samples_(0),
      expanded_noise_samples_(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),
      expand_uma_logger_("WebRTC.Audio.ExpandRatePercent",
                         10,  // Report once every 10 s.
                         tick_timer),
      speech_expand_uma_logger_("WebRTC.Audio.SpeechExpandRatePercent",
                                10,  // Report once every 10 s.
                                tick_timer) {}

StatisticsCalculator::~StatisticsCalculator() = default;

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

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

void StatisticsCalculator::ExpandedVoiceSamples(size_t num_samples,
                                                bool is_new_concealment_event) {
  if (!decoded_output_played_) {
    return;
  }
  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) {
  if (!decoded_output_played_) {
    return;
  }
  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) {
  if (!decoded_output_played_) {
    return;
  }
  expanded_speech_samples_ =
      AddIntToSizeTWithLowerCap(num_samples, expanded_speech_samples_);
  ConcealedSamplesCorrection(num_samples, true);
}

void StatisticsCalculator::ExpandedNoiseSamplesCorrection(int num_samples) {
  if (!decoded_output_played_) {
    return;
  }
  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) {
  if (!decoded_output_played_) {
    return;
  }
  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 (!decoded_output_played_) {
    return;
  }
  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) {
  if (!decoded_output_played_) {
    return;
  }
  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) {
  if (!decoded_output_played_) {
    return;
  }
  accelerate_samples_ += num_samples;
  operations_and_state_.accelerate_samples += num_samples;
  lifetime_stats_.removed_samples_for_acceleration += num_samples;
}

void StatisticsCalculator::GeneratedNoiseSamples(size_t num_samples) {
  if (!decoded_output_played_) {
    return;
  }
  lifetime_stats_.generated_noise_samples += num_samples;
}

void StatisticsCalculator::PacketsDiscarded(size_t num_packets) {
  lifetime_stats_.packets_discarded += 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::IncreaseCounter(size_t num_samples, int fs_hz) {
  if (!decoded_output_played_) {
    return;
  }
  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)) {
    timestamps_since_last_report_ = 0;
  }
  lifetime_stats_.total_samples_received += num_samples;
  expand_uma_logger_.UpdateSampleCounter(lifetime_stats_.concealed_samples,
                                         fs_hz);
  uint64_t speech_concealed_samples = 0;
  if (lifetime_stats_.concealed_samples >
      lifetime_stats_.silent_concealed_samples) {
    speech_concealed_samples = lifetime_stats_.concealed_samples -
                               lifetime_stats_.silent_concealed_samples;
  }
  speech_expand_uma_logger_.UpdateSampleCounter(speech_concealed_samples,
                                                fs_hz);
}

void StatisticsCalculator::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) {
  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_minimum_delay_ms +=
      unlimited_target_delay_ms * num_samples;
  lifetime_stats_.jitter_buffer_emitted_count += num_samples;
  lifetime_stats_.total_processing_delay_us +=
      num_samples * processing_delay_us;
}

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;
  ++lifetime_stats_.delayed_packet_outage_events;
}

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(size_t samples_per_packet,
                                                NetEqNetworkStatistics* stats) {
  RTC_DCHECK(stats);

  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.
    RTC_DCHECK_LT((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
