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

import (
	"path/filepath"
	"runtime"
	"strings"
	"testing"

	"golang.org/x/tools/gopls/internal/hooks"
	. "golang.org/x/tools/gopls/internal/lsp/regtest"
	"golang.org/x/tools/gopls/internal/lsp/tests/compare"
	"golang.org/x/tools/internal/bug"

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

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

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")
}
`

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

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

const Name = "Blah"
-- random.org@v1.2.3/go.mod --
module random.org

go 1.12
-- random.org@v1.2.3/blah/blah.go --
package hello

const Name = "Hello"
`

func TestModFileModification(t *testing.T) {
	const untidyModule = `
-- a/go.mod --
module mod.com

-- a/main.go --
package main

import "example.com/blah"

func main() {
	println(blah.Name)
}
`

	runner := RunMultiple{
		{"default", WithOptions(ProxyFiles(proxy), WorkspaceFolders("a"))},
		{"nested", WithOptions(ProxyFiles(proxy))},
	}

	t.Run("basic", func(t *testing.T) {
		runner.Run(t, untidyModule, func(t *testing.T, env *Env) {
			// Open the file and make sure that the initial workspace load does not
			// modify the go.mod file.
			goModContent := env.ReadWorkspaceFile("a/go.mod")
			env.OpenFile("a/main.go")
			env.Await(
				OnceMet(
					env.DoneWithOpen(),
					env.DiagnosticAtRegexp("a/main.go", "\"example.com/blah\""),
				),
			)
			if got := env.ReadWorkspaceFile("a/go.mod"); got != goModContent {
				t.Fatalf("go.mod changed on disk:\n%s", compare.Text(goModContent, got))
			}
			// Save the buffer, which will format and organize imports.
			// Confirm that the go.mod file still does not change.
			env.SaveBuffer("a/main.go")
			env.Await(
				env.DiagnosticAtRegexp("a/main.go", "\"example.com/blah\""),
			)
			if got := env.ReadWorkspaceFile("a/go.mod"); got != goModContent {
				t.Fatalf("go.mod changed on disk:\n%s", compare.Text(goModContent, got))
			}
		})
	})

	// Reproduce golang/go#40269 by deleting and recreating main.go.
	t.Run("delete main.go", func(t *testing.T) {
		runner.Run(t, untidyModule, func(t *testing.T, env *Env) {
			goModContent := env.ReadWorkspaceFile("a/go.mod")
			mainContent := env.ReadWorkspaceFile("a/main.go")
			env.OpenFile("a/main.go")
			env.SaveBuffer("a/main.go")

			// Ensure that we're done processing all the changes caused by opening
			// and saving above. If not, we may run into a file locking issue on
			// windows.
			//
			// If this proves insufficient, env.RemoveWorkspaceFile can be updated to
			// retry file lock errors on windows.
			env.Await(
				env.DoneWithOpen(),
				env.DoneWithSave(),
				env.DoneWithChangeWatchedFiles(),
			)
			env.RemoveWorkspaceFile("a/main.go")

			// TODO(rfindley): awaiting here shouldn't really be necessary. We should
			// be consistent eventually.
			//
			// Probably this was meant to exercise a race with the change below.
			env.Await(
				env.DoneWithOpen(),
				env.DoneWithSave(),
				env.DoneWithChangeWatchedFiles(),
			)

			env.WriteWorkspaceFile("a/main.go", mainContent)
			env.Await(
				OnceMet(
					env.DoneWithChangeWatchedFiles(),
					env.DiagnosticAtRegexp("a/main.go", "\"example.com/blah\""),
				),
			)
			if got := env.ReadWorkspaceFile("a/go.mod"); got != goModContent {
				t.Fatalf("go.mod changed on disk:\n%s", compare.Text(goModContent, got))
			}
		})
	})
}

