// 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 workspace

import (
	"context"
	"fmt"
	"path/filepath"
	"strings"
	"testing"

	"golang.org/x/tools/gopls/internal/bug"
	"golang.org/x/tools/gopls/internal/hooks"
	"golang.org/x/tools/gopls/internal/lsp"
	"golang.org/x/tools/gopls/internal/lsp/fake"
	"golang.org/x/tools/gopls/internal/lsp/protocol"
	"golang.org/x/tools/internal/gocommand"
	"golang.org/x/tools/internal/testenv"

	. "golang.org/x/tools/gopls/internal/lsp/regtest"
)

func TestMain(m *testing.M) {
	bug.PanicOnBugs = true
	Main(m, hooks.Options)
}

const workspaceProxy = `
-- example.com@v1.2.3/go.mod --
module example.com

go 1.12
-- example.com@v1.2.3/blah/blah.go --
package blah

import "fmt"

func SaySomething() {
	fmt.Println("something")
}
-- random.org@v1.2.3/go.mod --
module random.org

go 1.12
-- random.org@v1.2.3/bye/bye.go --
package bye

func Goodbye() {
	println("Bye")
}
`

// TODO: Add a replace directive.
const workspaceModule = `
-- pkg/go.mod --
module mod.com

go 1.14

require (
	example.com v1.2.3
	random.org v1.2.3
)
-- pkg/go.sum --
example.com v1.2.3 h1:veRD4tUnatQRgsULqULZPjeoBGFr2qBhevSCZllD2Ds=
example.com v1.2.3/go.mod h1:Y2Rc5rVWjWur0h3pd9aEvK5Pof8YKDANh9gHA2Maujo=
random.org v1.2.3 h1:+JE2Fkp7gS0zsHXGEQJ7hraom3pNTlkxC4b2qPfA+/Q=
random.org v1.2.3/go.mod h1:E9KM6+bBX2g5ykHZ9H27w16sWo3QwgonyjM44Dnej3I=
-- pkg/main.go --
package main

import (
	"example.com/blah"
	"mod.com/inner"
	"random.org/bye"
)

func main() {
	blah.SaySomething()
	inner.Hi()
	bye.Goodbye()
}
-- pkg/main2.go --
package main

import "fmt"

func _() {
	fmt.Print("%s")
}
-- pkg/inner/inner.go --
package inner

import "example.com/blah"

func Hi() {
	blah.SaySomething()
}
-- goodbye/bye/bye.go --
package bye

func Bye() {}
-- goodbye/go.mod --
module random.org

go 1.12
`

// Confirm that find references returns all of the references in the module,
// regardless of what the workspace root is.
func TestReferences(t *testing.T) {
	for _, tt := range []struct {
		name, rootPath string
	}{
		{
			name:     "module root",
			rootPath: "pkg",
		},
		{
			name:     "subdirectory",
			rootPath: "pkg/inner",
		},
	} {
		t.Run(tt.name, func(t *testing.T) {
			opts := []RunOption{ProxyFiles(workspaceProxy)}
			if tt.rootPath != "" {
				opts = append(opts, WorkspaceFolders(tt.rootPath))
			}
			WithOptions(opts...).Run(t, workspaceModule, func(t *testing.T, env *Env) {
				f := "pkg/inner/inner.go"
				env.OpenFile(f)
				locations := env.References(env.RegexpSearch(f, `SaySomething`))
				want := 3
				if got := len(locations); got != want {
					t.Fatalf("expected %v locations, got %v", want, got)
				}
			})
		})
	}
}

// Make sure that analysis diagnostics are cleared for the whole package when
// the only opened file is closed. This test was inspired by the experience in
// VS Code, where clicking on a reference result triggers a
// textDocument/didOpen without a corresponding textDocument/didClose.
func TestClearAnalysisDiagnostics(t *testing.T) {
	WithOptions(
		ProxyFiles(workspaceProxy),
		WorkspaceFolders("pkg/inner"),
	).Run(t, workspaceModule, func(t *testing.T, env *Env) {
		env.OpenFile("pkg/main.go")
		env.AfterChange(
			Diagnostics(env.AtRegexp("pkg/main2.go", "fmt.Print")),
		)
		env.CloseBuffer("pkg/main.go")
		env.AfterChange(
			NoDiagnostics(ForFile("pkg/main2.go")),
		)
	})
}

