package bench

import (
	"fmt"
	"testing"
)

type Target struct {
	//这里定义需要测试的方法
	Set func()
	Get func()
}

//测试基准
type Benchmark struct {
	Parallelism   int         //并行数目
	Data          interface{} //bench 参数数据
	TargetBuilder TargetBuilder
}

//构建基准目标
type TargetBuilder struct {
	Name string
	Make func(bench Benchmark) (Target, error)
}

func compose(parallelisms, dataSize []int, numKeys int, builders []TargetBuilder) []Benchmark {
	benchmarks := make([]Benchmark, 0, len(parallelisms)*len(dataSize)*len(builders))

	for _, p := range parallelisms {
		for range dataSize {

			for _, builder := range builders {
				benchmarks = append(benchmarks, Benchmark{
					Parallelism: p,
					// Data:          d,
					TargetBuilder: builder,
				})
			}

		}
	}

	return benchmarks
}

func RunBenchmark(b *testing.B, benchmarks []Benchmark) {
	for _, bench := range benchmarks {
		bench := bench
		b.Run(fmt.Sprintf("%s-parallelism(%d)- ", bench.TargetBuilder.Name, bench.Parallelism), func(b *testing.B) {
			target, err := bench.TargetBuilder.Make(bench)
			if err != nil {
				b.Fatalf("%s setup fail: %v", bench.TargetBuilder.Name, err)
			}
			if bench.Parallelism == 0 {
				b.ResetTimer()
				for i := 0; i < b.N; i++ {
					//执行测试方法
					target.Get()
				}

			} else {
				b.SetParallelism(bench.Parallelism) //指定并行数目
				b.ResetTimer()
				b.RunParallel(func(pb *testing.PB) { //并行执行
					for pb.Next() {
						//执行测试方法
						target.Get()
					}
				})
			}
			b.StopTimer()
		})
	}
}
