// Copyright 2019 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 tests exports functionality to be used across a variety of gopls tests.
package tests

import (
	"bytes"
	"context"
	"flag"
	"fmt"
	"go/ast"
	"go/token"
	"io"
	"io/ioutil"
	"os"
	"path/filepath"
	"regexp"
	"sort"
	"strconv"
	"strings"
	"sync"
	"testing"
	"time"

	"golang.org/x/tools/go/expect"
	"golang.org/x/tools/go/packages"
	"golang.org/x/tools/go/packages/packagestest"
	"golang.org/x/tools/gopls/internal/lsp/command"
	"golang.org/x/tools/gopls/internal/lsp/protocol"
	"golang.org/x/tools/gopls/internal/lsp/source"
	"golang.org/x/tools/gopls/internal/lsp/source/completion"
	"golang.org/x/tools/gopls/internal/lsp/tests/compare"
	"golang.org/x/tools/internal/span"
	"golang.org/x/tools/internal/testenv"
	"golang.org/x/tools/internal/typeparams"
	"golang.org/x/tools/txtar"
)

const (
	overlayFileSuffix = ".overlay"
	goldenFileSuffix  = ".golden"
	inFileSuffix      = ".in"

	// The module path containing the testdata packages.
	//
	// Warning: the length of this module path matters, as we have bumped up
	// against command-line limitations on windows (golang/go#54800).
	testModule = "golang.org/lsptests"
)

var summaryFile = "summary.txt"

func init() {
	if typeparams.Enabled {
		summaryFile = "summary_go1.18.txt"
	}
}

var UpdateGolden = flag.Bool("golden", false, "Update golden files")

// These type names apparently avoid the need to repeat the
// type in the field name and the make() expression.
type CallHierarchy = map[span.Span]*CallHierarchyResult
type CodeLens = map[span.URI][]protocol.CodeLens
type Diagnostics = map[span.URI][]*source.Diagnostic
type CompletionItems = map[token.Pos]*completion.CompletionItem
type Completions = map[span.Span][]Completion
type CompletionSnippets = map[span.Span][]CompletionSnippet
type UnimportedCompletions = map[span.Span][]Completion
type DeepCompletions = map[span.Span][]Completion
type FuzzyCompletions = map[span.Span][]Completion
type CaseSensitiveCompletions = map[span.Span][]Completion
type RankCompletions = map[span.Span][]Completion
type FoldingRanges = []span.Span
type Formats = []span.Span
type Imports = []span.Span
type SemanticTokens = []span.Span
type SuggestedFixes = map[span.Span][]SuggestedFix
type FunctionExtractions = map[span.Span]span.Span
type MethodExtractions = map[span.Span]span.Span
type Definitions = map[span.Span]Definition
type Implementations = map[span.Span][]span.Span
type Highlights = map[span.Span][]span.Span
type References = map[span.Span][]span.Span
type Renames = map[span.Span]string
type PrepareRenames = map[span.Span]*source.PrepareItem
type Symbols = map[span.URI][]*symbol
type SymbolInformation = map[span.Span]protocol.SymbolInformation
type InlayHints = []span.Span
type WorkspaceSymbols = map[WorkspaceSymbolsTestType]map[span.URI][]string
type Signatures = map[span.Span]*protocol.SignatureHelp
type Links = map[span.URI][]Link
type AddImport = map[span.URI]string
type Hovers = map[span.Span]string

type Data struct {
	Config                   packages.Config
	Exported                 *packagestest.Exported
	CallHierarchy            CallHierarchy
	CodeLens                 CodeLens
	Diagnostics              Diagnostics
	CompletionItems          CompletionItems
	Completions              Completions
	CompletionSnippets       CompletionSnippets
	UnimportedCompletions    UnimportedCompletions
	DeepCompletions          DeepCompletions
	FuzzyCompletions         FuzzyCompletions
	CaseSensitiveCompletions CaseSensitiveCompletions
	RankCompletions          RankCompletions
	FoldingRanges            FoldingRanges
	Formats                  Formats
	Imports                  Imports
	SemanticTokens           SemanticTokens
	SuggestedFixes           SuggestedFixes
	FunctionExtractions      FunctionExtractions
	MethodExtractions        MethodExtractions
	Definitions              Definitions
	Implementations          Implementations
	Highlights               Highlights
	References               References
	Renames                  Renames
	InlayHints               InlayHints
	PrepareRenames           PrepareRenames
	Symbols                  Symbols
	WorkspaceSymbols         WorkspaceSymbols
	Signatures               Signatures
	Links                    Links
	AddImport                AddImport
	Hovers                   Hovers

	fragments map[string]string
	dir       string
	golden    map[string]*Golden
	mode      string

	ModfileFlagAvailable bool

	mappersMu sync.Mutex
	mappers   map[span.URI]*protocol.ColumnMapper
}

// TODO(adonovan): there are multiple implementations of this (undocumented)
// interface, each of which must implement similar semantics. For example:
// - *runner in ../cmd/test/check.go
// - *runner in ../source/source_test.go
// - *runner in ../lsp_test.go
// Can we avoid this duplication?
type Tests interface {
	CallHierarchy(*testing.T, span.Span, *CallHierarchyResult)
	CodeLens(*testing.T, span.URI, []protocol.CodeLens)
	Diagnostics(*testing.T, span.URI, []*source.Diagnostic)
	Completion(*testing.T, span.Span, Completion, CompletionItems)
	CompletionSnippet(*testing.T, span.Span, CompletionSnippet, bool, CompletionItems)
	UnimportedCompletion(*testing.T, span.Span, Completion, CompletionItems)
	DeepCompletion(*testing.T, span.Span, Completion, CompletionItems)
	FuzzyCompletion(*testing.T, span.Span, Completion, CompletionItems)
	CaseSensitiveCompletion(*testing.T, span.Span, Completion, CompletionItems)
	RankCompletion(*testing.T, span.Span, Completion, CompletionItems)
	FoldingRanges(*testing.T, span.Span)
	Format(*testing.T, span.Span)
	Import(*testing.T, span.Span)
	SemanticTokens(*testing.T, span.Span)
	SuggestedFix(*testing.T, span.Span, []SuggestedFix, int)
	FunctionExtraction(*testing.T, span.Span, span.Span)
	MethodExtraction(*testing.T, span.Span, span.Span)
	Definition(*testing.T, span.Span, Definition)
	Implementation(*testing.T, span.Span, []span.Span)
	Highlight(*testing.T, span.Span, []span.Span)
	InlayHints(*testing.T, span.Span)
	References(*testing.T, span.Span, []span.Span)
	Rename(*testing.T, span.Span, string)
	PrepareRename(*testing.T, span.Span, *source.PrepareItem)
	Symbols(*testing.T, span.URI, []protocol.DocumentSymbol)
	WorkspaceSymbols(*testing.T, span.URI, string, WorkspaceSymbolsTestType)
	SignatureHelp(*testing.T, span.Span, *protocol.SignatureHelp)
	Link(*testing.T, span.URI, []Link)
	AddImport(*testing.T, span.URI, string)
	Hover(*testing.T, span.Span, string)
}