// TestReloadOnlyOnce checks that changes to the go.mod file do not result in
// redundant package loads (golang/go#54473).
//
// Note that this test may be fragile, as it depends on specific structure to
// log messages around reinitialization. Nevertheless, it is important for
// guarding against accidentally duplicate reloading.
func TestReloadOnlyOnce(t *testing.T) {
	WithOptions(
		ProxyFiles(workspaceProxy),
		WorkspaceFolders("pkg"),
	).Run(t, workspaceModule, func(t *testing.T, env *Env) {
		dir := env.Sandbox.Workdir.URI("goodbye").SpanURI().Filename()
		goModWithReplace := fmt.Sprintf(`%s
replace random.org => %s
`, env.ReadWorkspaceFile("pkg/go.mod"), dir)
		env.WriteWorkspaceFile("pkg/go.mod", goModWithReplace)
		env.AfterChange(
			LogMatching(protocol.Info, `packages\.Load #\d+\n`, 2, false),
		)
	})
}

// This test checks that gopls updates the set of files it watches when a
// replace target is added to the go.mod.
func TestWatchReplaceTargets(t *testing.T) {
	t.Skipf("skipping known-flaky test: see https://go.dev/issue/50748")

	WithOptions(
		ProxyFiles(workspaceProxy),
		WorkspaceFolders("pkg"),
	).Run(t, workspaceModule, func(t *testing.T, env *Env) {
		// Add a replace directive and expect the files that gopls is watching
		// to change.
		dir := env.Sandbox.Workdir.URI("goodbye").SpanURI().Filename()
		goModWithReplace := fmt.Sprintf(`%s
replace random.org => %s
`, env.ReadWorkspaceFile("pkg/go.mod"), dir)
		env.WriteWorkspaceFile("pkg/go.mod", goModWithReplace)
		env.AfterChange(
			UnregistrationMatching("didChangeWatchedFiles"),
			RegistrationMatching("didChangeWatchedFiles"),
		)
	})
}

const workspaceModuleProxy = `
-- example.com@v1.2.3/go.mod --
module example.com

go 1.12
-- example.com@v1.2.3/blah/blah.go --
package blah

import "fmt"

func SaySomething() {
	fmt.Println("something")
}
-- b.com@v1.2.3/go.mod --
module b.com

go 1.12
-- b.com@v1.2.3/b/b.go --
package b

func Hello() {}
`

func TestAutomaticWorkspaceModule_Interdependent(t *testing.T) {
	testenv.NeedsGo1Point(t, 18) // uses go.work
	const multiModule = `
-- moda/a/go.mod --
module a.com

require b.com v1.2.3
-- moda/a/go.sum --
b.com v1.2.3 h1:tXrlXP0rnjRpKNmkbLYoWBdq0ikb3C3bKK9//moAWBI=
b.com v1.2.3/go.mod h1:D+J7pfFBZK5vdIdZEFquR586vKKIkqG7Qjw9AxG5BQ8=
-- moda/a/a.go --
package a

import (
	"b.com/b"
)

func main() {
	var x int
	_ = b.Hello()
}
-- modb/go.mod --
module b.com

-- modb/b/b.go --
package b

func Hello() int {
	var x int
}
`
	WithOptions(
		ProxyFiles(workspaceModuleProxy),
	).Run(t, multiModule, func(t *testing.T, env *Env) {
		env.RunGoCommand("work", "init")
		env.RunGoCommand("work", "use", "-r", ".")
		env.AfterChange(
			Diagnostics(env.AtRegexp("moda/a/a.go", "x")),
			Diagnostics(env.AtRegexp("modb/b/b.go", "x")),
			NoDiagnostics(env.AtRegexp("moda/a/a.go", `"b.com/b"`)),
		)
	})
}

func TestModuleWithExclude(t *testing.T) {
	const proxy = `
-- c.com@v1.2.3/go.mod --
module c.com

go 1.12

require b.com v1.2.3
-- c.com@v1.2.3/blah/blah.go --
package blah

import "fmt"

func SaySomething() {
	fmt.Println("something")
}
-- b.com@v1.2.3/go.mod --
module b.com

go 1.12
-- b.com@v1.2.4/b/b.go --
package b

func Hello() {}
-- b.com@v1.2.4/go.mod --
module b.com

go 1.12
`
	const multiModule = `
-- go.mod --
module a.com

require c.com v1.2.3

exclude b.com v1.2.3
-- go.sum --
c.com v1.2.3 h1:n07Dz9fYmpNqvZMwZi5NEqFcSHbvLa9lacMX+/g25tw=
c.com v1.2.3/go.mod h1:/4TyYgU9Nu5tA4NymP5xyqE8R2VMzGD3TbJCwCOvHAg=
-- main.go --
package a

func main() {
	var x int
}
`
	WithOptions(
		ProxyFiles(proxy),
	).Run(t, multiModule, func(t *testing.T, env *Env) {
		env.OnceMet(
			InitialWorkspaceLoad,
			Diagnostics(env.AtRegexp("main.go", "x")),
		)
	})
}

