// Copyright 2022 The Cobalt Authors. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#ifndef COBALT_BASE_STATISTICS_H_
#define COBALT_BASE_STATISTICS_H_

#include <algorithm>
#include <functional>
#include <string>
#include <vector>

#include "cobalt/base/c_val.h"
#include "starboard/types.h"

namespace base {

namespace internal {

// The default function to convert a sample to its value by dividing.
inline int64_t DefaultSampleToValueFunc(int64_t dividend, int64_t divisor) {
  if (divisor == 0) {
    divisor = 1;
  }
  return dividend / divisor;
}

}  // namespace internal

// Track the statistics of a series of generic samples reprensented as
// dividends and divisors in integer types.  The value of a sample is calculated
// by `SampleToValueFunc` using its dividend and divisor.
//
// Example usages:
//   1. Set dividends to bytes in int and divisors to int64_t, to track the
//      statistics of bandwidth.
//   2. Set the divisor to always be 1, to track the statistics of a count or a
//      duration.
//
// Currently the class can produce the following statistics:
//   1. Average, tracked across all samples.
//   2. Median, tracked across the most recent |MaxSamples| samples.
//   3. Min, tracked across all samples.
//   4. Max, tracked across all samples.
//
// Notes:
//   1. The accumulated values are stored in `int64_t`, and it is the user's
//      responsibility to avoid overflow.
//   2. The class isn't multi-thread safe, and it is the user's responsibility
//      to synchronize the usage when necessary.
//   3. Both the dividend and divisor of the samples should ideally be positive,
//      which is NOT enforced by the class.

#if defined(COBALT_BUILD_TYPE_GOLD)

template <typename DividendType, typename DivisorType, int MaxSamples,
          int64_t (*SampleToValueFunc)(int64_t, int64_t) =
              internal::DefaultSampleToValueFunc>
class Statistics {
 public:
  explicit Statistics(const std::string& metric_name) {}

  void AddSample(DividendType dividend, DivisorType divisor) {}
  int64_t accumulated_dividend() const { return 0; }
  int64_t accumulated_divisor() const { return 1; }
  int64_t average() const { return 0; }
  int64_t min() const { return 0; }
  int64_t max() const { return 0; }

  int64_t GetMedian() const { return 0; }
};

#else  // defined(COBALT_BUILD_TYPE_GOLD)

template <typename DividendType, typename DivisorType, size_t MaxSamples,
          int64_t (*SampleToValueFunc)(int64_t, int64_t) =
              internal::DefaultSampleToValueFunc>
class Statistics {
 public:
  explicit Statistics(const std::string& metric_name)
      : last_sample_value_(metric_name + ".Latest", 0,
                           metric_name + " most recent value."),
        median_sample_value_(metric_name + ".Median", 0,
                             metric_name + " median value.") {}

  void AddSample(DividendType dividend, DivisorType divisor) {
    static_assert(MaxSamples > 0, "MaxSamples has to be greater than 0.");

    auto& current =
        samples_[(first_sample_index_ + number_of_samples_) % MaxSamples];
    if (number_of_samples_ == MaxSamples) {
      first_sample_index_ = (first_sample_index_ + 1) % MaxSamples;
    } else {
      ++number_of_samples_;
    }

    current.dividend = dividend;
    current.divisor = divisor;
    accumulated_dividend_ += dividend;
    accumulated_divisor_ += divisor;

    auto value = GetSampleValue(current);
    if (first_sample_added_) {
      min_ = std::min(min_, value);
      max_ = std::max(max_, value);
    } else {
      min_ = max_ = value;
      first_sample_added_ = true;
    }
    last_sample_value_ = value;
    // TODO(b/258531018) this should be optimized in future.
    median_sample_value_ = GetMedian();
  }

  int64_t accumulated_dividend() const { return accumulated_dividend_; }
  int64_t accumulated_divisor() const { return accumulated_divisor_; }

  int64_t average() const {
    return SampleToValueFunc(accumulated_dividend_, accumulated_divisor_);
  }
  int64_t min() const { return min_; }
  int64_t max() const { return max_; }

  // When there are even number of samples in the object, it is implementation
  // specific to pick any number close to the middle, or the median of the
  // numbers close to the middle.  Use {1, 2, 3, 4} as an example, the median
  // can be 3, or 4, or 3.5.
  int64_t GetMedian() const {
    if (number_of_samples_ == 0) {
      return 0;
    }

    std::vector<Sample> copy;
    copy.reserve(number_of_samples_);
    if (first_sample_index_ + number_of_samples_ <= MaxSamples) {
      copy.assign(samples_ + first_sample_index_,
                  samples_ + first_sample_index_ + number_of_samples_);
    } else {
      auto samples_to_copy = number_of_samples_;
      copy.assign(samples_ + first_sample_index_, samples_ + MaxSamples);
      samples_to_copy -= MaxSamples - first_sample_index_;
      copy.insert(copy.end(), samples_, samples_ + samples_to_copy);
    }

    std::nth_element(copy.begin(), copy.begin() + number_of_samples_ / 2,
                     copy.end(), [](const Sample& left, const Sample& right) {
                       return GetSampleValue(left) < GetSampleValue(right);
                     });
    return GetSampleValue(copy[number_of_samples_ / 2]);
  }

 private:
  Statistics(const Statistics&) = delete;
  Statistics& operator=(const Statistics&) = delete;

  struct Sample {
    DividendType dividend = 0;
    DivisorType divisor = 0;
  };

  static int64_t GetSampleValue(const Sample& sample) {
    return SampleToValueFunc(static_cast<int64_t>(sample.dividend),
                             static_cast<int64_t>(sample.divisor));
  }

  bool first_sample_added_ = false;

  int64_t accumulated_dividend_ = 0;
  int64_t accumulated_divisor_ = 0;
  int64_t min_ = 0;
  int64_t max_ = 0;

  Sample samples_[MaxSamples] = {};  // Ring buffer for samples.
  size_t number_of_samples_ = 0;     // Number of samples in |samples_|.
  size_t first_sample_index_ = 0;    // Index of the first sample in |samples_|.

  base::CVal<int64_t> last_sample_value_;
  base::CVal<int64_t> median_sample_value_;
};

#endif  // defined(COBALT_BUILD_TYPE_GOLD)

}  // namespace base

#endif  // COBALT_BASE_STATISTICS_H_