func TestGoGetFix(t *testing.T) {
	const mod = `
-- a/go.mod --
module mod.com

go 1.12

-- a/main.go --
package main

import "example.com/blah"

var _ = blah.Name
`

	const want = `module mod.com

go 1.12

require example.com v1.2.3
`

	RunMultiple{
		{"default", WithOptions(ProxyFiles(proxy), WorkspaceFolders("a"))},
		{"nested", WithOptions(ProxyFiles(proxy))},
	}.Run(t, mod, func(t *testing.T, env *Env) {
		if strings.Contains(t.Name(), "workspace_module") {
			t.Skip("workspace module mode doesn't set -mod=readonly")
		}
		env.OpenFile("a/main.go")
		var d protocol.PublishDiagnosticsParams
		env.Await(
			OnceMet(
				env.DiagnosticAtRegexp("a/main.go", `"example.com/blah"`),
				ReadDiagnostics("a/main.go", &d),
			),
		)
		var goGetDiag protocol.Diagnostic
		for _, diag := range d.Diagnostics {
			if strings.Contains(diag.Message, "could not import") {
				goGetDiag = diag
			}
		}
		env.ApplyQuickFixes("a/main.go", []protocol.Diagnostic{goGetDiag})
		if got := env.ReadWorkspaceFile("a/go.mod"); got != want {
			t.Fatalf("unexpected go.mod content:\n%s", compare.Text(want, got))
		}
	})
}

// Tests that multiple missing dependencies gives good single fixes.
func TestMissingDependencyFixes(t *testing.T) {
	const mod = `
-- a/go.mod --
module mod.com

go 1.12

-- a/main.go --
package main

import "example.com/blah"
import "random.org/blah"

var _, _ = blah.Name, hello.Name
`

	const want = `module mod.com

go 1.12

require random.org v1.2.3
`

	RunMultiple{
		{"default", WithOptions(ProxyFiles(proxy), WorkspaceFolders("a"))},
		{"nested", WithOptions(ProxyFiles(proxy))},
	}.Run(t, mod, func(t *testing.T, env *Env) {
		env.OpenFile("a/main.go")
		var d protocol.PublishDiagnosticsParams
		env.Await(
			OnceMet(
				env.DiagnosticAtRegexp("a/main.go", `"random.org/blah"`),
				ReadDiagnostics("a/main.go", &d),
			),
		)
		var randomDiag protocol.Diagnostic
		for _, diag := range d.Diagnostics {
			if strings.Contains(diag.Message, "random.org") {
				randomDiag = diag
			}
		}
		env.ApplyQuickFixes("a/main.go", []protocol.Diagnostic{randomDiag})
		if got := env.ReadWorkspaceFile("a/go.mod"); got != want {
			t.Fatalf("unexpected go.mod content:\n%s", compare.Text(want, got))
		}
	})
}

// Tests that multiple missing dependencies gives good single fixes.
func TestMissingDependencyFixesWithGoWork(t *testing.T) {
	testenv.NeedsGo1Point(t, 18)
	const mod = `
-- go.work --
go 1.18

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

go 1.12

-- a/main.go --
package main

import "example.com/blah"
import "random.org/blah"

var _, _ = blah.Name, hello.Name
`

	const want = `module mod.com

go 1.12

require random.org v1.2.3
`

	RunMultiple{
		{"default", WithOptions(ProxyFiles(proxy), WorkspaceFolders("a"))},
		{"nested", WithOptions(ProxyFiles(proxy))},
	}.Run(t, mod, func(t *testing.T, env *Env) {
		env.OpenFile("a/main.go")
		var d protocol.PublishDiagnosticsParams
		env.Await(
			OnceMet(
				env.DiagnosticAtRegexp("a/main.go", `"random.org/blah"`),
				ReadDiagnostics("a/main.go", &d),
			),
		)
		var randomDiag protocol.Diagnostic
		for _, diag := range d.Diagnostics {
			if strings.Contains(diag.Message, "random.org") {
				randomDiag = diag
			}
		}
		env.ApplyQuickFixes("a/main.go", []protocol.Diagnostic{randomDiag})
		if got := env.ReadWorkspaceFile("a/go.mod"); got != want {
			t.Fatalf("unexpected go.mod content:\n%s", compare.Text(want, got))
		}
	})
}