// This change tests that the version of the module used changes after it has
// been deleted from the workspace.
//
// TODO(golang/go#55331): delete this placeholder along with experimental
// workspace module.
func TestDeleteModule_Interdependent(t *testing.T) {
	testenv.NeedsGo1Point(t, 18) // uses go.work
	const multiModule = `
-- go.work --
go 1.18

use (
	moda/a
	modb
)
-- moda/a/go.mod --
module a.com

require b.com v1.2.3
-- moda/a/go.sum --
b.com v1.2.3 h1:tXrlXP0rnjRpKNmkbLYoWBdq0ikb3C3bKK9//moAWBI=
b.com v1.2.3/go.mod h1:D+J7pfFBZK5vdIdZEFquR586vKKIkqG7Qjw9AxG5BQ8=
-- moda/a/a.go --
package a

import (
	"b.com/b"
)

func main() {
	var x int
	_ = b.Hello()
}
-- modb/go.mod --
module b.com

-- modb/b/b.go --
package b

func Hello() int {
	var x int
}
`
	WithOptions(
		ProxyFiles(workspaceModuleProxy),
	).Run(t, multiModule, func(t *testing.T, env *Env) {
		env.OpenFile("moda/a/a.go")
		env.Await(env.DoneWithOpen())

		originalLoc := env.GoToDefinition(env.RegexpSearch("moda/a/a.go", "Hello"))
		original := env.Sandbox.Workdir.URIToPath(originalLoc.URI)
		if want := "modb/b/b.go"; !strings.HasSuffix(original, want) {
			t.Errorf("expected %s, got %v", want, original)
		}
		env.CloseBuffer(original)
		env.AfterChange()

		env.RemoveWorkspaceFile("modb/b/b.go")
		env.RemoveWorkspaceFile("modb/go.mod")
		env.WriteWorkspaceFile("go.work", "go 1.18\nuse moda/a")
		env.AfterChange()

		gotLoc := env.GoToDefinition(env.RegexpSearch("moda/a/a.go", "Hello"))
		got := env.Sandbox.Workdir.URIToPath(gotLoc.URI)
		if want := "b.com@v1.2.3/b/b.go"; !strings.HasSuffix(got, want) {
			t.Errorf("expected %s, got %v", want, got)
		}
	})
}

// Tests that the version of the module used changes after it has been added
// to the workspace.
func TestCreateModule_Interdependent(t *testing.T) {
	testenv.NeedsGo1Point(t, 18) // uses go.work
	const multiModule = `
-- go.work --
go 1.18

use (
	moda/a
)
-- moda/a/go.mod --
module a.com

require b.com v1.2.3
-- moda/a/go.sum --
b.com v1.2.3 h1:tXrlXP0rnjRpKNmkbLYoWBdq0ikb3C3bKK9//moAWBI=
b.com v1.2.3/go.mod h1:D+J7pfFBZK5vdIdZEFquR586vKKIkqG7Qjw9AxG5BQ8=
-- moda/a/a.go --
package a

import (
	"b.com/b"
)

func main() {
	var x int
	_ = b.Hello()
}
`
	WithOptions(
		ProxyFiles(workspaceModuleProxy),
	).Run(t, multiModule, func(t *testing.T, env *Env) {
		env.OpenFile("moda/a/a.go")
		loc := env.GoToDefinition(env.RegexpSearch("moda/a/a.go", "Hello"))
		original := env.Sandbox.Workdir.URIToPath(loc.URI)
		if want := "b.com@v1.2.3/b/b.go"; !strings.HasSuffix(original, want) {
			t.Errorf("expected %s, got %v", want, original)
		}
		env.CloseBuffer(original)
		env.WriteWorkspaceFiles(map[string]string{
			"go.work": `go 1.18

use (
	moda/a
	modb
)
`,
			"modb/go.mod": "module b.com",
			"modb/b/b.go": `package b

func Hello() int {
	var x int
}
`,
		})
		env.AfterChange(Diagnostics(env.AtRegexp("modb/b/b.go", "x")))
		gotLoc := env.GoToDefinition(env.RegexpSearch("moda/a/a.go", "Hello"))
		got := env.Sandbox.Workdir.URIToPath(gotLoc.URI)
		if want := "modb/b/b.go"; !strings.HasSuffix(got, want) {
			t.Errorf("expected %s, got %v", want, original)
		}
	})
}

