/*
 *  Copyright (c) 2018 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 "api/numerics/samples_stats_counter.h"

#include <algorithm>
#include <cmath>

#include "absl/algorithm/container.h"
#include "rtc_base/time_utils.h"

namespace webrtc {

SamplesStatsCounter::SamplesStatsCounter() = default;
SamplesStatsCounter::SamplesStatsCounter(size_t expected_samples_count) {
  samples_.reserve(expected_samples_count);
}

SamplesStatsCounter::~SamplesStatsCounter() = default;
SamplesStatsCounter::SamplesStatsCounter(const SamplesStatsCounter&) = default;
SamplesStatsCounter& SamplesStatsCounter::operator=(
    const SamplesStatsCounter&) = default;
SamplesStatsCounter::SamplesStatsCounter(SamplesStatsCounter&&) = default;
SamplesStatsCounter& SamplesStatsCounter::operator=(SamplesStatsCounter&&) =
    default;

void SamplesStatsCounter::AddSample(double value) {
  AddSample(StatsSample{value, Timestamp::Micros(rtc::TimeMicros())});
}

void SamplesStatsCounter::AddSample(StatsSample sample) {
  stats_.AddSample(sample.value);
  samples_.push_back(sample);
  sorted_ = false;
}

void SamplesStatsCounter::AddSamples(const SamplesStatsCounter& other) {
  stats_.MergeStatistics(other.stats_);
  samples_.insert(samples_.end(), other.samples_.begin(), other.samples_.end());
  sorted_ = false;
}

double SamplesStatsCounter::GetPercentile(double percentile) {
  RTC_DCHECK(!IsEmpty());
  RTC_CHECK_GE(percentile, 0);
  RTC_CHECK_LE(percentile, 1);
  if (!sorted_) {
    absl::c_sort(samples_, [](const StatsSample& a, const StatsSample& b) {
      return a.value < b.value;
    });
    sorted_ = true;
  }
  const double raw_rank = percentile * (samples_.size() - 1);
  double int_part;
  double fract_part = std::modf(raw_rank, &int_part);
  size_t rank = static_cast<size_t>(int_part);
  if (fract_part >= 1.0) {
    // It can happen due to floating point calculation error.
    rank++;
    fract_part -= 1.0;
  }

  RTC_DCHECK_GE(rank, 0);
  RTC_DCHECK_LT(rank, samples_.size());
  RTC_DCHECK_GE(fract_part, 0);
  RTC_DCHECK_LT(fract_part, 1);
  RTC_DCHECK(rank + fract_part == raw_rank);

  const double low = samples_[rank].value;
  const double high = samples_[std::min(rank + 1, samples_.size() - 1)].value;
  return low + fract_part * (high - low);
}

SamplesStatsCounter operator*(const SamplesStatsCounter& counter,
                              double value) {
  SamplesStatsCounter out;
  for (const auto& sample : counter.GetTimedSamples()) {
    out.AddSample(
        SamplesStatsCounter::StatsSample{sample.value * value, sample.time});
  }
  return out;
}

SamplesStatsCounter operator/(const SamplesStatsCounter& counter,
                              double value) {
  SamplesStatsCounter out;
  for (const auto& sample : counter.GetTimedSamples()) {
    out.AddSample(
        SamplesStatsCounter::StatsSample{sample.value / value, sample.time});
  }
  return out;
}

}  // namespace webrtc