func TestIndirectDependencyFix(t *testing.T) {
	const mod = `
-- a/go.mod --
module mod.com

go 1.12

require example.com v1.2.3 // indirect
-- a/go.sum --
example.com v1.2.3 h1:ihBTGWGjTU3V4ZJ9OmHITkU9WQ4lGdQkMjgyLFk0FaY=
example.com v1.2.3/go.mod h1:Y2Rc5rVWjWur0h3pd9aEvK5Pof8YKDANh9gHA2Maujo=
-- a/main.go --
package main

import "example.com/blah"

func main() {
	fmt.Println(blah.Name)
`
	const want = `module mod.com

go 1.12

require example.com v1.2.3
`

	RunMultiple{
		{"default", WithOptions(ProxyFiles(proxy), WorkspaceFolders("a"))},
		{"nested", WithOptions(ProxyFiles(proxy))},
	}.Run(t, mod, func(t *testing.T, env *Env) {
		env.OpenFile("a/go.mod")
		var d protocol.PublishDiagnosticsParams
		env.Await(
			OnceMet(
				env.DiagnosticAtRegexp("a/go.mod", "// indirect"),
				ReadDiagnostics("a/go.mod", &d),
			),
		)
		env.ApplyQuickFixes("a/go.mod", d.Diagnostics)
		if got := env.BufferText("a/go.mod"); got != want {
			t.Fatalf("unexpected go.mod content:\n%s", compare.Text(want, got))
		}
	})
}

func TestUnusedDiag(t *testing.T) {

	const proxy = `
-- example.com@v1.0.0/x.go --
package pkg
const X = 1
`
	const files = `
-- a/go.mod --
module mod.com
go 1.14
require example.com v1.0.0
-- a/go.sum --
example.com v1.0.0 h1:38O7j5rEBajXk+Q5wzLbRN7KqMkSgEiN9NqcM1O2bBM=
example.com v1.0.0/go.mod h1:vUsPMGpx9ZXXzECCOsOmYCW7npJTwuA16yl89n3Mgls=
-- a/main.go --
package main
func main() {}
`

	const want = `module mod.com

go 1.14
`

	RunMultiple{
		{"default", WithOptions(ProxyFiles(proxy), WorkspaceFolders("a"))},
		{"nested", WithOptions(ProxyFiles(proxy))},
	}.Run(t, files, func(t *testing.T, env *Env) {
		env.OpenFile("a/go.mod")
		var d protocol.PublishDiagnosticsParams
		env.Await(
			OnceMet(
				env.DiagnosticAtRegexp("a/go.mod", `require example.com`),
				ReadDiagnostics("a/go.mod", &d),
			),
		)
		env.ApplyQuickFixes("a/go.mod", d.Diagnostics)
		if got := env.BufferText("a/go.mod"); got != want {
			t.Fatalf("unexpected go.mod content:\n%s", compare.Text(want, got))
		}
	})
}

// Test to reproduce golang/go#39041. It adds a new require to a go.mod file
// that already has an unused require.
func TestNewDepWithUnusedDep(t *testing.T) {

	const proxy = `
-- github.com/esimov/caire@v1.2.5/go.mod --
module github.com/esimov/caire

go 1.12
-- github.com/esimov/caire@v1.2.5/caire.go --
package caire

func RemoveTempImage() {}
-- google.golang.org/protobuf@v1.20.0/go.mod --
module google.golang.org/protobuf

go 1.12
-- google.golang.org/protobuf@v1.20.0/hello/hello.go --
package hello
`
	const repro = `
-- a/go.mod --
module mod.com

go 1.14

require google.golang.org/protobuf v1.20.0
-- a/go.sum --
github.com/esimov/caire v1.2.5 h1:OcqDII/BYxcBYj3DuwDKjd+ANhRxRqLa2n69EGje7qw=
github.com/esimov/caire v1.2.5/go.mod h1:mXnjRjg3+WUtuhfSC1rKRmdZU9vJZyS1ZWU0qSvJhK8=
google.golang.org/protobuf v1.20.0 h1:y9T1vAtFKQg0faFNMOxJU7WuEqPWolVkjIkU6aI8qCY=
google.golang.org/protobuf v1.20.0/go.mod h1:FcqsytGClbtLv1ot8NvsJHjBi0h22StKVP+K/j2liKA=
-- a/main.go --
package main

import (
    "github.com/esimov/caire"
)

func _() {
    caire.RemoveTempImage()
}`

	RunMultiple{
		{"default", WithOptions(ProxyFiles(proxy), WorkspaceFolders("a"))},
		{"nested", WithOptions(ProxyFiles(proxy))},
	}.Run(t, repro, func(t *testing.T, env *Env) {
		env.OpenFile("a/main.go")
		var d protocol.PublishDiagnosticsParams
		env.Await(
			OnceMet(
				env.DiagnosticAtRegexp("a/main.go", `"github.com/esimov/caire"`),
				ReadDiagnostics("a/main.go", &d),
			),
		)
		env.ApplyQuickFixes("a/main.go", d.Diagnostics)
		want := `module mod.com

go 1.14

require (
	github.com/esimov/caire v1.2.5
	google.golang.org/protobuf v1.20.0
)
`
		if got := env.ReadWorkspaceFile("a/go.mod"); got != want {
			t.Fatalf("TestNewDepWithUnusedDep failed:\n%s", compare.Text(want, got))
		}
	})
}