// This test confirms that a gopls workspace can recover from initialization
// with one invalid module.
func TestOneBrokenModule(t *testing.T) {
	testenv.NeedsGo1Point(t, 18) // uses go.work
	const multiModule = `
-- go.work --
go 1.18

use (
	moda/a
	modb
)
-- moda/a/go.mod --
module a.com

require b.com v1.2.3

-- moda/a/a.go --
package a

import (
	"b.com/b"
)

func main() {
	var x int
	_ = b.Hello()
}
-- modb/go.mod --
modul b.com // typo here

-- modb/b/b.go --
package b

func Hello() int {
	var x int
}
`
	WithOptions(
		ProxyFiles(workspaceModuleProxy),
	).Run(t, multiModule, func(t *testing.T, env *Env) {
		env.OpenFile("modb/go.mod")
		env.AfterChange(
			Diagnostics(AtPosition("modb/go.mod", 0, 0)),
		)
		env.RegexpReplace("modb/go.mod", "modul", "module")
		env.SaveBufferWithoutActions("modb/go.mod")
		env.AfterChange(
			Diagnostics(env.AtRegexp("modb/b/b.go", "x")),
		)
	})
}

// TestBadGoWork exercises the panic from golang/vscode-go#2121.
func TestBadGoWork(t *testing.T) {
	const files = `
-- go.work --
use ./bar
-- bar/go.mod --
module example.com/bar
`
	Run(t, files, func(t *testing.T, env *Env) {
		env.OpenFile("go.work")
	})
}

func TestUseGoWork(t *testing.T) {
	testenv.NeedsGo1Point(t, 18) // uses go.work
	// This test validates certain functionality related to using a go.work
	// file to specify workspace modules.
	const multiModule = `
-- moda/a/go.mod --
module a.com

require b.com v1.2.3
-- moda/a/go.sum --
b.com v1.2.3 h1:tXrlXP0rnjRpKNmkbLYoWBdq0ikb3C3bKK9//moAWBI=
b.com v1.2.3/go.mod h1:D+J7pfFBZK5vdIdZEFquR586vKKIkqG7Qjw9AxG5BQ8=
-- moda/a/a.go --
package a

import (
	"b.com/b"
)

func main() {
	var x int
	_ = b.Hello()
}
-- modb/go.mod --
module b.com

require example.com v1.2.3
-- modb/go.sum --
example.com v1.2.3 h1:Yryq11hF02fEf2JlOS2eph+ICE2/ceevGV3C9dl5V/c=
example.com v1.2.3/go.mod h1:Y2Rc5rVWjWur0h3pd9aEvK5Pof8YKDANh9gHA2Maujo=
-- modb/b/b.go --
package b

func Hello() int {
	var x int
}
-- go.work --
go 1.17

use (
	./moda/a
)
`
	WithOptions(
		ProxyFiles(workspaceModuleProxy),
	).Run(t, multiModule, func(t *testing.T, env *Env) {
		// Initially, the go.work should cause only the a.com module to be
		// loaded. Validate this by jumping to a definition in b.com and ensuring
		// that we go to the module cache.
		env.OpenFile("moda/a/a.go")
		env.Await(env.DoneWithOpen())

		// To verify which modules are loaded, we'll jump to the definition of
		// b.Hello.
		checkHelloLocation := func(want string) error {
			loc := env.GoToDefinition(env.RegexpSearch("moda/a/a.go", "Hello"))
			file := env.Sandbox.Workdir.URIToPath(loc.URI)
			if !strings.HasSuffix(file, want) {
				return fmt.Errorf("expected %s, got %v", want, file)
			}
			return nil
		}

		// Initially this should be in the module cache, as b.com is not replaced.
		if err := checkHelloLocation("b.com@v1.2.3/b/b.go"); err != nil {
			t.Fatal(err)
		}

		// Now, modify the go.work file on disk to activate the b.com module in
		// the workspace.
		env.WriteWorkspaceFile("go.work", `
go 1.17

use (
	./moda/a
	./modb
)
`)

		// As of golang/go#54069, writing go.work to the workspace triggers a
		// workspace reload.
		env.AfterChange(
			Diagnostics(env.AtRegexp("modb/b/b.go", "x")),
		)

		// Jumping to definition should now go to b.com in the workspace.
		if err := checkHelloLocation("modb/b/b.go"); err != nil {
			t.Fatal(err)
		}

		// Now, let's modify the go.work *overlay* (not on disk), and verify that
		// this change is only picked up once it is saved.
		env.OpenFile("go.work")
		env.AfterChange()
		env.SetBufferContent("go.work", `go 1.17

use (
	./moda/a
)`)

		// Simply modifying the go.work file does not cause a reload, so we should
		// still jump within the workspace.
		//
		// TODO: should editing the go.work above cause modb diagnostics to be
		// suppressed?
		env.Await(env.DoneWithChange())
		if err := checkHelloLocation("modb/b/b.go"); err != nil {
			t.Fatal(err)
		}

		// Saving should reload the workspace.
		env.SaveBufferWithoutActions("go.work")
		if err := checkHelloLocation("b.com@v1.2.3/b/b.go"); err != nil {
			t.Fatal(err)
		}

		// This fails if guarded with a OnceMet(DoneWithSave(), ...), because it is
		// delayed (and therefore not synchronous with the change).
		env.Await(NoDiagnostics(ForFile("modb/go.mod")))

		// Test Formatting.
		env.SetBufferContent("go.work", `go 1.18
  use      (



		./moda/a
)
`) // TODO(matloob): For some reason there's a "start position 7:0 is out of bounds" error when the ")" is on the last character/line in the file. Rob probably knows what's going on.
		env.SaveBuffer("go.work")
		env.Await(env.DoneWithSave())
		gotWorkContents := env.ReadWorkspaceFile("go.work")
		wantWorkContents := `go 1.18

use (
	./moda/a
)
`
		if gotWorkContents != wantWorkContents {
			t.Fatalf("formatted contents of workspace: got %q; want %q", gotWorkContents, wantWorkContents)
		}
	})
}

