// Copyright 2014 The Bazel 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.
package com.google.devtools.build.lib.profiler;

import com.google.common.base.Preconditions;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.Range;
import com.google.devtools.build.lib.concurrent.ThreadSafety.ThreadSafe;
import com.google.devtools.build.lib.profiler.MetricData.HistogramElement;
import java.util.concurrent.atomic.AtomicIntegerArray;
import java.util.concurrent.atomic.AtomicLong;
import java.util.concurrent.atomic.LongAccumulator;

/**
 * A stat recorder that can record time histograms, count of calls, average time, Std. Deviation
 * and max time.
 */
@ThreadSafe
public class SingleStatRecorder implements StatRecorder {

  private final int buckets;
  private final Object description;
  private final AtomicIntegerArray histogram;
  private final AtomicLong sum = new AtomicLong(0);
  private final AtomicLong sumSquared = new AtomicLong(0);
  private final LongAccumulator max = new LongAccumulator(Math::max, -1);

  public SingleStatRecorder(Object description, int buckets) {
    this.description = description;
    Preconditions.checkArgument(buckets > 1, "At least two buckets (one for bellow start and one"
        + "for above start) are required");
    this.buckets = buckets;
    histogram = new AtomicIntegerArray(buckets);
  }

  /** Create an snapshot of the stats recorded up to now. */
  public MetricData snapshot() {
    ImmutableList.Builder<HistogramElement> result = ImmutableList.builder();
    result.add(new HistogramElement(Range.closedOpen(0, 1), histogram.get(0)));
    int from = 1;
    for (int i = 1; i < histogram.length() - 1; i++) {
      int to = from << 1;
      result.add(new HistogramElement(Range.closedOpen(from, to), histogram.get(i)));
      from = to;
    }
    result.add(new HistogramElement(Range.atLeast(from), histogram.get(histogram.length() - 1)));
    int n = 0;
    for (int i = 0; i < histogram.length(); i++) {
      n += histogram.get(i);
    }
    double stddev;
    if (n == 1) {
      stddev = 0;
    } else {
      stddev = Math.sqrt((sumSquared.longValue() - sum.get() * sum.doubleValue() / n) / n);
    }
    return new MetricData(
        description, result.build(), n, sum.doubleValue() / n, stddev, max.intValue());
  }

  @Override
  public void addStat(int duration, Object obj) {
    int histogramBucket = Math.min(32 - Integer.numberOfLeadingZeros(duration), buckets - 1);
    sum.addAndGet(duration);
    sumSquared.addAndGet(duration * duration);
    max.accumulate(duration);
    histogram.incrementAndGet(histogramBucket);
  }

  @Override
  public boolean isEmpty() {
    return snapshot().getCount() == 0;
  }

  @Override
  public String toString() {
    return snapshot().toString();
  }
}