type Definition struct {
	Name      string
	IsType    bool
	OnlyHover bool
	Src, Def  span.Span
}

type CompletionTestType int

const (
	// Default runs the standard completion tests.
	CompletionDefault = CompletionTestType(iota)

	// Unimported tests the autocompletion of unimported packages.
	CompletionUnimported

	// Deep tests deep completion.
	CompletionDeep

	// Fuzzy tests deep completion and fuzzy matching.
	CompletionFuzzy

	// CaseSensitive tests case sensitive completion.
	CompletionCaseSensitive

	// CompletionRank candidates in test must be valid and in the right relative order.
	CompletionRank
)

type WorkspaceSymbolsTestType int

const (
	// Default runs the standard workspace symbols tests.
	WorkspaceSymbolsDefault = WorkspaceSymbolsTestType(iota)

	// Fuzzy tests workspace symbols with fuzzy matching.
	WorkspaceSymbolsFuzzy

	// CaseSensitive tests workspace symbols with case sensitive.
	WorkspaceSymbolsCaseSensitive
)

type Completion struct {
	CompletionItems []token.Pos
}

type CompletionSnippet struct {
	CompletionItem     token.Pos
	PlainSnippet       string
	PlaceholderSnippet string
}

type CallHierarchyResult struct {
	IncomingCalls, OutgoingCalls []protocol.CallHierarchyItem
}

type Link struct {
	Src          span.Span
	Target       string
	NotePosition token.Position
}

type SuggestedFix struct {
	ActionKind, Title string
}

// A symbol holds a DocumentSymbol along with its parent-child edge.
type symbol struct {
	pSymbol      protocol.DocumentSymbol
	id, parentID string
}

type Golden struct {
	Filename string
	Archive  *txtar.Archive
	Modified bool
}

func Context(t testing.TB) context.Context {
	return context.Background()
}

func DefaultOptions(o *source.Options) {
	o.SupportedCodeActions = map[source.FileKind]map[protocol.CodeActionKind]bool{
		source.Go: {
			protocol.SourceOrganizeImports: true,
			protocol.QuickFix:              true,
			protocol.RefactorRewrite:       true,
			protocol.RefactorExtract:       true,
			protocol.SourceFixAll:          true,
		},
		source.Mod: {
			protocol.SourceOrganizeImports: true,
		},
		source.Sum:  {},
		source.Work: {},
		source.Tmpl: {},
	}
	o.UserOptions.Codelenses[string(command.Test)] = true
	o.HoverKind = source.SynopsisDocumentation
	o.InsertTextFormat = protocol.SnippetTextFormat
	o.CompletionBudget = time.Minute
	o.HierarchicalDocumentSymbolSupport = true
	o.ExperimentalWorkspaceModule = true
	o.SemanticTokens = true
	o.InternalOptions.NewDiff = "both"
}

func RunTests(t *testing.T, dataDir string, includeMultiModule bool, f func(*testing.T, *Data)) {
	t.Helper()
	modes := []string{"Modules", "GOPATH"}
	if includeMultiModule {
		modes = append(modes, "MultiModule")
	}
	for _, mode := range modes {
		t.Run(mode, func(t *testing.T) {
			if mode == "MultiModule" {
				// Some bug in 1.12 breaks reading markers, and it's not worth figuring out.
				testenv.NeedsGo1Point(t, 13)
			}
			datum := load(t, mode, dataDir)
			t.Helper()
			f(t, datum)
		})
	}
}

