package testutil

import (
	"bytes"
	"fmt"
	"io"
	"math"
	"time"

	"veyron.io/veyron/veyron/lib/stats/histogram"
)

// BenchStats is a simple helper for gathering additional statistics
// like histogram during benchmarks. This is not thread safe.
type BenchStats struct {
	numBuckets int
	unit       time.Duration
	min, max   int64
	histogram  *histogram.Histogram

	durations durationSlice
	dirty     bool
}

type durationSlice []time.Duration

// NewBenchStats creates a new BenchStats instance. If numBuckets is not
// positive, the default value (16) will be used.
func NewBenchStats(numBuckets int) *BenchStats {
	if numBuckets <= 0 {
		numBuckets = 16
	}
	return &BenchStats{
		// Use one more bucket for the last unbounded bucket.
		numBuckets: numBuckets + 1,
		durations:  make(durationSlice, 0, 100000),
	}
}

// Add adds an elapsed time per operation to the BenchStats.
func (stats *BenchStats) Add(d time.Duration) {
	stats.durations = append(stats.durations, d)
	stats.dirty = true
}

// Clear resets the stats, removing all values.
func (stats *BenchStats) Clear() {
	stats.durations = stats.durations[:0]
	stats.dirty = true
}

// maybeUpdate updates internal stat data if there was any newly added
// stats since this was updated.
func (stats *BenchStats) maybeUpdate() {
	if !stats.dirty || len(stats.durations) == 0 {
		return
	}

	stats.min = math.MaxInt64
	stats.max = 0
	for _, d := range stats.durations {
		if stats.min > int64(d) {
			stats.min = int64(d)
		}
		if stats.max < int64(d) {
			stats.max = int64(d)
		}
	}

	// Use the largest unit that can represent the minimum time duration.
	stats.unit = time.Nanosecond
	for _, u := range []time.Duration{time.Microsecond, time.Millisecond, time.Second} {
		if stats.min <= int64(u) {
			break
		}
		stats.unit = u
	}

	// Adjust the min/max according to the new unit.
	stats.min /= int64(stats.unit)
	stats.max /= int64(stats.unit)

	stats.histogram = histogram.New(histogram.Options{
		NumBuckets: stats.numBuckets,
		// max(i.e., Nth lower bound) = min + (1 + growthFactor)^(numBuckets-2).
		GrowthFactor:       math.Pow(float64(stats.max-stats.min), 1/float64(stats.numBuckets-2)) - 1,
		SmallestBucketSize: 1.0,
		MinValue:           stats.min})

	for _, d := range stats.durations {
		stats.histogram.Add(int64(d / stats.unit))
	}

	stats.dirty = false
}

// Print writes textual output of the BenchStats.
func (stats *BenchStats) Print(w io.Writer) {
	stats.maybeUpdate()

	fmt.Fprintf(w, "Histogram (unit: %s)\n", fmt.Sprintf("%v", stats.unit)[1:])
	stats.histogram.Value().Print(w)
}

// String returns the textual output of the BenchStats as string.
func (stats *BenchStats) String() string {
	var b bytes.Buffer
	stats.Print(&b)
	return b.String()
}
