// Copyright 2018 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "config/buckets_config.h"

#include "glog/logging.h"

namespace cobalt {
namespace config {

uint32_t IntegerBucketConfig::BucketIndex(int64_t val) const {
  // 0 is the underflow bucket.
  if (val < floors_[0]) {
    return 0;
  }

  // TODO(azani): Maybe switch to binary search?
  for (uint32_t i = 1; i < floors_.size(); i++) {
    if (val >= floors_[i-1] && val < floors_[i]) {
      return i;
    }
  }

  // floors_.size() is the overflow bucket.
  return floors_.size();
}

std::unique_ptr<IntegerBucketConfig> IntegerBucketConfig::CreateFromProto(
    const IntegerBuckets& int_buckets) {
  switch (int_buckets.buckets_case()) {
    case IntegerBuckets::kExponential:
      return CreateExponential(int_buckets.exponential().floor(),
                               int_buckets.exponential().num_buckets(),
                               int_buckets.exponential().initial_step(),
                               int_buckets.exponential().step_multiplier());

    case IntegerBuckets::kLinear:
      return CreateLinear(int_buckets.linear().floor(),
                          int_buckets.linear().num_buckets(),
                          int_buckets.linear().step_size());

    case IntegerBuckets::BUCKETS_NOT_SET:
      LOG(ERROR) << "IntegerBuckets with buckets field not set.";
      return std::unique_ptr<IntegerBucketConfig>();
  }
}

std::unique_ptr<IntegerBucketConfig> IntegerBucketConfig::CreateLinear(
    int64_t floor, uint32_t num_buckets, uint32_t step_size) {
  if (num_buckets == 0) {
    LOG(ERROR) << "LinearIntegerBucket with 0 buckets.";
    return std::unique_ptr<IntegerBucketConfig>();
  }

  if (step_size == 0) {
    LOG(ERROR) << "LinearIntegerBucket with 0 step size.";
    return std::unique_ptr<IntegerBucketConfig>();
  }

  std::vector<int64_t> floors(num_buckets + 1);
  for (uint32_t i = 0; i < num_buckets+1; i++) {
    floors[i] = floor + i * step_size;
  }

  return std::unique_ptr<IntegerBucketConfig>(new IntegerBucketConfig(floors));
}

std::unique_ptr<IntegerBucketConfig> IntegerBucketConfig::CreateExponential(
    int64_t floor, uint32_t num_buckets, uint32_t initial_step,
    uint32_t step_multiplier) {
  if (num_buckets == 0) {
    LOG(ERROR)
        << "ExponentialIntegerBucket with 0 buckets.";
    return std::unique_ptr<IntegerBucketConfig>();
  }

  if (initial_step == 0) {
    LOG(ERROR) << "ExponentialIntegerBucket with 0 initial_step.";
    return std::unique_ptr<IntegerBucketConfig>();
  }

  if (step_multiplier == 0) {
    LOG(ERROR) << "ExponentialIntegerBucket with 0 step_multiplier.";
    return std::unique_ptr<IntegerBucketConfig>();
  }

  std::vector<int64_t> floors(num_buckets + 1);

  floors[0] = floor;
  uint32_t offset = initial_step;
  for (uint32_t i = 1; i < num_buckets+1; i++) {
    floors[i] = floor + offset;
    offset *= step_multiplier;
  }
  return std::unique_ptr<IntegerBucketConfig>(new IntegerBucketConfig(floors));
}
}  // namespace config
}  // namespace cobalt