// TODO: For this test to be effective, the sandbox's file watcher must respect
// the file watching GlobPattern in the capability registration. See
// golang/go#39384.
func TestModuleChangesOnDisk(t *testing.T) {
	const mod = `
-- a/go.mod --
module mod.com

go 1.12

require example.com v1.2.3
-- a/go.sum --
example.com v1.2.3 h1:ihBTGWGjTU3V4ZJ9OmHITkU9WQ4lGdQkMjgyLFk0FaY=
example.com v1.2.3/go.mod h1:Y2Rc5rVWjWur0h3pd9aEvK5Pof8YKDANh9gHA2Maujo=
-- a/main.go --
package main

func main() {
	fmt.Println(blah.Name)
`
	RunMultiple{
		{"default", WithOptions(ProxyFiles(proxy), WorkspaceFolders("a"))},
		{"nested", WithOptions(ProxyFiles(proxy))},
	}.Run(t, mod, func(t *testing.T, env *Env) {
		env.Await(env.DiagnosticAtRegexp("a/go.mod", "require"))
		env.RunGoCommandInDir("a", "mod", "tidy")
		env.Await(
			EmptyDiagnostics("a/go.mod"),
		)
	})
}

// Tests golang/go#39784: a missing indirect dependency, necessary
// due to blah@v2.0.0's incomplete go.mod file.
func TestBadlyVersionedModule(t *testing.T) {
	const proxy = `
-- example.com/blah/@v/v1.0.0.mod --
module example.com

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

const Name = "Blah"
-- example.com/blah/v2/@v/v2.0.0.mod --
module example.com

go 1.12
-- example.com/blah/v2@v2.0.0/blah.go --
package blah

import "example.com/blah"

var V1Name = blah.Name
const Name = "Blah"
`
	const files = `
-- a/go.mod --
module mod.com

go 1.12

require example.com/blah/v2 v2.0.0
-- a/go.sum --
example.com/blah v1.0.0 h1:kGPlWJbMsn1P31H9xp/q2mYI32cxLnCvauHN0AVaHnc=
example.com/blah v1.0.0/go.mod h1:PZUQaGFeVjyDmAE8ywmLbmDn3fj4Ws8epg4oLuDzW3M=
example.com/blah/v2 v2.0.0 h1:DNPsFPkKtTdxclRheaMCiYAoYizp6PuBzO0OmLOO0pY=
example.com/blah/v2 v2.0.0/go.mod h1:UZiKbTwobERo/hrqFLvIQlJwQZQGxWMVY4xere8mj7w=
-- a/main.go --
package main

import "example.com/blah/v2"

var _ = blah.Name
`
	RunMultiple{
		{"default", WithOptions(ProxyFiles(proxy), WorkspaceFolders("a"))},
		{"nested", WithOptions(ProxyFiles(proxy))},
	}.Run(t, files, func(t *testing.T, env *Env) {
		env.OpenFile("a/main.go")
		env.OpenFile("a/go.mod")
		var modDiags protocol.PublishDiagnosticsParams
		env.AfterChange(
			// We would like for the error to appear in the v2 module, but
			// as of writing non-workspace packages are not diagnosed.
			env.DiagnosticAtRegexpWithMessage("a/main.go", `"example.com/blah/v2"`, "cannot find module providing"),
			env.DiagnosticAtRegexpWithMessage("a/go.mod", `require example.com/blah/v2`, "cannot find module providing"),
			ReadDiagnostics("a/go.mod", &modDiags),
		)
		env.ApplyQuickFixes("a/go.mod", modDiags.Diagnostics)
		const want = `module mod.com

go 1.12

require (
	example.com/blah v1.0.0 // indirect
	example.com/blah/v2 v2.0.0
)
`
		env.SaveBuffer("a/go.mod")
		env.AfterChange(EmptyDiagnostics("a/main.go"))
		if got := env.BufferText("a/go.mod"); got != want {
			t.Fatalf("suggested fixes failed:\n%s", compare.Text(want, got))
		}
	})
}