func TestUseGoWorkDiagnosticMissingModule(t *testing.T) {
	testenv.NeedsGo1Point(t, 18) // uses go.work

	const files = `
-- go.work --
go 1.18

use ./foo
-- bar/go.mod --
module example.com/bar
`
	Run(t, files, func(t *testing.T, env *Env) {
		env.OpenFile("go.work")
		env.AfterChange(
			Diagnostics(env.AtRegexp("go.work", "use"), WithMessage("directory ./foo does not contain a module")),
		)
		// The following tests is a regression test against an issue where we weren't
		// copying the workFile struct field on workspace when a new one was created in
		// (*workspace).invalidate. Set the buffer content to a working file so that
		// invalidate recognizes the workspace to be change and copies over the workspace
		// struct, and then set the content back to the old contents to make sure
		// the diagnostic still shows up.
		env.SetBufferContent("go.work", "go 1.18 \n\n use ./bar\n")
		env.AfterChange(
			NoDiagnostics(env.AtRegexp("go.work", "use")),
		)
		env.SetBufferContent("go.work", "go 1.18 \n\n use ./foo\n")
		env.AfterChange(
			Diagnostics(env.AtRegexp("go.work", "use"), WithMessage("directory ./foo does not contain a module")),
		)
	})
}

func TestUseGoWorkDiagnosticSyntaxError(t *testing.T) {
	testenv.NeedsGo1Point(t, 18)
	const files = `
-- go.work --
go 1.18

usa ./foo
replace
`
	Run(t, files, func(t *testing.T, env *Env) {
		env.OpenFile("go.work")
		env.AfterChange(
			Diagnostics(env.AtRegexp("go.work", "usa"), WithMessage("unknown directive: usa")),
			Diagnostics(env.AtRegexp("go.work", "replace"), WithMessage("usage: replace")),
		)
	})
}

func TestUseGoWorkHover(t *testing.T) {
	testenv.NeedsGo1Point(t, 18)

	const files = `
-- go.work --
go 1.18

use ./foo
use (
	./bar
	./bar/baz
)
-- foo/go.mod --
module example.com/foo
-- bar/go.mod --
module example.com/bar
-- bar/baz/go.mod --
module example.com/bar/baz
`
	Run(t, files, func(t *testing.T, env *Env) {
		env.OpenFile("go.work")

		tcs := map[string]string{
			`\./foo`:      "example.com/foo",
			`(?m)\./bar$`: "example.com/bar",
			`\./bar/baz`:  "example.com/bar/baz",
		}

		for hoverRE, want := range tcs {
			got, _ := env.Hover(env.RegexpSearch("go.work", hoverRE))
			if got.Value != want {
				t.Errorf(`hover on %q: got %q, want %q`, hoverRE, got, want)
			}
		}
	})
}