func load(t testing.TB, mode string, dir string) *Data {
	datum := &Data{
		CallHierarchy:            make(CallHierarchy),
		CodeLens:                 make(CodeLens),
		Diagnostics:              make(Diagnostics),
		CompletionItems:          make(CompletionItems),
		Completions:              make(Completions),
		CompletionSnippets:       make(CompletionSnippets),
		UnimportedCompletions:    make(UnimportedCompletions),
		DeepCompletions:          make(DeepCompletions),
		FuzzyCompletions:         make(FuzzyCompletions),
		RankCompletions:          make(RankCompletions),
		CaseSensitiveCompletions: make(CaseSensitiveCompletions),
		Definitions:              make(Definitions),
		Implementations:          make(Implementations),
		Highlights:               make(Highlights),
		References:               make(References),
		Renames:                  make(Renames),
		PrepareRenames:           make(PrepareRenames),
		SuggestedFixes:           make(SuggestedFixes),
		FunctionExtractions:      make(FunctionExtractions),
		MethodExtractions:        make(MethodExtractions),
		Symbols:                  make(Symbols),
		WorkspaceSymbols:         make(WorkspaceSymbols),
		Signatures:               make(Signatures),
		Links:                    make(Links),
		AddImport:                make(AddImport),
		Hovers:                   make(Hovers),

		dir:       dir,
		fragments: map[string]string{},
		golden:    map[string]*Golden{},
		mode:      mode,
		mappers:   map[span.URI]*protocol.ColumnMapper{},
	}

	if !*UpdateGolden {
		summary := filepath.Join(filepath.FromSlash(dir), summaryFile+goldenFileSuffix)
		if _, err := os.Stat(summary); os.IsNotExist(err) {
			t.Fatalf("could not find golden file summary.txt in %#v", dir)
		}
		archive, err := txtar.ParseFile(summary)
		if err != nil {
			t.Fatalf("could not read golden file %v/%v: %v", dir, summary, err)
		}
		datum.golden[summaryFile] = &Golden{
			Filename: summary,
			Archive:  archive,
		}
	}

	files := packagestest.MustCopyFileTree(dir)
	// Prune test cases that exercise generics.
	if !typeparams.Enabled {
		for name := range files {
			if strings.Contains(name, "_generics") {
				delete(files, name)
			}
		}
	}
	overlays := map[string][]byte{}
	for fragment, operation := range files {
		if trimmed := strings.TrimSuffix(fragment, goldenFileSuffix); trimmed != fragment {
			delete(files, fragment)
			goldFile := filepath.Join(dir, fragment)
			archive, err := txtar.ParseFile(goldFile)
			if err != nil {
				t.Fatalf("could not read golden file %v: %v", fragment, err)
			}
			datum.golden[trimmed] = &Golden{
				Filename: goldFile,
				Archive:  archive,
			}
		} else if trimmed := strings.TrimSuffix(fragment, inFileSuffix); trimmed != fragment {
			delete(files, fragment)
			files[trimmed] = operation
		} else if index := strings.Index(fragment, overlayFileSuffix); index >= 0 {
			delete(files, fragment)
			partial := fragment[:index] + fragment[index+len(overlayFileSuffix):]
			contents, err := ioutil.ReadFile(filepath.Join(dir, fragment))
			if err != nil {
				t.Fatal(err)
			}
			overlays[partial] = contents
		}
	}

	modules := []packagestest.Module{
		{
			Name:    testModule,
			Files:   files,
			Overlay: overlays,
		},
	}
	switch mode {
	case "Modules":
		datum.Exported = packagestest.Export(t, packagestest.Modules, modules)
	case "GOPATH":
		datum.Exported = packagestest.Export(t, packagestest.GOPATH, modules)
	case "MultiModule":
		files := map[string]interface{}{}
		for k, v := range modules[0].Files {
			files[filepath.Join("testmodule", k)] = v
		}
		modules[0].Files = files

		overlays := map[string][]byte{}
		for k, v := range modules[0].Overlay {
			overlays[filepath.Join("testmodule", k)] = v
		}
		modules[0].Overlay = overlays

		golden := map[string]*Golden{}
		for k, v := range datum.golden {
			if k == summaryFile {
				golden[k] = v
			} else {
				golden[filepath.Join("testmodule", k)] = v
			}
		}
		datum.golden = golden

		datum.Exported = packagestest.Export(t, packagestest.Modules, modules)
	default:
		panic("unknown mode " + mode)
	}

	for _, m := range modules {
		for fragment := range m.Files {
			filename := datum.Exported.File(m.Name, fragment)
			datum.fragments[filename] = fragment
		}
	}

	// Turn off go/packages debug logging.
	datum.Exported.Config.Logf = nil
	datum.Config.Logf = nil

	// Merge the exported.Config with the view.Config.
	datum.Config = *datum.Exported.Config
	datum.Config.Fset = token.NewFileSet()
	datum.Config.Context = Context(nil)
	datum.Config.ParseFile = func(fset *token.FileSet, filename string, src []byte) (*ast.File, error) {
		panic("ParseFile should not be called")
	}

	// Do a first pass to collect special markers for completion and workspace symbols.
	if err := datum.Exported.Expect(map[string]interface{}{
		"item": func(name string, r packagestest.Range, _ []string) {
			datum.Exported.Mark(name, r)
		},
		"symbol": func(name string, r packagestest.Range, _ []string) {
			datum.Exported.Mark(name, r)
		},
	}); err != nil {
		t.Fatal(err)
	}

	// Collect any data that needs to be used by subsequent tests.
	if err := datum.Exported.Expect(map[string]interface{}{
		"codelens":        datum.collectCodeLens,
		"diag":            datum.collectDiagnostics,
		"item":            datum.collectCompletionItems,
		"complete":        datum.collectCompletions(CompletionDefault),
		"unimported":      datum.collectCompletions(CompletionUnimported),
		"deep":            datum.collectCompletions(CompletionDeep),
		"fuzzy":           datum.collectCompletions(CompletionFuzzy),
		"casesensitive":   datum.collectCompletions(CompletionCaseSensitive),
		"rank":            datum.collectCompletions(CompletionRank),
		"snippet":         datum.collectCompletionSnippets,
		"fold":            datum.collectFoldingRanges,
		"format":          datum.collectFormats,
		"import":          datum.collectImports,
		"semantic":        datum.collectSemanticTokens,
		"godef":           datum.collectDefinitions,
		"implementations": datum.collectImplementations,
		"typdef":          datum.collectTypeDefinitions,
		"hoverdef":        datum.collectHoverDefinitions,
		"hover":           datum.collectHovers,
		"highlight":       datum.collectHighlights,
		"inlayHint":       datum.collectInlayHints,
		"refs":            datum.collectReferences,
		"rename":          datum.collectRenames,
		"prepare":         datum.collectPrepareRenames,
		"symbol":          datum.collectSymbols,
		"signature":       datum.collectSignatures,
		"link":            datum.collectLinks,
		"suggestedfix":    datum.collectSuggestedFixes,
		"extractfunc":     datum.collectFunctionExtractions,
		"extractmethod":   datum.collectMethodExtractions,
		"incomingcalls":   datum.collectIncomingCalls,
		"outgoingcalls":   datum.collectOutgoingCalls,
		"addimport":       datum.collectAddImports,
	}); err != nil {
		t.Fatal(err)
	}

	// Collect names for the entries that require golden files.
	if err := datum.Exported.Expect(map[string]interface{}{
		"godef":                        datum.collectDefinitionNames,
		"hoverdef":                     datum.collectDefinitionNames,
		"workspacesymbol":              datum.collectWorkspaceSymbols(WorkspaceSymbolsDefault),
		"workspacesymbolfuzzy":         datum.collectWorkspaceSymbols(WorkspaceSymbolsFuzzy),
		"workspacesymbolcasesensitive": datum.collectWorkspaceSymbols(WorkspaceSymbolsCaseSensitive),
	}); err != nil {
		t.Fatal(err)
	}
	if mode == "MultiModule" {
		if err := moveFile(filepath.Join(datum.Config.Dir, "go.mod"), filepath.Join(datum.Config.Dir, "testmodule/go.mod")); err != nil {
			t.Fatal(err)
		}
	}

	return datum
}