// Reproduces golang/go#38232.
func TestUnknownRevision(t *testing.T) {
	if runtime.GOOS == "plan9" {
		t.Skipf("skipping test that fails for unknown reasons on plan9; see https://go.dev/issue/50477")
	}
	const unknown = `
-- a/go.mod --
module mod.com

require (
	example.com v1.2.2
)
-- a/main.go --
package main

import "example.com/blah"

func main() {
	var x = blah.Name
}
`

	runner := RunMultiple{
		{"default", WithOptions(ProxyFiles(proxy), WorkspaceFolders("a"))},
		{"nested", WithOptions(ProxyFiles(proxy))},
	}
	// Start from a bad state/bad IWL, and confirm that we recover.
	t.Run("bad", func(t *testing.T) {
		runner.Run(t, unknown, func(t *testing.T, env *Env) {
			env.OpenFile("a/go.mod")
			env.Await(
				env.DiagnosticAtRegexp("a/go.mod", "example.com v1.2.2"),
			)
			env.RegexpReplace("a/go.mod", "v1.2.2", "v1.2.3")
			env.SaveBuffer("a/go.mod") // Save to trigger diagnostics.

			d := protocol.PublishDiagnosticsParams{}
			env.AfterChange(
				// Make sure the diagnostic mentions the new version -- the old diagnostic is in the same place.
				env.DiagnosticAtRegexpWithMessage("a/go.mod", "example.com v1.2.3", "example.com@v1.2.3"),
				ReadDiagnostics("a/go.mod", &d),
			)
			qfs := env.GetQuickFixes("a/go.mod", d.Diagnostics)
			if len(qfs) == 0 {
				t.Fatalf("got 0 code actions to fix %v, wanted at least 1", d.Diagnostics)
			}
			env.ApplyCodeAction(qfs[0]) // Arbitrarily pick a single fix to apply. Applying all of them seems to cause trouble in this particular test.
			env.SaveBuffer("a/go.mod")  // Save to trigger diagnostics.
			env.AfterChange(
				EmptyDiagnostics("a/go.mod"),
				env.DiagnosticAtRegexp("a/main.go", "x = "),
			)
		})
	})

	const known = `
-- a/go.mod --
module mod.com

require (
	example.com v1.2.3
)
-- a/go.sum --
example.com v1.2.3 h1:ihBTGWGjTU3V4ZJ9OmHITkU9WQ4lGdQkMjgyLFk0FaY=
example.com v1.2.3/go.mod h1:Y2Rc5rVWjWur0h3pd9aEvK5Pof8YKDANh9gHA2Maujo=
-- a/main.go --
package main

import "example.com/blah"

func main() {
	var x = blah.Name
}
`
	// Start from a good state, transform to a bad state, and confirm that we
	// still recover.
	t.Run("good", func(t *testing.T) {
		runner.Run(t, known, func(t *testing.T, env *Env) {
			env.OpenFile("a/go.mod")
			env.AfterChange(
				env.DiagnosticAtRegexp("a/main.go", "x = "),
			)
			env.RegexpReplace("a/go.mod", "v1.2.3", "v1.2.2")
			env.Editor.SaveBuffer(env.Ctx, "a/go.mod") // go.mod changes must be on disk
			env.AfterChange(
				env.DiagnosticAtRegexp("a/go.mod", "example.com v1.2.2"),
			)
			env.RegexpReplace("a/go.mod", "v1.2.2", "v1.2.3")
			env.Editor.SaveBuffer(env.Ctx, "a/go.mod") // go.mod changes must be on disk
			env.AfterChange(
				env.DiagnosticAtRegexp("a/main.go", "x = "),
			)
		})
	})
}

// Confirm that an error in an indirect dependency of a requirement is surfaced
// as a diagnostic in the go.mod file.
func TestErrorInIndirectDependency(t *testing.T) {
	const badProxy = `
-- example.com@v1.2.3/go.mod --
module example.com

go 1.12

require random.org v1.2.3 // indirect
-- example.com@v1.2.3/blah/blah.go --
package blah

const Name = "Blah"
-- random.org@v1.2.3/go.mod --
module bob.org

go 1.12
-- random.org@v1.2.3/blah/blah.go --
package hello

const Name = "Hello"
`
	const module = `
-- a/go.mod --
module mod.com

go 1.14

require example.com v1.2.3
-- a/main.go --
package main

import "example.com/blah"

func main() {
	println(blah.Name)
}
`
	RunMultiple{
		{"default", WithOptions(ProxyFiles(badProxy), WorkspaceFolders("a"))},
		{"nested", WithOptions(ProxyFiles(badProxy))},
	}.Run(t, module, func(t *testing.T, env *Env) {
		env.OpenFile("a/go.mod")
		env.Await(
			env.DiagnosticAtRegexp("a/go.mod", "require example.com v1.2.3"),
		)
	})
}

