// Copyright 2013 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package testing_test

import (
	"bytes"
	"cmp"
	"context"
	"errors"
	"internal/asan"
	"internal/msan"
	"internal/race"
	"internal/testenv"
	"runtime"
	"slices"
	"strings"
	"sync/atomic"
	"testing"
	"text/template"
	"time"
)

var prettyPrintTests = []struct {
	v        float64
	expected string
}{
	{0, "         0 x"},
	{1234.1, "      1234 x"},
	{-1234.1, "     -1234 x"},
	{999.950001, "      1000 x"},
	{999.949999, "       999.9 x"},
	{99.9950001, "       100.0 x"},
	{99.9949999, "        99.99 x"},
	{-99.9949999, "       -99.99 x"},
	{0.000999950001, "         0.001000 x"},
	{0.000999949999, "         0.0009999 x"}, // smallest case
	{0.0000999949999, "         0.0001000 x"},
}

func TestPrettyPrint(t *testing.T) {
	for _, tt := range prettyPrintTests {
		buf := new(strings.Builder)
		testing.PrettyPrint(buf, tt.v, "x")
		if tt.expected != buf.String() {
			t.Errorf("prettyPrint(%v): expected %q, actual %q", tt.v, tt.expected, buf.String())
		}
	}
}

func TestResultString(t *testing.T) {
	// Test fractional ns/op handling
	r := testing.BenchmarkResult{
		N: 100,
		T: 240 * time.Nanosecond,
	}
	if r.NsPerOp() != 2 {
		t.Errorf("NsPerOp: expected 2, actual %v", r.NsPerOp())
	}
	if want, got := "     100\t         2.400 ns/op", r.String(); want != got {
		t.Errorf("String: expected %q, actual %q", want, got)
	}

	// Test sub-1 ns/op (issue #31005)
	r.T = 40 * time.Nanosecond
	if want, got := "     100\t         0.4000 ns/op", r.String(); want != got {
		t.Errorf("String: expected %q, actual %q", want, got)
	}

	// Test 0 ns/op
	r.T = 0
	if want, got := "     100", r.String(); want != got {
		t.Errorf("String: expected %q, actual %q", want, got)
	}
}

func TestRunParallel(t *testing.T) {
	if testing.Short() {
		t.Skip("skipping in short mode")
	}
	testing.Benchmark(func(b *testing.B) {
		procs := uint32(0)
		iters := uint64(0)
		b.SetParallelism(3)
		b.RunParallel(func(pb *testing.PB) {
			atomic.AddUint32(&procs, 1)
			for pb.Next() {
				atomic.AddUint64(&iters, 1)
			}
		})
		if want := uint32(3 * runtime.GOMAXPROCS(0)); procs != want {
			t.Errorf("got %v procs, want %v", procs, want)
		}
		if iters != uint64(b.N) {
			t.Errorf("got %v iters, want %v", iters, b.N)
		}
	})
}

func TestRunParallelFail(t *testing.T) {
	testing.Benchmark(func(b *testing.B) {
		b.RunParallel(func(pb *testing.PB) {
			// The function must be able to log/abort
			// w/o crashing/deadlocking the whole benchmark.
			b.Log("log")
			b.Error("error")
		})
	})
}

func TestRunParallelFatal(t *testing.T) {
	testing.Benchmark(func(b *testing.B) {
		b.RunParallel(func(pb *testing.PB) {
			for pb.Next() {
				if b.N > 1 {
					b.Fatal("error")
				}
			}
		})
	})
}

func TestRunParallelSkipNow(t *testing.T) {
	testing.Benchmark(func(b *testing.B) {
		b.RunParallel(func(pb *testing.PB) {
			for pb.Next() {
				if b.N > 1 {
					b.SkipNow()
				}
			}
		})
	})
}

func TestBenchmarkContext(t *testing.T) {
	testing.Benchmark(func(b *testing.B) {
		ctx := b.Context()
		if err := ctx.Err(); err != nil {
			b.Fatalf("expected non-canceled context, got %v", err)
		}

		var innerCtx context.Context
		b.Run("inner", func(b *testing.B) {
			innerCtx = b.Context()
			if err := innerCtx.Err(); err != nil {
				b.Fatalf("expected inner benchmark to not inherit canceled context, got %v", err)
			}
		})
		b.Run("inner2", func(b *testing.B) {
			if !errors.Is(innerCtx.Err(), context.Canceled) {
				t.Fatal("expected context of sibling benchmark to be canceled after its test function finished")
			}
		})

		t.Cleanup(func() {
			if !errors.Is(ctx.Err(), context.Canceled) {
				t.Fatal("expected context canceled before cleanup")
			}
		})
	})
}