// moveFile moves the file at oldpath to newpath, by renaming if possible
// or copying otherwise.
func moveFile(oldpath, newpath string) (err error) {
	renameErr := os.Rename(oldpath, newpath)
	if renameErr == nil {
		return nil
	}

	src, err := os.Open(oldpath)
	if err != nil {
		return err
	}
	defer func() {
		src.Close()
		if err == nil {
			err = os.Remove(oldpath)
		}
	}()

	perm := os.ModePerm
	fi, err := src.Stat()
	if err == nil {
		perm = fi.Mode().Perm()
	}

	dst, err := os.OpenFile(newpath, os.O_WRONLY|os.O_CREATE|os.O_EXCL, perm)
	if err != nil {
		return err
	}

	_, err = io.Copy(dst, src)
	if closeErr := dst.Close(); err == nil {
		err = closeErr
	}
	return err
}

func Run(t *testing.T, tests Tests, data *Data) {
	t.Helper()
	checkData(t, data)

	eachCompletion := func(t *testing.T, cases map[span.Span][]Completion, test func(*testing.T, span.Span, Completion, CompletionItems)) {
		t.Helper()

		for src, exp := range cases {
			for i, e := range exp {
				t.Run(SpanName(src)+"_"+strconv.Itoa(i), func(t *testing.T) {
					t.Helper()
					if strings.Contains(t.Name(), "cgo") {
						testenv.NeedsTool(t, "cgo")
					}
					if strings.Contains(t.Name(), "declarecgo") {
						testenv.NeedsGo1Point(t, 15)
					}
					test(t, src, e, data.CompletionItems)
				})
			}

		}
	}

	t.Run("CallHierarchy", func(t *testing.T) {
		t.Helper()
		for spn, callHierarchyResult := range data.CallHierarchy {
			t.Run(SpanName(spn), func(t *testing.T) {
				t.Helper()
				tests.CallHierarchy(t, spn, callHierarchyResult)
			})
		}
	})

	t.Run("Completion", func(t *testing.T) {
		t.Helper()
		eachCompletion(t, data.Completions, tests.Completion)
	})

	t.Run("CompletionSnippets", func(t *testing.T) {
		t.Helper()
		for _, placeholders := range []bool{true, false} {
			for src, expecteds := range data.CompletionSnippets {
				for i, expected := range expecteds {
					name := SpanName(src) + "_" + strconv.Itoa(i+1)
					if placeholders {
						name += "_placeholders"
					}

					t.Run(name, func(t *testing.T) {
						t.Helper()
						tests.CompletionSnippet(t, src, expected, placeholders, data.CompletionItems)
					})
				}
			}
		}
	})

	t.Run("UnimportedCompletion", func(t *testing.T) {
		t.Helper()
		eachCompletion(t, data.UnimportedCompletions, tests.UnimportedCompletion)
	})

	t.Run("DeepCompletion", func(t *testing.T) {
		t.Helper()
		eachCompletion(t, data.DeepCompletions, tests.DeepCompletion)
	})

	t.Run("FuzzyCompletion", func(t *testing.T) {
		t.Helper()
		eachCompletion(t, data.FuzzyCompletions, tests.FuzzyCompletion)
	})

	t.Run("CaseSensitiveCompletion", func(t *testing.T) {
		t.Helper()
		eachCompletion(t, data.CaseSensitiveCompletions, tests.CaseSensitiveCompletion)
	})

	t.Run("RankCompletions", func(t *testing.T) {
		t.Helper()
		eachCompletion(t, data.RankCompletions, tests.RankCompletion)
	})

	t.Run("CodeLens", func(t *testing.T) {
		t.Helper()
		for uri, want := range data.CodeLens {
			// Check if we should skip this URI if the -modfile flag is not available.
			if shouldSkip(data, uri) {
				continue
			}
			t.Run(uriName(uri), func(t *testing.T) {
				t.Helper()
				tests.CodeLens(t, uri, want)
			})
		}
	})

	t.Run("Diagnostics", func(t *testing.T) {
		t.Helper()
		for uri, want := range data.Diagnostics {
			// Check if we should skip this URI if the -modfile flag is not available.
			if shouldSkip(data, uri) {
				continue
			}
			t.Run(uriName(uri), func(t *testing.T) {
				t.Helper()
				tests.Diagnostics(t, uri, want)
			})
		}
	})

	t.Run("FoldingRange", func(t *testing.T) {
		t.Helper()
		for _, spn := range data.FoldingRanges {
			t.Run(uriName(spn.URI()), func(t *testing.T) {
				t.Helper()
				tests.FoldingRanges(t, spn)
			})
		}
	})

	t.Run("Format", func(t *testing.T) {
		t.Helper()
		for _, spn := range data.Formats {
			t.Run(uriName(spn.URI()), func(t *testing.T) {
				t.Helper()
				tests.Format(t, spn)
			})
		}
	})

	t.Run("Import", func(t *testing.T) {
		t.Helper()
		for _, spn := range data.Imports {
			t.Run(uriName(spn.URI()), func(t *testing.T) {
				t.Helper()
				tests.Import(t, spn)
			})
		}
	})

	t.Run("SemanticTokens", func(t *testing.T) {
		t.Helper()
		for _, spn := range data.SemanticTokens {
			t.Run(uriName(spn.URI()), func(t *testing.T) {
				t.Helper()
				tests.SemanticTokens(t, spn)
			})
		}
	})

	t.Run("SuggestedFix", func(t *testing.T) {
		t.Helper()
		for spn, actionKinds := range data.SuggestedFixes {
			// Check if we should skip this spn if the -modfile flag is not available.
			if shouldSkip(data, spn.URI()) {
				continue
			}
			t.Run(SpanName(spn), func(t *testing.T) {
				t.Helper()
				tests.SuggestedFix(t, spn, actionKinds, 1)
			})
		}
	})

	t.Run("FunctionExtraction", func(t *testing.T) {
		t.Helper()
		for start, end := range data.FunctionExtractions {
			// Check if we should skip this spn if the -modfile flag is not available.
			if shouldSkip(data, start.URI()) {
				continue
			}
			t.Run(SpanName(start), func(t *testing.T) {
				t.Helper()
				tests.FunctionExtraction(t, start, end)
			})
		}
	})

	t.Run("MethodExtraction", func(t *testing.T) {
		t.Helper()
		for start, end := range data.MethodExtractions {
			// Check if we should skip this spn if the -modfile flag is not available.
			if shouldSkip(data, start.URI()) {
				continue
			}
			t.Run(SpanName(start), func(t *testing.T) {
				t.Helper()
				tests.MethodExtraction(t, start, end)
			})
		}
	})

	t.Run("Definition", func(t *testing.T) {
		t.Helper()
		for spn, d := range data.Definitions {
			t.Run(SpanName(spn), func(t *testing.T) {
				t.Helper()
				if strings.Contains(t.Name(), "cgo") {
					testenv.NeedsTool(t, "cgo")
				}
				if strings.Contains(t.Name(), "declarecgo") {
					testenv.NeedsGo1Point(t, 15)
				}
				tests.Definition(t, spn, d)
			})
		}
	})

	t.Run("Implementation", func(t *testing.T) {
		t.Helper()
		for spn, m := range data.Implementations {
			t.Run(SpanName(spn), func(t *testing.T) {
				t.Helper()
				tests.Implementation(t, spn, m)
			})
		}
	})

	t.Run("Highlight", func(t *testing.T) {
		t.Helper()
		for pos, locations := range data.Highlights {
			t.Run(SpanName(pos), func(t *testing.T) {
				t.Helper()
				tests.Highlight(t, pos, locations)
			})
		}
	})

	t.Run("Hover", func(t *testing.T) {
		t.Helper()
		for pos, info := range data.Hovers {
			t.Run(SpanName(pos), func(t *testing.T) {
				t.Helper()
				tests.Hover(t, pos, info)
			})
		}
	})

	t.Run("InlayHints", func(t *testing.T) {
		t.Helper()
		for _, src := range data.InlayHints {
			t.Run(SpanName(src), func(t *testing.T) {
				t.Helper()
				tests.InlayHints(t, src)
			})
		}
	})

	t.Run("References", func(t *testing.T) {
		t.Helper()
		for src, itemList := range data.References {
			t.Run(SpanName(src), func(t *testing.T) {
				t.Helper()
				tests.References(t, src, itemList)
			})
		}
	})

	t.Run("Renames", func(t *testing.T) {
		t.Helper()
		for spn, newText := range data.Renames {
			t.Run(uriName(spn.URI())+"_"+newText, func(t *testing.T) {
				t.Helper()
				tests.Rename(t, spn, newText)
			})
		}
	})

	t.Run("PrepareRenames", func(t *testing.T) {
		t.Helper()
		for src, want := range data.PrepareRenames {
			t.Run(SpanName(src), func(t *testing.T) {
				t.Helper()
				tests.PrepareRename(t, src, want)
			})
		}
	})

	t.Run("Symbols", func(t *testing.T) {
		t.Helper()
		for uri, allSymbols := range data.Symbols {
			byParent := make(map[string][]*symbol)
			for _, sym := range allSymbols {
				if sym.parentID != "" {
					byParent[sym.parentID] = append(byParent[sym.parentID], sym)
				}
			}

			// collectChildren does a depth-first traversal of the symbol tree,
			// computing children of child nodes before returning to their parent.
			// This is necessary as the Children field is slice of non-pointer types,
			// and therefore we need to be careful to mutate children first before
			// assigning them to their parent.
			var collectChildren func(id string) []protocol.DocumentSymbol
			collectChildren = func(id string) []protocol.DocumentSymbol {
				children := byParent[id]
				// delete from byParent before recursing, to ensure that
				// collectChildren terminates even in the presence of cycles.
				delete(byParent, id)
				var result []protocol.DocumentSymbol
				for _, child := range children {
					child.pSymbol.Children = collectChildren(child.id)
					result = append(result, child.pSymbol)
				}
				return result
			}

			var topLevel []protocol.DocumentSymbol
			for _, sym := range allSymbols {
				if sym.parentID == "" {
					sym.pSymbol.Children = collectChildren(sym.id)
					topLevel = append(topLevel, sym.pSymbol)
				}
			}

			t.Run(uriName(uri), func(t *testing.T) {
				t.Helper()
				tests.Symbols(t, uri, topLevel)
			})
		}
	})

	t.Run("WorkspaceSymbols", func(t *testing.T) {
		t.Helper()

		for _, typ := range []WorkspaceSymbolsTestType{
			WorkspaceSymbolsDefault,
			WorkspaceSymbolsCaseSensitive,
			WorkspaceSymbolsFuzzy,
		} {
			for uri, cases := range data.WorkspaceSymbols[typ] {
				for _, query := range cases {
					name := query
					if name == "" {
						name = "EmptyQuery"
					}
					t.Run(name, func(t *testing.T) {
						t.Helper()
						tests.WorkspaceSymbols(t, uri, query, typ)
					})
				}
			}
		}

	})

	t.Run("SignatureHelp", func(t *testing.T) {
		t.Helper()
		for spn, expectedSignature := range data.Signatures {
			t.Run(SpanName(spn), func(t *testing.T) {
				t.Helper()
				tests.SignatureHelp(t, spn, expectedSignature)
			})
		}
	})

	t.Run("Link", func(t *testing.T) {
		t.Helper()
		for uri, wantLinks := range data.Links {
			// If we are testing GOPATH, then we do not want links with the versions
			// attached (pkg.go.dev/repoa/moda@v1.1.0/pkg), unless the file is a
			// go.mod, then we can skip it altogether.
			if data.Exported.Exporter == packagestest.GOPATH {
				if strings.HasSuffix(uri.Filename(), ".mod") {
					continue
				}
				re := regexp.MustCompile(`@v\d+\.\d+\.[\w-]+`)
				for i, link := range wantLinks {
					wantLinks[i].Target = re.ReplaceAllString(link.Target, "")
				}
			}
			t.Run(uriName(uri), func(t *testing.T) {
				t.Helper()
				tests.Link(t, uri, wantLinks)
			})
		}
	})

	t.Run("AddImport", func(t *testing.T) {
		t.Helper()
		for uri, exp := range data.AddImport {
			t.Run(uriName(uri), func(t *testing.T) {
				tests.AddImport(t, uri, exp)
			})
		}
	})

	if *UpdateGolden {
		for _, golden := range data.golden {
			if !golden.Modified {
				continue
			}
			sort.Slice(golden.Archive.Files, func(i, j int) bool {
				return golden.Archive.Files[i].Name < golden.Archive.Files[j].Name
			})
			if err := ioutil.WriteFile(golden.Filename, txtar.Format(golden.Archive), 0666); err != nil {
				t.Fatal(err)
			}
		}
	}
}