// A copy of govim's config_set_env_goflags_mod_readonly test.
func TestGovimModReadonly(t *testing.T) {
	const mod = `
-- go.mod --
module mod.com

go 1.13
-- main.go --
package main

import "example.com/blah"

func main() {
	println(blah.Name)
}
`
	WithOptions(
		EnvVars{"GOFLAGS": "-mod=readonly"},
		ProxyFiles(proxy),
		Modes(Default),
	).Run(t, mod, func(t *testing.T, env *Env) {
		env.OpenFile("main.go")
		original := env.ReadWorkspaceFile("go.mod")
		env.Await(
			env.DiagnosticAtRegexp("main.go", `"example.com/blah"`),
		)
		got := env.ReadWorkspaceFile("go.mod")
		if got != original {
			t.Fatalf("go.mod file modified:\n%s", compare.Text(original, got))
		}
		env.RunGoCommand("get", "example.com/blah@v1.2.3")
		env.RunGoCommand("mod", "tidy")
		env.Await(
			EmptyDiagnostics("main.go"),
		)
	})
}

func TestMultiModuleModDiagnostics(t *testing.T) {
	testenv.NeedsGo1Point(t, 18) // uses go.work
	const mod = `
-- go.work --
go 1.18

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

go 1.14

require (
	example.com v1.2.3
)
-- a/go.sum --
example.com v1.2.3 h1:Yryq11hF02fEf2JlOS2eph+ICE2/ceevGV3C9dl5V/c=
example.com v1.2.3/go.mod h1:Y2Rc5rVWjWur0h3pd9aEvK5Pof8YKDANh9gHA2Maujo=
-- a/main.go --
package main

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

require example.com v1.2.3

go 1.14
-- b/main.go --
package main

import "example.com/blah"

func main() {
	blah.SaySomething()
}
`
	WithOptions(
		ProxyFiles(workspaceProxy),
	).Run(t, mod, func(t *testing.T, env *Env) {
		env.Await(
			env.DiagnosticAtRegexpWithMessage("a/go.mod", "example.com v1.2.3", "is not used"),
		)
	})
}

func TestModTidyWithBuildTags(t *testing.T) {
	const mod = `
-- go.mod --
module mod.com

go 1.14
-- main.go --
// +build bob

package main

import "example.com/blah"

func main() {
	blah.SaySomething()
}
`
	WithOptions(
		ProxyFiles(workspaceProxy),
		Settings{"buildFlags": []string{"-tags", "bob"}},
	).Run(t, mod, func(t *testing.T, env *Env) {
		env.Await(
			env.DiagnosticAtRegexp("main.go", `"example.com/blah"`),
		)
	})
}

func TestModTypoDiagnostic(t *testing.T) {
	const mod = `
-- go.mod --
module mod.com

go 1.12
-- main.go --
package main

func main() {}
`
	Run(t, mod, func(t *testing.T, env *Env) {
		env.OpenFile("go.mod")
		env.RegexpReplace("go.mod", "module", "modul")
		env.Await(
			env.DiagnosticAtRegexp("go.mod", "modul"),
		)
	})
}

func TestSumUpdateFixesDiagnostics(t *testing.T) {
	const mod = `
-- go.mod --
module mod.com

go 1.12

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

import (
	"example.com/blah"
)

func main() {
	println(blah.Name)
}
`
	WithOptions(
		ProxyFiles(workspaceProxy),
	).Run(t, mod, func(t *testing.T, env *Env) {
		d := &protocol.PublishDiagnosticsParams{}
		env.OpenFile("go.mod")
		env.Await(
			OnceMet(
				env.GoSumDiagnostic("go.mod", `example.com v1.2.3`),
				ReadDiagnostics("go.mod", d),
			),
		)
		env.ApplyQuickFixes("go.mod", d.Diagnostics)
		env.SaveBuffer("go.mod") // Save to trigger diagnostics.
		env.Await(
			EmptyDiagnostics("go.mod"),
		)
	})
}

