// Copyright 2020 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package regtest

import (
	"testing"

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

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

go 1.14
-- a/a.go --
package a

func _() {
	var x int
}
`
	// Edit the file when it's *not open* in the workspace, and check that
	// diagnostics are updated.
	t.Run("unopened", func(t *testing.T) {
		runner.Run(t, pkg, func(t *testing.T, env *Env) {
			env.Await(
				env.DiagnosticAtRegexp("a/a.go", "x"),
			)
			env.WriteWorkspaceFile("a/a.go", `package a; func _() {};`)
			env.Await(
				EmptyDiagnostics("a/a.go"),
			)
		})
	})

	// Edit the file when it *is open* in the workspace, and check that
	// diagnostics are *not* updated.
	t.Run("opened", func(t *testing.T) {
		runner.Run(t, pkg, func(t *testing.T, env *Env) {
			env.OpenFile("a/a.go")
			env.Await(CompletedWork(lsp.DiagnosticWorkTitle(lsp.FromDidOpen), 1))
			env.WriteWorkspaceFile("a/a.go", `package a; func _() {};`)
			env.Await(
				env.DiagnosticAtRegexp("a/a.go", "x"),
			)
		})
	})
}

// Edit a dependency on disk and expect a new diagnostic.
func TestEditDependency(t *testing.T) {
	const pkg = `
-- go.mod --
module mod.com

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

func B() int { return 0 }
-- a/a.go --
package a

import (
	"mod.com/b"
)

func _() {
	_ = b.B()
}
`
	runner.Run(t, pkg, func(t *testing.T, env *Env) {
		env.OpenFile("a/a.go")
		env.Await(CompletedWork(lsp.DiagnosticWorkTitle(lsp.FromDidOpen), 1))
		env.WriteWorkspaceFile("b/b.go", `package b; func B() {};`)
		env.Await(
			env.DiagnosticAtRegexp("a/a.go", "b.B"),
		)
	})
}

// Edit both the current file and one of its dependencies on disk and
// expect diagnostic changes.
func TestEditFileAndDependency(t *testing.T) {
	const pkg = `
-- go.mod --
module mod.com

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

func B() int { return 0 }
-- a/a.go --
package a

import (
	"mod.com/b"
)

func _() {
	var x int
	_ = b.B()
}
`
	runner.Run(t, pkg, func(t *testing.T, env *Env) {
		env.Await(
			env.DiagnosticAtRegexp("a/a.go", "x"),
		)
		env.WriteWorkspaceFiles(map[string]string{
			"b/b.go": `package b; func B() {};`,
			"a/a.go": `package a

import "mod.com/b"

func _() {
	b.B()
}`,
		})
		env.Await(
			EmptyDiagnostics("a/a.go"),
			NoDiagnostics("b/b.go"),
		)
	})
}

// Delete a dependency and expect a new diagnostic.
func TestDeleteDependency(t *testing.T) {
	const pkg = `
-- go.mod --
module mod.com

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

func B() int { return 0 }
-- a/a.go --
package a

import (
	"mod.com/b"
)

func _() {
	_ = b.B()
}
`
	runner.Run(t, pkg, func(t *testing.T, env *Env) {
		env.OpenFile("a/a.go")
		env.Await(CompletedWork(lsp.DiagnosticWorkTitle(lsp.FromDidOpen), 1))
		env.RemoveWorkspaceFile("b/b.go")
		env.Await(
			env.DiagnosticAtRegexp("a/a.go", "\"mod.com/b\""),
		)
	})
}

// Create a dependency on disk and expect the diagnostic to go away.
func TestCreateDependency(t *testing.T) {
	const missing = `
-- go.mod --
module mod.com

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

func B() int { return 0 }
-- a/a.go --
package a

import (
	"mod.com/c"
)

func _() {
	c.C()
}
`
	runner.Run(t, missing, func(t *testing.T, env *Env) {
		t.Skipf("the initial workspace load fails and never retries")

		env.Await(
			env.DiagnosticAtRegexp("a/a.go", "\"mod.com/c\""),
		)
		env.WriteWorkspaceFile("c/c.go", `package c; func C() {};`)
		env.Await(
			EmptyDiagnostics("c/c.go"),
		)
	})
}

// Create a new dependency and add it to the file on disk.
// This is similar to what might happen if you switch branches.
func TestCreateAndAddDependency(t *testing.T) {
	const original = `
-- go.mod --
module mod.com

go 1.14
-- a/a.go --
package a

func _() {}
`
	runner.Run(t, original, func(t *testing.T, env *Env) {
		env.WriteWorkspaceFile("c/c.go", `package c; func C() {};`)
		env.WriteWorkspaceFile("a/a.go", `package a; import "mod.com/c"; func _() { c.C() }`)
		env.Await(
			NoDiagnostics("a/a.go"),
		)
	})
}

// Create a new file that defines a new symbol, in the same package.
func TestCreateFile(t *testing.T) {
	const pkg = `
-- go.mod --
module mod.com

go 1.14
-- a/a.go --
package a

func _() {
	hello()
}
`
	runner.Run(t, pkg, func(t *testing.T, env *Env) {
		env.Await(
			env.DiagnosticAtRegexp("a/a.go", "hello"),
		)
		env.WriteWorkspaceFile("a/a2.go", `package a; func hello() {};`)
		env.Await(
			EmptyDiagnostics("a/a.go"),
		)
	})
}

// Add a new method to an interface and implement it.
// Inspired by the structure of internal/lsp/source and internal/lsp/cache.
func TestCreateImplementation(t *testing.T) {
	const pkg = `
-- go.mod --
module mod.com

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

type B interface{
	Hello() string
}

func SayHello(bee B) {
	println(bee.Hello())
}
-- a/a.go --
package a

import "mod.com/b"

type X struct {}

func (_ X) Hello() string {
	return ""
}

func _() {
	x := X{}
	b.SayHello(x)
}
`
	const newMethod = `package b
type B interface{
	Hello() string
	Bye() string
}

func SayHello(bee B) {
	println(bee.Hello())
}`
	const implementation = `package a

import "mod.com/b"

type X struct {}

func (_ X) Hello() string {
	return ""
}

func (_ X) Bye() string {
	return ""
}

func _() {
	x := X{}
	b.SayHello(x)
}`

	// Add the new method before the implementation. Expect diagnostics.
	t.Run("method before implementation", func(t *testing.T) {
		runner.Run(t, pkg, func(t *testing.T, env *Env) {
			env.Await(
				CompletedWork(lsp.DiagnosticWorkTitle(lsp.FromInitialWorkspaceLoad), 1),
			)
			env.WriteWorkspaceFile("b/b.go", newMethod)
			env.Await(
				OnceMet(
					CompletedWork(lsp.DiagnosticWorkTitle(lsp.FromDidChangeWatchedFiles), 1),
					DiagnosticAt("a/a.go", 12, 12),
				),
			)
			env.WriteWorkspaceFile("a/a.go", implementation)
			env.Await(
				EmptyDiagnostics("a/a.go"),
			)
		})
	})
	// Add the new implementation before the new method. Expect no diagnostics.
	t.Run("implementation before method", func(t *testing.T) {
		runner.Run(t, pkg, func(t *testing.T, env *Env) {
			env.Await(
				CompletedWork(lsp.DiagnosticWorkTitle(lsp.FromInitialWorkspaceLoad), 1),
			)
			env.WriteWorkspaceFile("a/a.go", implementation)
			env.Await(
				OnceMet(
					CompletedWork(lsp.DiagnosticWorkTitle(lsp.FromDidChangeWatchedFiles), 1),
					NoDiagnostics("a/a.go"),
				),
			)
			env.WriteWorkspaceFile("b/b.go", newMethod)
			env.Await(
				NoDiagnostics("a/a.go"),
			)
		})
	})
	// Add both simultaneously. Expect no diagnostics.
	t.Run("implementation and method simultaneously", func(t *testing.T) {
		runner.Run(t, pkg, func(t *testing.T, env *Env) {
			env.Await(
				CompletedWork(lsp.DiagnosticWorkTitle(lsp.FromInitialWorkspaceLoad), 1),
			)
			env.WriteWorkspaceFiles(map[string]string{
				"a/a.go": implementation,
				"b/b.go": newMethod,
			})
			env.Await(
				OnceMet(
					CompletedWork(lsp.DiagnosticWorkTitle(lsp.FromDidChangeWatchedFiles), 1),
					NoDiagnostics("a/a.go"),
				),
				NoDiagnostics("b/b.go"),
			)
		})
	})
}

// Tests golang/go#38498. Delete a file and then force a reload.
// Assert that we no longer try to load the file.
func TestDeleteFiles(t *testing.T) {
	const pkg = `
-- go.mod --
module mod.com

go 1.14
-- a/a.go --
package a

func _() {
	var _ int
}
-- a/a_unneeded.go --
package a
`
	t.Run("close then delete", func(t *testing.T) {
		runner.Run(t, pkg, func(t *testing.T, env *Env) {
			env.OpenFile("a/a.go")
			env.OpenFile("a/a_unneeded.go")
			env.Await(
				OnceMet(
					CompletedWork(lsp.DiagnosticWorkTitle(lsp.FromDidOpen), 2),
					LogMatching(protocol.Info, "a_unneeded.go", 1),
				),
			)

			// Close and delete the open file, mimicking what an editor would do.
			env.CloseBuffer("a/a_unneeded.go")
			env.RemoveWorkspaceFile("a/a_unneeded.go")
			env.RegexpReplace("a/a.go", "var _ int", "fmt.Println(\"\")")
			env.Await(
				env.DiagnosticAtRegexp("a/a.go", "fmt"),
			)
			env.SaveBuffer("a/a.go")
			env.Await(
				OnceMet(
					CompletedWork(lsp.DiagnosticWorkTitle(lsp.FromDidSave), 1),
					// There should only be one log message containing
					// a_unneeded.go, from the initial workspace load, which we
					// check for earlier. If there are more, there's a bug.
					LogMatching(protocol.Info, "a_unneeded.go", 1),
				),
				EmptyDiagnostics("a/a.go"),
			)
		})
	})

	t.Run("delete then close", func(t *testing.T) {
		runner.Run(t, pkg, func(t *testing.T, env *Env) {
			env.OpenFile("a/a.go")
			env.OpenFile("a/a_unneeded.go")
			env.Await(
				OnceMet(
					CompletedWork(lsp.DiagnosticWorkTitle(lsp.FromDidOpen), 2),
					LogMatching(protocol.Info, "a_unneeded.go", 1),
				),
			)

			// Delete and then close the file.
			env.RemoveWorkspaceFile("a/a_unneeded.go")
			env.CloseBuffer("a/a_unneeded.go")
			env.RegexpReplace("a/a.go", "var _ int", "fmt.Println(\"\")")
			env.Await(
				env.DiagnosticAtRegexp("a/a.go", "fmt"),
			)
			env.SaveBuffer("a/a.go")
			env.Await(
				OnceMet(
					CompletedWork(lsp.DiagnosticWorkTitle(lsp.FromDidSave), 1),
					// There should only be one log message containing
					// a_unneeded.go, from the initial workspace load, which we
					// check for earlier. If there are more, there's a bug.
					LogMatching(protocol.Info, "a_unneeded.go", 1),
				),
				EmptyDiagnostics("a/a.go"),
			)
		})
	})
}

// This change reproduces the behavior of switching branches, with multiple
// files being created and deleted. The key change here is the movement of a
// symbol from one file to another in a given package through a deletion and
// creation. To reproduce an issue with metadata invalidation in batched
// changes, the last change in the batch is an on-disk file change that doesn't
// require metadata invalidation.
func TestMoveSymbol(t *testing.T) {
	const pkg = `
-- go.mod --
module mod.com

go 1.14
-- main.go --
package main

import "mod.com/a"

func main() {
	var x int
	x = a.Hello
	println(x)
}
-- a/a1.go --
package a

var Hello int
-- a/a2.go --
package a

func _() {}
`
	runner.Run(t, pkg, func(t *testing.T, env *Env) {
		env.Await(
			CompletedWork(lsp.DiagnosticWorkTitle(lsp.FromInitialWorkspaceLoad), 1),
		)
		env.ChangeFilesOnDisk([]fake.FileEvent{
			{
				Path: "a/a3.go",
				Content: `package a

var Hello int
`,
				ProtocolEvent: protocol.FileEvent{
					URI:  env.Sandbox.Workdir.URI("a/a3.go"),
					Type: protocol.Created,
				},
			},
			{
				Path: "a/a1.go",
				ProtocolEvent: protocol.FileEvent{
					URI:  env.Sandbox.Workdir.URI("a/a1.go"),
					Type: protocol.Deleted,
				},
			},
			{
				Path:    "a/a2.go",
				Content: `package a; func _() {};`,
				ProtocolEvent: protocol.FileEvent{
					URI:  env.Sandbox.Workdir.URI("a/a2.go"),
					Type: protocol.Changed,
				},
			},
		})
		env.Await(
			OnceMet(
				CompletedWork(lsp.DiagnosticWorkTitle(lsp.FromDidChangeWatchedFiles), 1),
				NoDiagnostics("main.go"),
			),
		)
	})
}

// Reproduce golang/go#40456.
func TestChangeVersion(t *testing.T) {
	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"

func X(x int) {}
-- example.com@v1.2.2/go.mod --
module example.com

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

const Name = "Blah"

func X() {}
-- 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"
`
	const mod = `
-- go.mod --
module mod.com

go 1.12

require example.com v1.2.2
-- main.go --
package main

import "example.com/blah"

func main() {
	blah.X()
}
`
	withOptions(WithProxyFiles(proxy)).run(t, mod, func(t *testing.T, env *Env) {
		env.Await(
			CompletedWork(lsp.DiagnosticWorkTitle(lsp.FromInitialWorkspaceLoad), 1),
		)
		env.WriteWorkspaceFiles(map[string]string{
			"go.mod": `module mod.com

go 1.12

require example.com v1.2.3
`,
			"main.go": `package main

import (
	"example.com/blah"
)

func main() {
	blah.X(1)
}
`,
		})
		env.Await(
			CompletedWork(lsp.DiagnosticWorkTitle(lsp.FromDidChangeWatchedFiles), 1),
			NoDiagnostics("main.go"),
		)
	})
}