// Some auxiliary functions for measuring allocations in a b.Loop benchmark below,
// where in this case mid-stack inlining allows stack allocation of a slice.
// This is based on the example in go.dev/issue/73137.

func newX() []byte {
	out := make([]byte, 8)
	return use1(out)
}

//go:noinline
func use1(out []byte) []byte {
	return out
}

// An auxiliary function for measuring allocations with a simple function argument
// in the b.Loop body.

//go:noinline
func use2(x any) {}

func TestBenchmarkBLoopAllocs(t *testing.T) {
	testenv.SkipIfOptimizationOff(t)
	if race.Enabled || asan.Enabled || msan.Enabled {
		t.Skip("skipping in case sanitizers alter allocation behavior")
	}

	t.Run("call-result", func(t *testing.T) {
		bRet := testing.Benchmark(func(b *testing.B) {
			b.ReportAllocs()
			for b.Loop() {
				newX()
			}
		})
		if bRet.N == 0 {
			t.Fatalf("benchmark reported 0 iterations")
		}
		if bRet.AllocsPerOp() != 0 {
			t.Errorf("want 0 allocs, got %d", bRet.AllocsPerOp())
		}
	})

	t.Run("call-arg", func(t *testing.T) {
		bRet := testing.Benchmark(func(b *testing.B) {
			b.ReportAllocs()
			for b.Loop() {
				use2(make([]byte, 1000))
			}
		})
		if bRet.N == 0 {
			t.Fatalf("benchmark reported 0 iterations")
		}
		if bRet.AllocsPerOp() != 0 {
			t.Errorf("want 0 allocs, got %d", bRet.AllocsPerOp())
		}
	})
}

func ExampleB_RunParallel() {
	// Parallel benchmark for text/template.Template.Execute on a single object.
	testing.Benchmark(func(b *testing.B) {
		templ := template.Must(template.New("test").Parse("Hello, {{.}}!"))
		// RunParallel will create GOMAXPROCS goroutines
		// and distribute work among them.
		b.RunParallel(func(pb *testing.PB) {
			// Each goroutine has its own bytes.Buffer.
			var buf bytes.Buffer
			for pb.Next() {
				// The loop body is executed b.N times total across all goroutines.
				buf.Reset()
				templ.Execute(&buf, "World")
			}
		})
	})
}

func TestReportMetric(t *testing.T) {
	res := testing.Benchmark(func(b *testing.B) {
		b.ReportMetric(12345, "ns/op")
		b.ReportMetric(0.2, "frobs/op")
	})
	// Test built-in overriding.
	if res.NsPerOp() != 12345 {
		t.Errorf("NsPerOp: expected %v, actual %v", 12345, res.NsPerOp())
	}
	// Test stringing.
	res.N = 1 // Make the output stable
	want := "       1\t     12345 ns/op\t         0.2000 frobs/op"
	if want != res.String() {
		t.Errorf("expected %q, actual %q", want, res.String())
	}
}

func ExampleB_ReportMetric() {
	// This reports a custom benchmark metric relevant to a
	// specific algorithm (in this case, sorting).
	testing.Benchmark(func(b *testing.B) {
		var compares int64
		for b.Loop() {
			s := []int{5, 4, 3, 2, 1}
			slices.SortFunc(s, func(a, b int) int {
				compares++
				return cmp.Compare(a, b)
			})
		}
		// This metric is per-operation, so divide by b.N and
		// report it as a "/op" unit.
		b.ReportMetric(float64(compares)/float64(b.N), "compares/op")
		// This metric is per-time, so divide by b.Elapsed and
		// report it as a "/ns" unit.
		b.ReportMetric(float64(compares)/float64(b.Elapsed().Nanoseconds()), "compares/ns")
	})
}

func ExampleB_ReportMetric_parallel() {
	// This reports a custom benchmark metric relevant to a
	// specific algorithm (in this case, sorting) in parallel.
	testing.Benchmark(func(b *testing.B) {
		var compares atomic.Int64
		b.RunParallel(func(pb *testing.PB) {
			for pb.Next() {
				s := []int{5, 4, 3, 2, 1}
				slices.SortFunc(s, func(a, b int) int {
					// Because RunParallel runs the function many
					// times in parallel, we must increment the
					// counter atomically to avoid racing writes.
					compares.Add(1)
					return cmp.Compare(a, b)
				})
			}
		})

		// NOTE: Report each metric once, after all of the parallel
		// calls have completed.

		// This metric is per-operation, so divide by b.N and
		// report it as a "/op" unit.
		b.ReportMetric(float64(compares.Load())/float64(b.N), "compares/op")
		// This metric is per-time, so divide by b.Elapsed and
		// report it as a "/ns" unit.
		b.ReportMetric(float64(compares.Load())/float64(b.Elapsed().Nanoseconds()), "compares/ns")
	})
}