func checkData(t *testing.T, data *Data) {
	buf := &bytes.Buffer{}
	diagnosticsCount := 0
	for _, want := range data.Diagnostics {
		diagnosticsCount += len(want)
	}
	linksCount := 0
	for _, want := range data.Links {
		linksCount += len(want)
	}
	definitionCount := 0
	typeDefinitionCount := 0
	for _, d := range data.Definitions {
		if d.IsType {
			typeDefinitionCount++
		} else {
			definitionCount++
		}
	}

	snippetCount := 0
	for _, want := range data.CompletionSnippets {
		snippetCount += len(want)
	}

	countCompletions := func(c map[span.Span][]Completion) (count int) {
		for _, want := range c {
			count += len(want)
		}
		return count
	}

	countCodeLens := func(c map[span.URI][]protocol.CodeLens) (count int) {
		for _, want := range c {
			count += len(want)
		}
		return count
	}

	countWorkspaceSymbols := func(c map[WorkspaceSymbolsTestType]map[span.URI][]string) (count int) {
		for _, typs := range c {
			for _, queries := range typs {
				count += len(queries)
			}
		}
		return count
	}

	fmt.Fprintf(buf, "CallHierarchyCount = %v\n", len(data.CallHierarchy))
	fmt.Fprintf(buf, "CodeLensCount = %v\n", countCodeLens(data.CodeLens))
	fmt.Fprintf(buf, "CompletionsCount = %v\n", countCompletions(data.Completions))
	fmt.Fprintf(buf, "CompletionSnippetCount = %v\n", snippetCount)
	fmt.Fprintf(buf, "UnimportedCompletionsCount = %v\n", countCompletions(data.UnimportedCompletions))
	fmt.Fprintf(buf, "DeepCompletionsCount = %v\n", countCompletions(data.DeepCompletions))
	fmt.Fprintf(buf, "FuzzyCompletionsCount = %v\n", countCompletions(data.FuzzyCompletions))
	fmt.Fprintf(buf, "RankedCompletionsCount = %v\n", countCompletions(data.RankCompletions))
	fmt.Fprintf(buf, "CaseSensitiveCompletionsCount = %v\n", countCompletions(data.CaseSensitiveCompletions))
	fmt.Fprintf(buf, "DiagnosticsCount = %v\n", diagnosticsCount)
	fmt.Fprintf(buf, "FoldingRangesCount = %v\n", len(data.FoldingRanges))
	fmt.Fprintf(buf, "FormatCount = %v\n", len(data.Formats))
	fmt.Fprintf(buf, "ImportCount = %v\n", len(data.Imports))
	fmt.Fprintf(buf, "SemanticTokenCount = %v\n", len(data.SemanticTokens))
	fmt.Fprintf(buf, "SuggestedFixCount = %v\n", len(data.SuggestedFixes))
	fmt.Fprintf(buf, "FunctionExtractionCount = %v\n", len(data.FunctionExtractions))
	fmt.Fprintf(buf, "MethodExtractionCount = %v\n", len(data.MethodExtractions))
	fmt.Fprintf(buf, "DefinitionsCount = %v\n", definitionCount)
	fmt.Fprintf(buf, "TypeDefinitionsCount = %v\n", typeDefinitionCount)
	fmt.Fprintf(buf, "HighlightsCount = %v\n", len(data.Highlights))
	fmt.Fprintf(buf, "InlayHintsCount = %v\n", len(data.InlayHints))
	fmt.Fprintf(buf, "ReferencesCount = %v\n", len(data.References))
	fmt.Fprintf(buf, "RenamesCount = %v\n", len(data.Renames))
	fmt.Fprintf(buf, "PrepareRenamesCount = %v\n", len(data.PrepareRenames))
	fmt.Fprintf(buf, "SymbolsCount = %v\n", len(data.Symbols))
	fmt.Fprintf(buf, "WorkspaceSymbolsCount = %v\n", countWorkspaceSymbols(data.WorkspaceSymbols))
	fmt.Fprintf(buf, "SignaturesCount = %v\n", len(data.Signatures))
	fmt.Fprintf(buf, "LinksCount = %v\n", linksCount)
	fmt.Fprintf(buf, "ImplementationsCount = %v\n", len(data.Implementations))

	want := string(data.Golden(t, "summary", summaryFile, func() ([]byte, error) {
		return buf.Bytes(), nil
	}))
	got := buf.String()
	if want != got {
		// These counters change when assertions are added or removed.
		// They act as an independent safety net to ensure that the
		// tests didn't spuriously pass because they did no work.
		t.Errorf("test summary does not match:\n%s\n(Run with -golden to update golden file; also, there may be one per Go version.)", compare.Text(want, got))
	}
}