func TestExpandToGoWork(t *testing.T) {
	testenv.NeedsGo1Point(t, 18)
	const workspace = `
-- moda/a/go.mod --
module a.com

require b.com v1.2.3
-- moda/a/a.go --
package a

import (
	"b.com/b"
)

func main() {
	var x int
	_ = b.Hello()
}
-- modb/go.mod --
module b.com

require example.com v1.2.3
-- modb/b/b.go --
package b

func Hello() int {
	var x int
}
-- go.work --
go 1.17

use (
	./moda/a
	./modb
)
`
	WithOptions(
		WorkspaceFolders("moda/a"),
	).Run(t, workspace, func(t *testing.T, env *Env) {
		env.OpenFile("moda/a/a.go")
		env.Await(env.DoneWithOpen())
		loc := env.GoToDefinition(env.RegexpSearch("moda/a/a.go", "Hello"))
		file := env.Sandbox.Workdir.URIToPath(loc.URI)
		want := "modb/b/b.go"
		if !strings.HasSuffix(file, want) {
			t.Errorf("expected %s, got %v", want, file)
		}
	})
}

func TestNonWorkspaceFileCreation(t *testing.T) {
	const files = `
-- work/go.mod --
module mod.com

go 1.12
-- work/x.go --
package x
`

	const code = `
package foo
import "fmt"
var _ = fmt.Printf
`
	WithOptions(
		WorkspaceFolders("work"), // so that outside/... is outside the workspace
	).Run(t, files, func(t *testing.T, env *Env) {
		env.CreateBuffer("outside/foo.go", "")
		env.EditBuffer("outside/foo.go", fake.NewEdit(0, 0, 0, 0, code))
		env.GoToDefinition(env.RegexpSearch("outside/foo.go", `Printf`))
	})
}

func TestGoWork_V2Module(t *testing.T) {
	testenv.NeedsGo1Point(t, 18) // uses go.work
	// When using a go.work, we must have proxy content even if it is replaced.
	const proxy = `
-- b.com/v2@v2.1.9/go.mod --
module b.com/v2

go 1.12
-- b.com/v2@v2.1.9/b/b.go --
package b

func Ciao()() int {
	return 0
}
`

	const multiModule = `
-- go.work --
go 1.18

use (
	moda/a
	modb
	modb/v2
	modc
)
-- moda/a/go.mod --
module a.com

require b.com/v2 v2.1.9
-- moda/a/a.go --
package a

import (
	"b.com/v2/b"
)

func main() {
	var x int
	_ = b.Hi()
}
-- modb/go.mod --
module b.com

-- modb/b/b.go --
package b

func Hello() int {
	var x int
}
-- modb/v2/go.mod --
module b.com/v2

-- modb/v2/b/b.go --
package b

func Hi() int {
	var x int
}
-- modc/go.mod --
module gopkg.in/yaml.v1 // test gopkg.in versions
-- modc/main.go --
package main

func main() {
	var x int
}
`

	WithOptions(
		ProxyFiles(proxy),
	).Run(t, multiModule, func(t *testing.T, env *Env) {
		env.OnceMet(
			InitialWorkspaceLoad,
			// TODO(rfindley): assert on the full set of diagnostics here. We
			// should ensure that we don't have a diagnostic at b.Hi in a.go.
			Diagnostics(env.AtRegexp("moda/a/a.go", "x")),
			Diagnostics(env.AtRegexp("modb/b/b.go", "x")),
			Diagnostics(env.AtRegexp("modb/v2/b/b.go", "x")),
			Diagnostics(env.AtRegexp("modc/main.go", "x")),
		)
	})
}