// This test confirms that editing a go.mod file only causes metadata
// to be invalidated when it's saved.
func TestGoModInvalidatesOnSave(t *testing.T) {
	const mod = `
-- go.mod --
module mod.com

go 1.12
-- main.go --
package main

func main() {
	hello()
}
-- hello.go --
package main

func hello() {}
`
	WithOptions(
		// TODO(rFindley) this doesn't work in multi-module workspace mode, because
		// it keeps around the last parsing modfile. Update this test to also
		// exercise the workspace module.
		Modes(Default),
	).Run(t, mod, func(t *testing.T, env *Env) {
		env.OpenFile("go.mod")
		env.Await(env.DoneWithOpen())
		env.RegexpReplace("go.mod", "module", "modul")
		// Confirm that we still have metadata with only on-disk edits.
		env.OpenFile("main.go")
		file, _ := env.GoToDefinition("main.go", env.RegexpSearch("main.go", "hello"))
		if filepath.Base(file) != "hello.go" {
			t.Fatalf("expected definition in hello.go, got %s", file)
		}
		// Confirm that we no longer have metadata when the file is saved.
		env.SaveBufferWithoutActions("go.mod")
		_, _, err := env.Editor.GoToDefinition(env.Ctx, "main.go", env.RegexpSearch("main.go", "hello"))
		if err == nil {
			t.Fatalf("expected error, got none")
		}
	})
}

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

go 1.12

require example.com v1.2.3
-- hasdep.com@v1.2.3/a/a.go --
package a
-- example.com@v1.2.3/go.mod --
module example.com

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

const Name = "Blah"
-- random.com@v1.2.3/go.mod --
module random.com

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

const Name = "Blah"
`
	t.Run("almost tidied", func(t *testing.T) {
		const mod = `
-- go.mod --
module mod.com

go 1.12

require hasdep.com v1.2.3
-- go.sum --
example.com v1.2.3 h1:ihBTGWGjTU3V4ZJ9OmHITkU9WQ4lGdQkMjgyLFk0FaY=
example.com v1.2.3/go.mod h1:Y2Rc5rVWjWur0h3pd9aEvK5Pof8YKDANh9gHA2Maujo=
hasdep.com v1.2.3 h1:00y+N5oD+SpKoqV1zP2VOPawcW65Zb9NebANY3GSzGI=
hasdep.com v1.2.3/go.mod h1:ePVZOlez+KZEOejfLPGL2n4i8qiAjrkhQZ4wcImqAes=
-- main.go --
package main

func main() {}
`
		WithOptions(
			ProxyFiles(proxy),
		).Run(t, mod, func(t *testing.T, env *Env) {
			env.OpenFile("go.mod")
			d := &protocol.PublishDiagnosticsParams{}
			env.Await(
				OnceMet(
					env.DiagnosticAtRegexp("go.mod", "require hasdep.com v1.2.3"),
					ReadDiagnostics("go.mod", d),
				),
			)
			const want = `module mod.com

go 1.12
`
			env.ApplyQuickFixes("go.mod", d.Diagnostics)
			if got := env.BufferText("go.mod"); got != want {
				t.Fatalf("unexpected content in go.mod:\n%s", compare.Text(want, got))
			}
		})
	})

	t.Run("not tidied", func(t *testing.T) {
		const mod = `
-- go.mod --
module mod.com

go 1.12

require hasdep.com v1.2.3
require random.com v1.2.3
-- go.sum --
example.com v1.2.3 h1:ihBTGWGjTU3V4ZJ9OmHITkU9WQ4lGdQkMjgyLFk0FaY=
example.com v1.2.3/go.mod h1:Y2Rc5rVWjWur0h3pd9aEvK5Pof8YKDANh9gHA2Maujo=
hasdep.com v1.2.3 h1:00y+N5oD+SpKoqV1zP2VOPawcW65Zb9NebANY3GSzGI=
hasdep.com v1.2.3/go.mod h1:ePVZOlez+KZEOejfLPGL2n4i8qiAjrkhQZ4wcImqAes=
random.com v1.2.3 h1:PzYTykzqqH6+qU0dIgh9iPFbfb4Mm8zNBjWWreRKtx0=
random.com v1.2.3/go.mod h1:8EGj+8a4Hw1clAp8vbaeHAsKE4sbm536FP7nKyXO+qQ=
-- main.go --
package main

