// Copyright 2020 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 regtest

import (
	"flag"
	"fmt"
	"testing"

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

var iwlBench = struct {
	workdir string
}{}

func init() {
	flag.StringVar(&iwlBench.workdir, "iwl_workdir", "", "if set, run IWL benchmark in this directory")
}

func TestBenchmarkIWL(t *testing.T) {
	if iwlBench.workdir == "" {
		t.Skip("-iwl_workdir not configured")
	}
	opts := stressTestOptions(iwlBench.workdir)
	// Don't skip hooks, so that we can wait for IWL.
	opts = append(opts, SkipHooks(false))
	b := testing.Benchmark(func(b *testing.B) {
		for i := 0; i < b.N; i++ {
			withOptions(opts...).run(t, "", func(t *testing.T, env *Env) {
				env.Await(InitialWorkspaceLoad)
			})
		}
	})
	printBench(b)
}

var symbolBench = struct {
	workdir, query, matcher, style string
	printResults                   bool
}{}

func init() {
	flag.StringVar(&symbolBench.workdir, "symbol_workdir", "", "if set, run symbol benchmark in this directory")
	flag.StringVar(&symbolBench.query, "symbol_query", "test", "symbol query to use in benchmark")
	flag.StringVar(&symbolBench.matcher, "symbol_matcher", "", "symbol matcher to use in benchmark")
	flag.StringVar(&symbolBench.style, "symbol_style", "", "symbol style to use in benchmark")
	flag.BoolVar(&symbolBench.printResults, "symbol_print_results", false, "whether to print symbol query results")
}

func TestBenchmarkSymbols(t *testing.T) {
	if symbolBench.workdir == "" {
		t.Skip("-symbol_workdir not configured")
	}
	opts := stressTestOptions(symbolBench.workdir)
	conf := EditorConfig{}
	if symbolBench.matcher != "" {
		conf.SymbolMatcher = &symbolBench.matcher
	}
	if symbolBench.style != "" {
		conf.SymbolStyle = &symbolBench.style
	}
	opts = append(opts, conf)
	withOptions(opts...).run(t, "", func(t *testing.T, env *Env) {
		// We can't Await in this test, since we have disabled hooks. Instead, run
		// one symbol request to completion to ensure all necessary cache entries
		// are populated.
		results, err := env.Editor.Server.Symbol(env.Ctx, &protocol.WorkspaceSymbolParams{
			Query: symbolBench.query,
		})
		if err != nil {
			t.Fatal(err)
		}
		if symbolBench.printResults {
			fmt.Println("Results:")
			for i := 0; i < len(results); i++ {
				fmt.Printf("\t%d. %s (%s)\n", i, results[i].Name, results[i].ContainerName)
			}
		}
		b := testing.Benchmark(func(b *testing.B) {
			for i := 0; i < b.N; i++ {
				if _, err := env.Editor.Server.Symbol(env.Ctx, &protocol.WorkspaceSymbolParams{
					Query: symbolBench.query,
				}); err != nil {
					t.Fatal(err)
				}
			}
		})
		printBench(b)
	})
}

func printBench(b testing.BenchmarkResult) {
	fmt.Println("Benchmark stats:")
	fmt.Println(b.String())
	fmt.Println(b.MemString())
}

func dummyCompletionBenchmarkFunction() { const s = "placeholder"; fmt.Printf("%s", s) }

var completionBench = struct {
	workdir, fileName, locationRegexp string
	printResults                      bool
}{}

func init() {
	flag.StringVar(&completionBench.workdir, "completion_workdir", "", "if set run completion benchmark in this directory (other benchmark flags expect an x/tools dir)")
	flag.StringVar(&completionBench.fileName, "completion_file", "internal/lsp/regtest/bench_test.go", "relative path to the file to complete")
	flag.StringVar(&completionBench.locationRegexp, "completion_regexp", `dummyCompletionBenchmarkFunction.*fmt\.Printf\("%s", s(\))`, "regexp location to complete at")
	flag.BoolVar(&completionBench.printResults, "completion_print_results", false, "whether to print completion results")
}

func TestBenchmarkCompletion(t *testing.T) {
	if completionBench.workdir == "" {
		t.Skip("-completion_workdir not configured")
	}
	opts := stressTestOptions(completionBench.workdir)
	// Completion gives bad results if IWL is not yet complete, so we must await
	// it first (and therefore need hooks).
	opts = append(opts, SkipHooks(false))
	withOptions(opts...).run(t, "", func(t *testing.T, env *Env) {
		env.Await(InitialWorkspaceLoad)
		env.OpenFile(completionBench.fileName)
		params := &protocol.CompletionParams{}
		params.Context.TriggerCharacter = "s"
		params.Context.TriggerKind = protocol.TriggerCharacter
		params.TextDocument.URI = env.Sandbox.Workdir.URI(completionBench.fileName)
		params.Position = env.RegexpSearch(completionBench.fileName, completionBench.locationRegexp).ToProtocolPosition()

		// Run one completion to make sure everything is warm.
		list, err := env.Editor.Server.Completion(env.Ctx, params)
		if err != nil {
			t.Fatal(err)
		}
		if completionBench.printResults {
			fmt.Println("Results:")
			for i := 0; i < len(list.Items); i++ {
				fmt.Printf("\t%d. %v\n", i, list.Items[i])
			}
		}
		b := testing.Benchmark(func(b *testing.B) {
			for i := 0; i < b.N; i++ {
				_, err := env.Editor.Server.Completion(env.Ctx, params)
				if err != nil {
					t.Fatal(err)
				}
			}
		})
		printBench(b)
	})
}
