// Copyright 2021 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 token_test

import (
	"go/build"
	"go/token"
	"math/rand/v2"
	"os"
	"path/filepath"
	"testing"
)

func BenchmarkSearchInts(b *testing.B) {
	data := make([]int, 10000)
	for i := 0; i < 10000; i++ {
		data[i] = i
	}
	const x = 8
	if r := token.SearchInts(data, x); r != x {
		b.Errorf("got index = %d; want %d", r, x)
	}
	b.ResetTimer()
	for i := 0; i < b.N; i++ {
		token.SearchInts(data, x)
	}
}

func BenchmarkFileSet_Position(b *testing.B) {
	rng := rand.New(rand.NewPCG(rand.Uint64(), rand.Uint64()))

	// Create a FileSet based on the files of net/http,
	// a single large package.
	netHTTPFset := token.NewFileSet()
	pkg, err := build.Default.Import("net/http", "", 0)
	if err != nil {
		b.Fatal(err)
	}
	for _, filename := range pkg.GoFiles {
		filename = filepath.Join(pkg.Dir, filename)
		fi, err := os.Stat(filename)
		if err != nil {
			b.Fatal(err)
		}
		netHTTPFset.AddFile(filename, -1, int(fi.Size()))
	}

	// Measure randomly distributed Pos values across net/http.
	b.Run("random", func(b *testing.B) {
		base := netHTTPFset.Base()
		for b.Loop() {
			pos := token.Pos(rng.IntN(base))
			_ = netHTTPFset.Position(pos)
		}
	})

	// Measure random lookups within the same file of net/http.
	// (It's faster because of the "last file" cache.)
	b.Run("file", func(b *testing.B) {
		var file *token.File
		for file = range netHTTPFset.Iterate {
			break
		}
		base, size := file.Base(), file.Size()
		for b.Loop() {
			_ = netHTTPFset.Position(token.Pos(base + rng.IntN(size)))
		}
	})

	// Measure random lookups on a FileSet with a great many files.
	b.Run("manyfiles", func(b *testing.B) {
		fset := token.NewFileSet()
		for range 25000 {
			fset.AddFile("", -1, 10000)
		}
		base := fset.Base()
		for b.Loop() {
			pos := token.Pos(rng.IntN(base))
			_ = fset.Position(pos)
		}
	})
}

func BenchmarkFileSet_AddExistingFiles(b *testing.B) {
	rng := rand.New(rand.NewPCG(rand.Uint64(), rand.Uint64()))

	// Create the "universe" of files.
	fset := token.NewFileSet()
	var files []*token.File
	for range 25000 {
		files = append(files, fset.AddFile("", -1, 10000))
	}
	token.Shuffle(rng, files)

	// choose returns n random files.
	choose := func(n int) []*token.File {
		res := make([]*token.File, n)
		for i := range res {
			res[i] = files[rand.IntN(n)]
		}
		return files[:n]
	}

	// Measure the cost of	creating a FileSet with a large number
	// of files added in small handfuls, with some overlap.
	// This case is critical to gopls.
	b.Run("sequence", func(b *testing.B) {
		for b.Loop() {
			b.StopTimer()
			fset2 := token.NewFileSet()
			fset2.AddExistingFiles(files[:10000]...)
			b.StartTimer()

			for range 1000 {
				fset2.AddExistingFiles(choose(10)...) // about one package
			}
		}
	})
}