func main() {}
`
		WithOptions(
			ProxyFiles(proxy),
		).Run(t, mod, func(t *testing.T, env *Env) {
			d := &protocol.PublishDiagnosticsParams{}
			env.OpenFile("go.mod")
			pos := env.RegexpSearch("go.mod", "require hasdep.com v1.2.3")
			env.Await(
				OnceMet(
					DiagnosticAt("go.mod", pos.Line, pos.Column),
					ReadDiagnostics("go.mod", d),
				),
			)
			const want = `module mod.com

go 1.12

require random.com v1.2.3
`
			var diagnostics []protocol.Diagnostic
			for _, d := range d.Diagnostics {
				if d.Range.Start.Line != uint32(pos.Line) {
					continue
				}
				diagnostics = append(diagnostics, d)
			}
			env.ApplyQuickFixes("go.mod", diagnostics)
			if got := env.BufferText("go.mod"); got != want {
				t.Fatalf("unexpected content in go.mod:\n%s", compare.Text(want, got))
			}
		})
	})
}

func TestSumUpdateQuickFix(t *testing.T) {
	const mod = `
-- go.mod --
module mod.com

go 1.12

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

import (
	"example.com/blah"
)

func main() {
	blah.Hello()
}
`
	WithOptions(
		ProxyFiles(workspaceProxy),
		Modes(Default),
	).Run(t, mod, func(t *testing.T, env *Env) {
		env.OpenFile("go.mod")
		params := &protocol.PublishDiagnosticsParams{}
		env.Await(
			OnceMet(
				env.GoSumDiagnostic("go.mod", "example.com"),
				ReadDiagnostics("go.mod", params),
			),
		)
		env.ApplyQuickFixes("go.mod", params.Diagnostics)
		const want = `example.com v1.2.3 h1:Yryq11hF02fEf2JlOS2eph+ICE2/ceevGV3C9dl5V/c=
example.com v1.2.3/go.mod h1:Y2Rc5rVWjWur0h3pd9aEvK5Pof8YKDANh9gHA2Maujo=
`
		if got := env.ReadWorkspaceFile("go.sum"); got != want {
			t.Fatalf("unexpected go.sum contents:\n%s", compare.Text(want, got))
		}
	})
}

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

go 1.12

require random.org v1.2.3
-- example.com@v1.2.3/blah/blah.go --
package blah

import "random.org/bye"

func SaySomething() {
	bye.Goodbye()
}
-- 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")
}
`

	const mod = `
-- go.mod --
module mod.com

go 1.12
-- go.sum --
-- main.go --
package main

import (
	"example.com/blah"
)

func main() {
	blah.SaySomething()
}
`
	WithOptions(
		ProxyFiles(proxy),
		Modes(Default),
	).Run(t, mod, func(t *testing.T, env *Env) {
		env.OpenFile("main.go")
		d := &protocol.PublishDiagnosticsParams{}
		env.Await(
			env.DiagnosticAtRegexpWithMessage("main.go", `"example.com/blah"`, `could not import example.com/blah (no required module provides package "example.com/blah")`),
			ReadDiagnostics("main.go", d),
		)
		env.ApplyQuickFixes("main.go", d.Diagnostics)
		env.Await(
			NoDiagnostics("main.go"),
			NoDiagnostics("go.mod"),
		)
	})
}

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

go foo
-- main.go --
package main
`
	Run(t, files, func(t *testing.T, env *Env) {
		env.Await(env.DiagnosticAtRegexpWithMessage("go.mod", `go foo`, "invalid go version"))
		env.WriteWorkspaceFile("go.mod", "module mod.com \n\ngo 1.12\n")
		env.Await(EmptyDiagnostics("go.mod"))
	})
}

// This is a regression test for a bug in the line-oriented implementation
// of the "apply diffs" operation used by the fake editor.
func TestIssue57627(t *testing.T) {
	const files = `
-- go.work --
package main
`
	Run(t, files, func(t *testing.T, env *Env) {
		env.OpenFile("go.work")
		env.SetBufferContent("go.work", "go 1.18\nuse moda/a")
		env.SaveBuffer("go.work") // doesn't fail
	})
}
