/*
 *
 * Copyright 2019 gRPC authors.
 *
 * 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 wrr

import (
	"errors"
	"math"
	"math/rand"
	"strconv"
	"testing"

	"github.com/google/go-cmp/cmp"
	"google.golang.org/grpc/internal/grpctest"
)

type s struct {
	grpctest.Tester
}

func Test(t *testing.T) {
	grpctest.RunSubTests(t, s{})
}

const iterCount = 10000

func equalApproximate(a, b float64) error {
	opt := cmp.Comparer(func(x, y float64) bool {
		delta := math.Abs(x - y)
		mean := math.Abs(x+y) / 2.0
		return delta/mean < 0.05
	})
	if !cmp.Equal(a, b, opt) {
		return errors.New(cmp.Diff(a, b))
	}
	return nil
}

func testWRRNext(t *testing.T, newWRR func() WRR) {
	tests := []struct {
		name    string
		weights []int64
	}{
		{
			name:    "1-1-1",
			weights: []int64{1, 1, 1},
		},
		{
			name:    "1-2-3",
			weights: []int64{1, 2, 3},
		},
		{
			name:    "5-3-2",
			weights: []int64{5, 3, 2},
		},
		{
			name:    "17-23-37",
			weights: []int64{17, 23, 37},
		},
		{
			name:    "no items",
			weights: []int64{},
		},
	}
	for _, tt := range tests {
		t.Run(tt.name, func(t *testing.T) {
			w := newWRR()
			if len(tt.weights) == 0 {
				if next := w.Next(); next != nil {
					t.Fatalf("w.Next returns non nil value:%v when there is no item", next)
				}
				return
			}

			var sumOfWeights int64
			for i, weight := range tt.weights {
				w.Add(i, weight)
				sumOfWeights += weight
			}

			results := make(map[int]int)
			for i := 0; i < iterCount; i++ {
				results[w.Next().(int)]++
			}

			wantRatio := make([]float64, len(tt.weights))
			for i, weight := range tt.weights {
				wantRatio[i] = float64(weight) / float64(sumOfWeights)
			}
			gotRatio := make([]float64, len(tt.weights))
			for i, count := range results {
				gotRatio[i] = float64(count) / iterCount
			}

			for i := range wantRatio {
				if err := equalApproximate(gotRatio[i], wantRatio[i]); err != nil {
					t.Errorf("%v not equal %v", i, err)
				}
			}
		})
	}
}

func (s) TestRandomWRRNext(t *testing.T) {
	testWRRNext(t, NewRandom)
}

func (s) TestEdfWrrNext(t *testing.T) {
	testWRRNext(t, NewEDF)
}

func BenchmarkRandomWRRNext(b *testing.B) {
	for _, n := range []int{100, 500, 1000} {
		b.Run("equal-weights-"+strconv.Itoa(n)+"-items", func(b *testing.B) {
			w := NewRandom()
			sumOfWeights := n
			for i := 0; i < n; i++ {
				w.Add(i, 1)
			}
			b.ResetTimer()
			for i := 0; i < b.N; i++ {
				for i := 0; i < sumOfWeights; i++ {
					w.Next()
				}
			}
		})
	}

	var maxWeight int64 = 1024
	for _, n := range []int{100, 500, 1000} {
		b.Run("random-weights-"+strconv.Itoa(n)+"-items", func(b *testing.B) {
			w := NewRandom()
			var sumOfWeights int64
			for i := 0; i < n; i++ {
				weight := rand.Int63n(maxWeight + 1)
				w.Add(i, weight)
				sumOfWeights += weight
			}
			b.ResetTimer()
			for i := 0; i < b.N; i++ {
				for i := 0; i < int(sumOfWeights); i++ {
					w.Next()
				}
			}
		})
	}

	itemsNum := 200
	heavyWeight := int64(itemsNum)
	lightWeight := int64(1)
	heavyIndices := []int{0, itemsNum / 2, itemsNum - 1}
	for _, heavyIndex := range heavyIndices {
		b.Run("skew-weights-heavy-index-"+strconv.Itoa(heavyIndex), func(b *testing.B) {
			w := NewRandom()
			var sumOfWeights int64
			for i := 0; i < itemsNum; i++ {
				var weight int64
				if i == heavyIndex {
					weight = heavyWeight
				} else {
					weight = lightWeight
				}
				sumOfWeights += weight
				w.Add(i, weight)
			}
			b.ResetTimer()
			for i := 0; i < b.N; i++ {
				for i := 0; i < int(sumOfWeights); i++ {
					w.Next()
				}
			}
		})
	}
}

func init() {
	r := rand.New(rand.NewSource(0))
	grpcrandInt63n = r.Int63n
}