// Confirm that a fix for a tidy module will correct all modules in the
// workspace.
func TestMultiModule_OneBrokenModule(t *testing.T) {
	// In the earlier 'experimental workspace mode', gopls would aggregate go.sum
	// entries for the workspace module, allowing it to correctly associate
	// missing go.sum with diagnostics. With go.work files, this doesn't work:
	// the go.command will happily write go.work.sum.
	t.Skip("golang/go#57509: go.mod diagnostics do not work in go.work mode")
	testenv.NeedsGo1Point(t, 18) // uses go.work
	const files = `
-- go.work --
go 1.18

use (
	a
	b
)
-- go.work.sum --
-- a/go.mod --
module a.com

go 1.12
-- a/main.go --
package main
-- b/go.mod --
module b.com

go 1.12

require (
	example.com v1.2.3
)
-- b/go.sum --
-- b/main.go --
package b

import "example.com/blah"

func main() {
	blah.Hello()
}
`
	WithOptions(
		ProxyFiles(workspaceProxy),
	).Run(t, files, func(t *testing.T, env *Env) {
		params := &protocol.PublishDiagnosticsParams{}
		env.OpenFile("b/go.mod")
		env.AfterChange(
			Diagnostics(
				env.AtRegexp("go.mod", `example.com v1.2.3`),
				WithMessage("go.sum is out of sync"),
			),
			ReadDiagnostics("b/go.mod", params),
		)
		for _, d := range params.Diagnostics {
			if !strings.Contains(d.Message, "go.sum is out of sync") {
				continue
			}
			actions := env.GetQuickFixes("b/go.mod", []protocol.Diagnostic{d})
			if len(actions) != 2 {
				t.Fatalf("expected 2 code actions, got %v", len(actions))
			}
			env.ApplyQuickFixes("b/go.mod", []protocol.Diagnostic{d})
		}
		env.AfterChange(
			NoDiagnostics(ForFile("b/go.mod")),
		)
	})
}

// Sometimes users may have their module cache within the workspace.
// We shouldn't consider any module in the module cache to be in the workspace.
func TestGOMODCACHEInWorkspace(t *testing.T) {
	const mod = `
-- a/go.mod --
module a.com

go 1.12
-- a/a.go --
package a

func _() {}
-- a/c/c.go --
package c
-- gopath/src/b/b.go --
package b
-- gopath/pkg/mod/example.com/go.mod --
module example.com

go 1.12
-- gopath/pkg/mod/example.com/main.go --
package main
`
	WithOptions(
		EnvVars{"GOPATH": filepath.FromSlash("$SANDBOX_WORKDIR/gopath")},
		Modes(Default),
	).Run(t, mod, func(t *testing.T, env *Env) {
		env.Await(
			// Confirm that the build configuration is seen as valid,
			// even though there are technically multiple go.mod files in the
			// worskpace.
			LogMatching(protocol.Info, ".*valid build configuration = true.*", 1, false),
		)
	})
}

func TestAddAndRemoveGoWork(t *testing.T) {
	testenv.NeedsGo1Point(t, 18)
	// Use a workspace with a module in the root directory to exercise the case
	// where a go.work is added to the existing root directory. This verifies
	// that we're detecting changes to the module source, not just the root
	// directory.
	const nomod = `
-- go.mod --
module a.com

go 1.16
-- main.go --
package main

func main() {}
-- b/go.mod --
module b.com

go 1.16
-- b/main.go --
package main

func main() {}
`
	WithOptions(
		Modes(Default),
	).Run(t, nomod, func(t *testing.T, env *Env) {
		env.OpenFile("main.go")
		env.OpenFile("b/main.go")
		// Since b/main.go is not in the workspace, it should have a warning on its
		// package declaration.
		env.AfterChange(
			NoDiagnostics(ForFile("main.go")),
			Diagnostics(AtPosition("b/main.go", 0, 0)),
		)
		env.WriteWorkspaceFile("go.work", `go 1.16

use (
	.
	b
)
`)
		env.AfterChange(NoDiagnostics())
		// Removing the go.work file should put us back where we started.
		env.RemoveWorkspaceFile("go.work")

		// TODO(golang/go#57558, golang/go#57508): file watching is asynchronous,
		// and we must wait for the view to be reconstructed before touching
		// b/main.go, so that the new view "knows" about b/main.go. This is simply
		// a bug, but awaiting the change here avoids it.
		env.Await(env.DoneWithChangeWatchedFiles())

		// TODO(rfindley): fix this bug: reopening b/main.go is necessary here
		// because we no longer "see" the file in any view.
		env.CloseBuffer("b/main.go")
		env.OpenFile("b/main.go")

		env.AfterChange(
			NoDiagnostics(ForFile("main.go")),
			Diagnostics(AtPosition("b/main.go", 0, 0)),
		)
	})
}

