package quantiles

import "sort"

// Constructs a new quantile estimator which returns exact values for
// quantiles. It stores all values in memory and sorts them when asked
// to compute a quantile.
func NewExactQuantileEstimator() QuantileEstimator {
	return &exactQuantile{}
}

type exactQuantile struct {
	vals []float64
}

func (eq *exactQuantile) Add(val float64, weight int) {
	// common case
	if weight == 1 {
		eq.vals = append(eq.vals, val)
		return
	}
	for i := 0; i < weight; i++ {
		eq.vals = append(eq.vals, val)
	}
}

func (eq *exactQuantile) Quantile(q float64) float64 {
	if len(eq.vals) == 0 {
		return 0
	}
	if q < 0 {
		q = 0
	} else if q > 1 {
		q = 1
	}
	sort.Float64s(eq.vals)
	idx := int(float64(len(eq.vals)) * q)
	if idx == len(eq.vals) {
		idx = len(eq.vals) - 1
	}
	return eq.vals[idx]
}