func (data *Data) Mapper(uri span.URI) (*protocol.ColumnMapper, error) {
	data.mappersMu.Lock()
	defer data.mappersMu.Unlock()

	if _, ok := data.mappers[uri]; !ok {
		content, err := data.Exported.FileContents(uri.Filename())
		if err != nil {
			return nil, err
		}
		data.mappers[uri] = protocol.NewColumnMapper(uri, content)
	}
	return data.mappers[uri], nil
}

func (data *Data) Golden(t *testing.T, tag, target string, update func() ([]byte, error)) []byte {
	t.Helper()
	fragment, found := data.fragments[target]
	if !found {
		if filepath.IsAbs(target) {
			t.Fatalf("invalid golden file fragment %v", target)
		}
		fragment = target
	}
	golden := data.golden[fragment]
	if golden == nil {
		if !*UpdateGolden {
			t.Fatalf("could not find golden file %v: %v", fragment, tag)
		}
		golden = &Golden{
			Filename: filepath.Join(data.dir, fragment+goldenFileSuffix),
			Archive:  &txtar.Archive{},
			Modified: true,
		}
		data.golden[fragment] = golden
	}
	var file *txtar.File
	for i := range golden.Archive.Files {
		f := &golden.Archive.Files[i]
		if f.Name == tag {
			file = f
			break
		}
	}
	if *UpdateGolden {
		if file == nil {
			golden.Archive.Files = append(golden.Archive.Files, txtar.File{
				Name: tag,
			})
			file = &golden.Archive.Files[len(golden.Archive.Files)-1]
		}
		contents, err := update()
		if err != nil {
			t.Fatalf("could not update golden file %v: %v", fragment, err)
		}
		file.Data = append(contents, '\n') // add trailing \n for txtar
		golden.Modified = true

	}
	if file == nil {
		t.Fatalf("could not find golden contents %v: %v", fragment, tag)
	}
	if len(file.Data) == 0 {
		return file.Data
	}
	return file.Data[:len(file.Data)-1] // drop the trailing \n
}