// Tests the fix for golang/go#52500.
func TestChangeTestVariant_Issue52500(t *testing.T) {
	const src = `
-- go.mod --
module mod.test

go 1.12
-- main_test.go --
package main_test

type Server struct{}

const mainConst = otherConst
-- other_test.go --
package main_test

const otherConst = 0

func (Server) Foo() {}
`

	Run(t, src, func(t *testing.T, env *Env) {
		env.OpenFile("other_test.go")
		env.RegexpReplace("other_test.go", "main_test", "main")

		// For this test to function, it is necessary to wait on both of the
		// expectations below: the bug is that when switching the package name in
		// other_test.go from main->main_test, metadata for main_test is not marked
		// as invalid. So we need to wait for the metadata of main_test.go to be
		// updated before moving other_test.go back to the main_test package.
		env.Await(
			Diagnostics(env.AtRegexp("other_test.go", "Server")),
			Diagnostics(env.AtRegexp("main_test.go", "otherConst")),
		)
		env.RegexpReplace("other_test.go", "main", "main_test")
		env.AfterChange(
			NoDiagnostics(ForFile("other_test.go")),
			NoDiagnostics(ForFile("main_test.go")),
		)

		// This will cause a test failure if other_test.go is not in any package.
		_ = env.GoToDefinition(env.RegexpSearch("other_test.go", "Server"))
	})
}

// Test for golang/go#48929.
func TestClearNonWorkspaceDiagnostics(t *testing.T) {
	testenv.NeedsGo1Point(t, 18) // uses go.work

	const ws = `
-- go.work --
go 1.18

use (
        ./b
)
-- a/go.mod --
module a

go 1.17
-- a/main.go --
package main

func main() {
   var V string
}
-- b/go.mod --
module b

go 1.17
-- b/main.go --
package b

import (
        _ "fmt"
)
`
	Run(t, ws, func(t *testing.T, env *Env) {
		env.OpenFile("b/main.go")
		env.AfterChange(
			NoDiagnostics(ForFile("a/main.go")),
		)
		env.OpenFile("a/main.go")
		env.AfterChange(
			Diagnostics(env.AtRegexp("a/main.go", "V"), WithMessage("not used")),
		)
		env.CloseBuffer("a/main.go")

		// Make an arbitrary edit because gopls explicitly diagnoses a/main.go
		// whenever it is "changed".
		//
		// TODO(rfindley): it should not be necessary to make another edit here.
		// Gopls should be smart enough to avoid diagnosing a.
		env.RegexpReplace("b/main.go", "package b", "package b // a package")
		env.AfterChange(
			NoDiagnostics(ForFile("a/main.go")),
		)
	})
}

// Test that we don't get a version warning when the Go version in PATH is
// supported.
func TestOldGoNotification_SupportedVersion(t *testing.T) {
	v := goVersion(t)
	if v < lsp.OldestSupportedGoVersion() {
		t.Skipf("go version 1.%d is unsupported", v)
	}

	Run(t, "", func(t *testing.T, env *Env) {
		env.OnceMet(
			InitialWorkspaceLoad,
			NoShownMessage("upgrade"),
		)
	})
}

// Test that we do get a version warning when the Go version in PATH is
// unsupported, though this test may never execute if we stop running CI at
// legacy Go versions (see also TestOldGoNotification_Fake)
func TestOldGoNotification_UnsupportedVersion(t *testing.T) {
	v := goVersion(t)
	if v >= lsp.OldestSupportedGoVersion() {
		t.Skipf("go version 1.%d is supported", v)
	}

	Run(t, "", func(t *testing.T, env *Env) {
		env.Await(
			// Note: cannot use OnceMet(InitialWorkspaceLoad, ...) here, as the
			// upgrade message may race with the IWL.
			ShownMessage("Please upgrade"),
		)
	})
}

func TestOldGoNotification_Fake(t *testing.T) {
	// Get the Go version from path, and make sure it's unsupported.
	//
	// In the future we'll stop running CI on legacy Go versions. By mutating the
	// oldest supported Go version here, we can at least ensure that the
	// ShowMessage pop-up works.
	ctx := context.Background()
	goversion, err := gocommand.GoVersion(ctx, gocommand.Invocation{}, &gocommand.Runner{})
	if err != nil {
		t.Fatal(err)
	}
	defer func(t []lsp.GoVersionSupport) {
		lsp.GoVersionTable = t
	}(lsp.GoVersionTable)
	lsp.GoVersionTable = []lsp.GoVersionSupport{
		{GoVersion: goversion, InstallGoplsVersion: "v1.0.0"},
	}

	Run(t, "", func(t *testing.T, env *Env) {
		env.Await(
			// Note: cannot use OnceMet(InitialWorkspaceLoad, ...) here, as the
			// upgrade message may race with the IWL.
			ShownMessage("Please upgrade"),
		)
	})
}

// goVersion returns the version of the Go command in PATH.
func goVersion(t *testing.T) int {
	t.Helper()
	ctx := context.Background()
	goversion, err := gocommand.GoVersion(ctx, gocommand.Invocation{}, &gocommand.Runner{})
	if err != nil {
		t.Fatal(err)
	}
	return goversion
}
