// Copyright 2022 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 bench

import (
	"fmt"
	"sync/atomic"
	"testing"
	"time"

	"golang.org/x/tools/gopls/internal/lsp/fake"
	"golang.org/x/tools/gopls/internal/lsp/protocol"
)

// Use a global edit counter as bench function may execute multiple times, and
// we want to avoid cache hits. Use time.Now to also avoid cache hits from the
// shared file cache.
var editID int64 = time.Now().UnixNano()

type changeTest struct {
	repo string
	file string
}

var didChangeTests = []changeTest{
	{"google-cloud-go", "internal/annotate.go"},
	{"istio", "pkg/fuzz/util.go"},
	{"kubernetes", "pkg/controller/lookup_cache.go"},
	{"kuma", "api/generic/insights.go"},
	{"oracle", "dataintegration/data_type.go"}, // diagnoseSave fails because this package is generated
	{"pkgsite", "internal/frontend/server.go"},
	{"starlark", "starlark/eval.go"},
	{"tools", "internal/lsp/cache/snapshot.go"},
}

// BenchmarkDidChange benchmarks modifications of a single file by making
// synthetic modifications in a comment. It controls pacing by waiting for the
// server to actually start processing the didChange notification before
// proceeding. Notably it does not wait for diagnostics to complete.
func BenchmarkDidChange(b *testing.B) {
	for _, test := range didChangeTests {
		b.Run(test.repo, func(b *testing.B) {
			env := getRepo(b, test.repo).sharedEnv(b)
			env.OpenFile(test.file)
			defer closeBuffer(b, env, test.file)

			// Insert the text we'll be modifying at the top of the file.
			env.EditBuffer(test.file, protocol.TextEdit{NewText: "// __REGTEST_PLACEHOLDER_0__\n"})
			env.AfterChange()
			b.ResetTimer()

			if stopAndRecord := startProfileIfSupported(b, env, qualifiedName(test.repo, "didchange")); stopAndRecord != nil {
				defer stopAndRecord()
			}

			for i := 0; i < b.N; i++ {
				edits := atomic.AddInt64(&editID, 1)
				env.EditBuffer(test.file, protocol.TextEdit{
					Range: protocol.Range{
						Start: protocol.Position{Line: 0, Character: 0},
						End:   protocol.Position{Line: 1, Character: 0},
					},
					// Increment the placeholder text, to ensure cache misses.
					NewText: fmt.Sprintf("// __REGTEST_PLACEHOLDER_%d__\n", edits),
				})
				env.Await(env.StartedChange())
			}
		})
	}
}

func BenchmarkDiagnoseChange(b *testing.B) {
	for _, test := range didChangeTests {
		runChangeDiagnosticsBenchmark(b, test, false, "diagnoseChange")
	}
}

// TODO(rfindley): add a benchmark for with a metadata-affecting change, when
// this matters.
func BenchmarkDiagnoseSave(b *testing.B) {
	for _, test := range didChangeTests {
		runChangeDiagnosticsBenchmark(b, test, true, "diagnoseSave")
	}
}

// runChangeDiagnosticsBenchmark runs a benchmark to edit the test file and
// await the resulting diagnostics pass. If save is set, the file is also saved.
func runChangeDiagnosticsBenchmark(b *testing.B, test changeTest, save bool, operation string) {
	b.Run(test.repo, func(b *testing.B) {
		sharedEnv := getRepo(b, test.repo).sharedEnv(b)
		config := fake.EditorConfig{
			Env: map[string]string{
				"GOPATH": sharedEnv.Sandbox.GOPATH(),
			},
			Settings: map[string]interface{}{
				"diagnosticsDelay": "0s",
			},
		}
		// Use a new env to avoid the diagnostic delay: we want to measure how
		// long it takes to produce the diagnostics.
		env := getRepo(b, test.repo).newEnv(b, config, operation, false)
		defer env.Close()
		env.OpenFile(test.file)
		// Insert the text we'll be modifying at the top of the file.
		env.EditBuffer(test.file, protocol.TextEdit{NewText: "// __REGTEST_PLACEHOLDER_0__\n"})
		if save {
			env.SaveBuffer(test.file)
		}
		env.AfterChange()
		b.ResetTimer()

		// We must use an extra subtest layer here, so that we only set up the
		// shared env once (otherwise we pay additional overhead and the profiling
		// flags don't work).
		b.Run("diagnose", func(b *testing.B) {
			if stopAndRecord := startProfileIfSupported(b, env, qualifiedName(test.repo, operation)); stopAndRecord != nil {
				defer stopAndRecord()
			}
			for i := 0; i < b.N; i++ {
				edits := atomic.AddInt64(&editID, 1)
				env.EditBuffer(test.file, protocol.TextEdit{
					Range: protocol.Range{
						Start: protocol.Position{Line: 0, Character: 0},
						End:   protocol.Position{Line: 1, Character: 0},
					},
					// Increment the placeholder text, to ensure cache misses.
					NewText: fmt.Sprintf("// __REGTEST_PLACEHOLDER_%d__\n", edits),
				})
				if save {
					env.SaveBuffer(test.file)
				}
				env.AfterChange()
			}
		})
	})
}