func (data *Data) collectCodeLens(spn span.Span, title, cmd string) {
	data.CodeLens[spn.URI()] = append(data.CodeLens[spn.URI()], protocol.CodeLens{
		Range: data.mustRange(spn),
		Command: protocol.Command{
			Title:   title,
			Command: cmd,
		},
	})
}

func (data *Data) collectDiagnostics(spn span.Span, msgSource, msgPattern, msgSeverity string) {
	severity := protocol.SeverityError
	switch msgSeverity {
	case "error":
		severity = protocol.SeverityError
	case "warning":
		severity = protocol.SeverityWarning
	case "hint":
		severity = protocol.SeverityHint
	case "information":
		severity = protocol.SeverityInformation
	}

	data.Diagnostics[spn.URI()] = append(data.Diagnostics[spn.URI()], &source.Diagnostic{
		Range:    data.mustRange(spn),
		Severity: severity,
		Source:   source.DiagnosticSource(msgSource),
		Message:  msgPattern,
	})
}

func (data *Data) collectCompletions(typ CompletionTestType) func(span.Span, []token.Pos) {
	result := func(m map[span.Span][]Completion, src span.Span, expected []token.Pos) {
		m[src] = append(m[src], Completion{
			CompletionItems: expected,
		})
	}
	switch typ {
	case CompletionDeep:
		return func(src span.Span, expected []token.Pos) {
			result(data.DeepCompletions, src, expected)
		}
	case CompletionUnimported:
		return func(src span.Span, expected []token.Pos) {
			result(data.UnimportedCompletions, src, expected)
		}
	case CompletionFuzzy:
		return func(src span.Span, expected []token.Pos) {
			result(data.FuzzyCompletions, src, expected)
		}
	case CompletionRank:
		return func(src span.Span, expected []token.Pos) {
			result(data.RankCompletions, src, expected)
		}
	case CompletionCaseSensitive:
		return func(src span.Span, expected []token.Pos) {
			result(data.CaseSensitiveCompletions, src, expected)
		}
	default:
		return func(src span.Span, expected []token.Pos) {
			result(data.Completions, src, expected)
		}
	}
}

func (data *Data) collectCompletionItems(pos token.Pos, label, detail, kind string, args []string) {
	var documentation string
	if len(args) > 3 {
		documentation = args[3]
	}
	data.CompletionItems[pos] = &completion.CompletionItem{
		Label:         label,
		Detail:        detail,
		Kind:          protocol.ParseCompletionItemKind(kind),
		Documentation: documentation,
	}
}

func (data *Data) collectFoldingRanges(spn span.Span) {
	data.FoldingRanges = append(data.FoldingRanges, spn)
}

func (data *Data) collectFormats(spn span.Span) {
	data.Formats = append(data.Formats, spn)
}

func (data *Data) collectImports(spn span.Span) {
	data.Imports = append(data.Imports, spn)
}

func (data *Data) collectAddImports(spn span.Span, imp string) {
	data.AddImport[spn.URI()] = imp
}

func (data *Data) collectSemanticTokens(spn span.Span) {
	data.SemanticTokens = append(data.SemanticTokens, spn)
}

func (data *Data) collectSuggestedFixes(spn span.Span, actionKind, fix string) {
	data.SuggestedFixes[spn] = append(data.SuggestedFixes[spn], SuggestedFix{actionKind, fix})
}

func (data *Data) collectFunctionExtractions(start span.Span, end span.Span) {
	if _, ok := data.FunctionExtractions[start]; !ok {
		data.FunctionExtractions[start] = end
	}
}

func (data *Data) collectMethodExtractions(start span.Span, end span.Span) {
	if _, ok := data.MethodExtractions[start]; !ok {
		data.MethodExtractions[start] = end
	}
}

func (data *Data) collectDefinitions(src, target span.Span) {
	data.Definitions[src] = Definition{
		Src: src,
		Def: target,
	}
}

func (data *Data) collectImplementations(src span.Span, targets []span.Span) {
	data.Implementations[src] = targets
}

func (data *Data) collectIncomingCalls(src span.Span, calls []span.Span) {
	for _, call := range calls {
		rng := data.mustRange(call)
		// we're only comparing protocol.range
		if data.CallHierarchy[src] != nil {
			data.CallHierarchy[src].IncomingCalls = append(data.CallHierarchy[src].IncomingCalls,
				protocol.CallHierarchyItem{
					URI:   protocol.DocumentURI(call.URI()),
					Range: rng,
				})
		} else {
			data.CallHierarchy[src] = &CallHierarchyResult{
				IncomingCalls: []protocol.CallHierarchyItem{
					{URI: protocol.DocumentURI(call.URI()), Range: rng},
				},
			}
		}
	}
}

