/*
 *
 * Copyright 2020 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 adaptive

import (
	"testing"
	"time"
)

func TestLookback(t *testing.T) {
	makeTicks := func(offsets []int64) []time.Time {
		var ticks []time.Time
		now := time.Now()
		for _, offset := range offsets {
			ticks = append(ticks, now.Add(time.Duration(offset)))
		}
		return ticks
	}

	// lookback.add and lookback.sum behave correctly.
	testcases := []struct {
		desc   string
		bins   int64
		ticks  []time.Time
		values []int64
		want   []int64
	}{
		{
			"Accumulate",
			3,
			makeTicks([]int64{0, 1, 2}), // Ticks
			[]int64{1, 2, 3},            // Values
			[]int64{1, 3, 6},            // Want
		},
		{
			"LightTimeTravel",
			3,
			makeTicks([]int64{1, 0, 2}), // Ticks
			[]int64{1, 2, 3},            // Values
			[]int64{1, 3, 6},            // Want
		},
		{
			"HeavyTimeTravel",
			3,
			makeTicks([]int64{8, 0, 9}), // Ticks
			[]int64{1, 2, 3},            // Values
			[]int64{1, 1, 4},            // Want
		},
		{
			"Rollover",
			1,
			makeTicks([]int64{0, 1, 2}), // Ticks
			[]int64{1, 2, 3},            // Values
			[]int64{1, 2, 3},            // Want
		},
	}

	for _, test := range testcases {
		t.Run(test.desc, func(t *testing.T) {
			lb := newLookback(test.bins, time.Duration(test.bins))
			for i, tick := range test.ticks {
				lb.add(tick, test.values[i])
				if got := lb.sum(tick); got != test.want[i] {
					t.Errorf("sum for index %d got %d, want %d", i, got, test.want[i])
				}
			}
		})
	}
}