// Reproduces golang/go#37069.
func TestSwitchFromGOPATHToModules(t *testing.T) {
	t.Skipf("golang/go#37069 is not yet resolved.")

	const files = `
-- foo/blah/blah.go --
package blah

const Name = ""
-- foo/main.go --
package main

import "blah"

func main() {
	_ = blah.Name
}
`
	withOptions(InGOPATH()).run(t, files, func(t *testing.T, env *Env) {
		env.OpenFile("foo/main.go")
		env.Await(
			OnceMet(
				CompletedWork(lsp.DiagnosticWorkTitle(lsp.FromInitialWorkspaceLoad), 1),
				env.DiagnosticAtRegexp("foo/main.go", `"blah"`),
			),
		)
		if err := env.Sandbox.RunGoCommand(env.Ctx, "foo", "mod", []string{"init", "mod.com"}); err != nil {
			t.Fatal(err)
		}
		env.Await(
			OnceMet(
				CompletedWork(lsp.DiagnosticWorkTitle(lsp.FromDidChangeWatchedFiles), 1),
				env.DiagnosticAtRegexp("foo/main.go", `"blah`),
			),
		)
		env.RegexpReplace("foo/main.go", `"blah"`, `"mod.com/blah"`)
		env.Await(
			OnceMet(
				CompletedWork(lsp.DiagnosticWorkTitle(lsp.FromDidChange), 1),
				NoDiagnostics("foo/main.go"),
			),
		)
	})
}

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

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