func (data *Data) collectOutgoingCalls(src span.Span, calls []span.Span) {
	if data.CallHierarchy[src] == nil {
		data.CallHierarchy[src] = &CallHierarchyResult{}
	}
	for _, call := range calls {
		// we're only comparing protocol.range
		data.CallHierarchy[src].OutgoingCalls = append(data.CallHierarchy[src].OutgoingCalls,
			protocol.CallHierarchyItem{
				URI:   protocol.DocumentURI(call.URI()),
				Range: data.mustRange(call),
			})
	}
}

func (data *Data) collectHoverDefinitions(src, target span.Span) {
	data.Definitions[src] = Definition{
		Src:       src,
		Def:       target,
		OnlyHover: true,
	}
}

func (data *Data) collectHovers(src span.Span, expected string) {
	data.Hovers[src] = expected
}

func (data *Data) collectTypeDefinitions(src, target span.Span) {
	data.Definitions[src] = Definition{
		Src:    src,
		Def:    target,
		IsType: true,
	}
}

func (data *Data) collectDefinitionNames(src span.Span, name string) {
	d := data.Definitions[src]
	d.Name = name
	data.Definitions[src] = d
}

func (data *Data) collectHighlights(src span.Span, expected []span.Span) {
	// Declaring a highlight in a test file: @highlight(src, expected1, expected2)
	data.Highlights[src] = append(data.Highlights[src], expected...)
}

func (data *Data) collectInlayHints(src span.Span) {
	data.InlayHints = append(data.InlayHints, src)
}

func (data *Data) collectReferences(src span.Span, expected []span.Span) {
	data.References[src] = expected
}

func (data *Data) collectRenames(src span.Span, newText string) {
	data.Renames[src] = newText
}

func (data *Data) collectPrepareRenames(src, spn span.Span, placeholder string) {
	data.PrepareRenames[src] = &source.PrepareItem{
		Range: data.mustRange(spn),
		Text:  placeholder,
	}
}

// collectSymbols is responsible for collecting @symbol annotations.
func (data *Data) collectSymbols(name string, selectionRng span.Span, kind, detail, id, parentID string) {
	// We don't set 'Range' here as it is difficult (impossible?) to express
	// multi-line ranges in the packagestest framework.
	uri := selectionRng.URI()
	data.Symbols[uri] = append(data.Symbols[uri], &symbol{
		pSymbol: protocol.DocumentSymbol{
			Name:           name,
			Kind:           protocol.ParseSymbolKind(kind),
			SelectionRange: data.mustRange(selectionRng),
			Detail:         detail,
		},
		id:       id,
		parentID: parentID,
	})
}

// mustRange converts spn into a protocol.Range, panicking on any error.
func (data *Data) mustRange(spn span.Span) protocol.Range {
	m, err := data.Mapper(spn.URI())
	rng, err := m.Range(spn)
	if err != nil {
		panic(fmt.Sprintf("converting span %s to range: %v", spn, err))
	}
	return rng
}

func (data *Data) collectWorkspaceSymbols(typ WorkspaceSymbolsTestType) func(*expect.Note, string) {
	return func(note *expect.Note, query string) {
		if data.WorkspaceSymbols[typ] == nil {
			data.WorkspaceSymbols[typ] = make(map[span.URI][]string)
		}
		pos := data.Exported.ExpectFileSet.Position(note.Pos)
		uri := span.URIFromPath(pos.Filename)
		data.WorkspaceSymbols[typ][uri] = append(data.WorkspaceSymbols[typ][uri], query)
	}
}

func (data *Data) collectSignatures(spn span.Span, signature string, activeParam int64) {
	data.Signatures[spn] = &protocol.SignatureHelp{
		Signatures: []protocol.SignatureInformation{
			{
				Label: signature,
			},
		},
		ActiveParameter: uint32(activeParam),
	}
	// Hardcode special case to test the lack of a signature.
	if signature == "" && activeParam == 0 {
		data.Signatures[spn] = nil
	}
}

func (data *Data) collectCompletionSnippets(spn span.Span, item token.Pos, plain, placeholder string) {
	data.CompletionSnippets[spn] = append(data.CompletionSnippets[spn], CompletionSnippet{
		CompletionItem:     item,
		PlainSnippet:       plain,
		PlaceholderSnippet: placeholder,
	})
}

func (data *Data) collectLinks(spn span.Span, link string, note *expect.Note, fset *token.FileSet) {
	position := fset.Position(note.Pos)
	uri := spn.URI()
	data.Links[uri] = append(data.Links[uri], Link{
		Src:          spn,
		Target:       link,
		NotePosition: position,
	})
}

func uriName(uri span.URI) string {
	return filepath.Base(strings.TrimSuffix(uri.Filename(), ".go"))
}

func SpanName(spn span.Span) string {
	return fmt.Sprintf("%v_%v_%v", uriName(spn.URI()), spn.Start().Line(), spn.Start().Column())
}

func CopyFolderToTempDir(folder string) (string, error) {
	if _, err := os.Stat(folder); err != nil {
		return "", err
	}
	dst, err := ioutil.TempDir("", "modfile_test")
	if err != nil {
		return "", err
	}
	fds, err := ioutil.ReadDir(folder)
	if err != nil {
		return "", err
	}
	for _, fd := range fds {
		srcfp := filepath.Join(folder, fd.Name())
		stat, err := os.Stat(srcfp)
		if err != nil {
			return "", err
		}
		if !stat.Mode().IsRegular() {
			return "", fmt.Errorf("cannot copy non regular file %s", srcfp)
		}
		contents, err := ioutil.ReadFile(srcfp)
		if err != nil {
			return "", err
		}
		if err := ioutil.WriteFile(filepath.Join(dst, fd.Name()), contents, stat.Mode()); err != nil {
			return "", err
		}
	}
	return dst, nil
}

func shouldSkip(data *Data, uri span.URI) bool {
	if data.ModfileFlagAvailable {
		return false
	}
	// If the -modfile flag is not available, then we do not want to run
	// any tests on the go.mod file.
	if strings.HasSuffix(uri.Filename(), ".mod") {
		return true
	}
	// If the -modfile flag is not available, then we do not want to test any
	// uri that contains "go mod tidy".
	m, err := data.Mapper(uri)
	return err == nil && strings.Contains(string(m.Content), ", \"go mod tidy\",")
}