func bob() {}
-- a/a_test.go --
package a

import "testing"

func TestBob(t *testing.T) {
	bob()
}
`
	run(t, files, func(t *testing.T, env *Env) {
		env.Await(
			CompletedWork(lsp.DiagnosticWorkTitle(lsp.FromInitialWorkspaceLoad), 1),
		)
		// Add a new symbol to the package under test and use it in the test
		// variant. Expect no diagnostics.
		env.WriteWorkspaceFiles(map[string]string{
			"a/a.go": `package a

func bob() {}
func george() {}
`,
			"a/a_test.go": `package a

import "testing"

func TestAll(t *testing.T) {
	bob()
	george()
}
`,
		})
		env.Await(
			OnceMet(
				CompletedWork(lsp.DiagnosticWorkTitle(lsp.FromDidChangeWatchedFiles), 1),
				NoDiagnostics("a/a.go"),
			),
			OnceMet(
				CompletedWork(lsp.DiagnosticWorkTitle(lsp.FromDidChangeWatchedFiles), 1),
				NoDiagnostics("a/a_test.go"),
			),
		)
		// Now, add a new file to the test variant and use its symbol in the
		// original test file. Expect no diagnostics.
		env.WriteWorkspaceFiles(map[string]string{
			"a/a_test.go": `package a

import "testing"

func TestAll(t *testing.T) {
	bob()
	george()
	hi()
}
`,
			"a/a2_test.go": `package a

import "testing"

func hi() {}

func TestSomething(t *testing.T) {}
`,
		})
		env.Await(
			OnceMet(
				CompletedWork(lsp.DiagnosticWorkTitle(lsp.FromDidChangeWatchedFiles), 2),
				NoDiagnostics("a/a_test.go"),
			),
			OnceMet(
				CompletedWork(lsp.DiagnosticWorkTitle(lsp.FromDidChangeWatchedFiles), 2),
				NoDiagnostics("a/a2_test.go"),
			),
		)
	})
}
