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

import (
	"fmt"
	"os"
	"path/filepath"
	"reflect"
	"sort"
	"strings"
	"testing"

	"github.com/google/go-cmp/cmp"
	"golang.org/x/tools/gopls/internal/protocol"
	"golang.org/x/tools/gopls/internal/test/integration"
	. "golang.org/x/tools/gopls/internal/test/integration"
)

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

go 1.12
-- main.go --
package main

import "fmt"

func main() {
	fmt.Print()
}
`

	Run(t, files, func(t *testing.T, env *Env) {
		env.OpenFile("main.go")
		loc := env.GoToDefinition(env.RegexpSearch("main.go", `fmt.(Print)`))
		refs, err := env.Editor.References(env.Ctx, loc)
		if err != nil {
			t.Fatal(err)
		}
		if len(refs) != 2 {
			// TODO(adonovan): make this assertion less maintainer-hostile.
			t.Fatalf("got %v reference(s), want 2", len(refs))
		}
		// The first reference is guaranteed to be the definition.
		if got, want := refs[1].URI, env.Sandbox.Workdir.URI("main.go"); got != want {
			t.Errorf("found reference in %v, wanted %v", got, want)
		}
	})
}

// This is a regression test for golang/go#48400 (a panic).
func TestReferencesOnErrorMethod(t *testing.T) {
	// Ideally this would actually return the correct answer,
	// instead of merely failing gracefully.
	const files = `
-- go.mod --
module mod.com

go 1.12
-- main.go --
package main

type t interface {
	error
}

type s struct{}

func (*s) Error() string {
	return ""
}

func _() {
	var s s
	_ = s.Error()
}
`
	Run(t, files, func(t *testing.T, env *Env) {
		env.OpenFile("main.go")
		loc := env.GoToDefinition(env.RegexpSearch("main.go", `Error`))
		refs, err := env.Editor.References(env.Ctx, loc)
		if err != nil {
			t.Fatalf("references on (*s).Error failed: %v", err)
		}
		// TODO(adonovan): this test is crying out for marker support in integration tests.
		var buf strings.Builder
		for _, ref := range refs {
			fmt.Fprintf(&buf, "%s %s\n", env.Sandbox.Workdir.URIToPath(ref.URI), ref.Range)
		}
		got := buf.String()
		want := "main.go 8:10-8:15\n" + // (*s).Error decl
			"main.go 14:7-14:12\n" // s.Error() call
		if diff := cmp.Diff(want, got); diff != "" {
			t.Errorf("unexpected references on (*s).Error (-want +got):\n%s", diff)
		}
	})
}

func TestDefsRefsBuiltins(t *testing.T) {
	// TODO(adonovan): add unsafe.{SliceData,String,StringData} in later go versions.
	const files = `
-- go.mod --
module example.com
go 1.16

-- a.go --
package a

import "unsafe"

const _ = iota
var _ error
var _ int
var _ = append()
var _ = unsafe.Pointer(nil)
var _ = unsafe.Add(nil, nil)
var _ = unsafe.Sizeof(0)
var _ = unsafe.Alignof(0)
var _ = unsafe.Slice(nil, 0)
`

	Run(t, files, func(t *testing.T, env *Env) {
		env.OpenFile("a.go")
		for _, name := range strings.Fields(
			"iota error int nil append iota Pointer Sizeof Alignof Add Slice") {
			loc := env.RegexpSearch("a.go", `\b`+name+`\b`)

			// definition -> {builtin,unsafe}.go
			def := env.GoToDefinition(loc)
			if (!strings.HasSuffix(string(def.URI), "builtin.go") &&
				!strings.HasSuffix(string(def.URI), "unsafe.go")) ||
				def.Range.Start.Line == 0 {
				t.Errorf("definition(%q) = %v, want {builtin,unsafe}.go",
					name, def)
			}

			// "references to (builtin "Foo"|unsafe.Foo) are not supported"
			_, err := env.Editor.References(env.Ctx, loc)
			gotErr := fmt.Sprint(err)
			if !strings.Contains(gotErr, "references to") ||
				!strings.Contains(gotErr, "not supported") ||
				!strings.Contains(gotErr, name) {
				t.Errorf("references(%q) error: got %q, want %q",
					name, gotErr, "references to ... are not supported")
			}
		}
	})
}

func TestPackageReferences(t *testing.T) {
	tests := []struct {
		packageName  string
		wantRefCount int
		wantFiles    []string
	}{
		{
			"lib1",
			3,
			[]string{
				"main.go",
				"lib1/a.go",
				"lib1/b.go",
			},
		},
		{
			"lib2",
			2,
			[]string{
				"main.go",
				"lib2/a.go",
			},
		},
	}

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

go 1.18
-- lib1/a.go --
package lib1

const A = 1

-- lib1/b.go --
package lib1

const B = 1

-- lib2/a.go --
package lib2

const C = 1

-- main.go --
package main

import (
	"mod.com/lib1"
	"mod.com/lib2"
)

func main() {
	println("Hello")
}
`
	Run(t, files, func(t *testing.T, env *Env) {
		for _, test := range tests {
			file := fmt.Sprintf("%s/a.go", test.packageName)
			env.OpenFile(file)
			loc := env.RegexpSearch(file, test.packageName)
			refs := env.References(loc)
			if len(refs) != test.wantRefCount {
				// TODO(adonovan): make this assertion less maintainer-hostile.
				t.Fatalf("got %v reference(s), want %d", len(refs), test.wantRefCount)
			}
			var refURIs []string
			for _, ref := range refs {
				refURIs = append(refURIs, string(ref.URI))
			}
			for _, base := range test.wantFiles {
				hasBase := false
				for _, ref := range refURIs {
					if strings.HasSuffix(ref, base) {
						hasBase = true
						break
					}
				}
				if !hasBase {
					t.Fatalf("got [%v], want reference ends with \"%v\"", strings.Join(refURIs, ","), base)
				}
			}
		}
	})
}

// Test for golang/go#43144.
//
// Verify that we search for references and implementations in intermediate
// test variants.
func TestReferencesInTestVariants(t *testing.T) {
	const files = `
-- go.mod --
module foo.mod

go 1.12
-- foo/foo.go --
package foo

import "foo.mod/bar"

const Foo = 42

type T int
type InterfaceM interface{ M() }
type InterfaceF interface{ F() }

func _() {
	_ = bar.Blah
}

-- foo/foo_test.go --
package foo

type Fer struct{}
func (Fer) F() {}

-- bar/bar.go --
package bar

var Blah = 123

-- bar/bar_test.go --
package bar

type Mer struct{}
func (Mer) M() {}

func TestBar() {
	_ = Blah
}
-- bar/bar_x_test.go --
package bar_test

import (
	"foo.mod/bar"
	"foo.mod/foo"
)

type Mer struct{}
func (Mer) M() {}

func _() {
	_ = bar.Blah
	_ = foo.Foo
}
`

	Run(t, files, func(t *testing.T, env *Env) {
		env.OpenFile("foo/foo.go")

		refTests := []struct {
			re       string
			wantRefs []string
		}{
			// Blah is referenced:
			// - inside the foo.mod/bar (ordinary) package
			// - inside the foo.mod/bar [foo.mod/bar.test] test variant package
			// - from the foo.mod/bar_test [foo.mod/bar.test] x_test package
			// - from the foo.mod/foo package
			{"Blah", []string{"bar/bar.go:3", "bar/bar_test.go:7", "bar/bar_x_test.go:12", "foo/foo.go:12"}},

			// Foo is referenced in bar_x_test.go via the intermediate test variant
			// foo.mod/foo [foo.mod/bar.test].
			{"Foo", []string{"bar/bar_x_test.go:13", "foo/foo.go:5"}},
		}

		for _, test := range refTests {
			loc := env.RegexpSearch("foo/foo.go", test.re)
			refs := env.References(loc)

			got := fileLocations(env, refs)
			if diff := cmp.Diff(test.wantRefs, got); diff != "" {
				t.Errorf("References(%q) returned unexpected diff (-want +got):\n%s", test.re, diff)
			}
		}

		implTests := []struct {
			re        string
			wantImpls []string
		}{
			// InterfaceM is implemented both in foo.mod/bar [foo.mod/bar.test] (which
			// doesn't import foo), and in foo.mod/bar_test [foo.mod/bar.test], which
			// imports the test variant of foo.
			{"InterfaceM", []string{"bar/bar_test.go:3", "bar/bar_x_test.go:8"}},

			// A search within the ordinary package to should find implementations
			// (Fer) within the augmented test package.
			{"InterfaceF", []string{"foo/foo_test.go:3"}},
		}

		for _, test := range implTests {
			loc := env.RegexpSearch("foo/foo.go", test.re)
			impls := env.Implementations(loc)

			got := fileLocations(env, impls)
			if diff := cmp.Diff(test.wantImpls, got); diff != "" {
				t.Errorf("Implementations(%q) returned unexpected diff (-want +got):\n%s", test.re, diff)
			}
		}
	})
}

// This is a regression test for Issue #56169, in which interface
// implementations in vendored modules were not found. The actual fix
// was the same as for #55995; see TestVendoringInvalidatesMetadata.
func TestImplementationsInVendor(t *testing.T) {
	const proxy = `
-- other.com/b@v1.0.0/go.mod --
module other.com/b
go 1.14

-- other.com/b@v1.0.0/b.go --
package b
type B int
func (B) F() {}
`
	const src = `
-- go.mod --
module example.com/a
go 1.14
require other.com/b v1.0.0

-- go.sum --
other.com/b v1.0.0 h1:9WyCKS+BLAMRQM0CegP6zqP2beP+ShTbPaARpNY31II=
other.com/b v1.0.0/go.mod h1:TgHQFucl04oGT+vrUm/liAzukYHNxCwKNkQZEyn3m9g=

-- a.go --
package a
import "other.com/b"
type I interface { F() }
var _ b.B

`
	WithOptions(
		ProxyFiles(proxy),
		Modes(Default), // fails in 'experimental' mode
	).Run(t, src, func(t *testing.T, env *Env) {
		// Enable to debug go.sum mismatch, which may appear as
		// "module lookup disabled by GOPROXY=off", confusingly.
		if false {
			env.DumpGoSum(".")
		}

		checkVendor := func(locs []protocol.Location, wantVendor bool) {
			if len(locs) != 1 {
				t.Errorf("got %d locations, want 1", len(locs))
			} else if strings.Contains(string(locs[0].URI), "/vendor/") != wantVendor {
				t.Errorf("got location %s, wantVendor=%t", locs[0], wantVendor)
			}
		}

		env.OpenFile("a.go")
		refLoc := env.RegexpSearch("a.go", "I") // find "I" reference

		// Initially, a.I has one implementation b.B in
		// the module cache, not the vendor tree.
		checkVendor(env.Implementations(refLoc), false)

		// Run 'go mod vendor' outside the editor.
		env.RunGoCommand("mod", "vendor")

		// Synchronize changes to watched files.
		env.Await(env.DoneWithChangeWatchedFiles())

		// Now, b.B is found in the vendor tree.
		checkVendor(env.Implementations(refLoc), true)

		// Delete the vendor tree.
		if err := os.RemoveAll(env.Sandbox.Workdir.AbsPath("vendor")); err != nil {
			t.Fatal(err)
		}
		// Notify the server of the deletion.
		if err := env.Sandbox.Workdir.CheckForFileChanges(env.Ctx); err != nil {
			t.Fatal(err)
		}

		// Synchronize again.
		env.Await(env.DoneWithChangeWatchedFiles())

		// b.B is once again defined in the module cache.
		checkVendor(env.Implementations(refLoc), false)
	})
}

// This test can't be expressed as a marker test because the marker
// test framework opens all files (which is a bit of a hack), creating
// a <command-line-arguments> package for packages that otherwise
// wouldn't be found from the go.work file.
func TestReferencesFromWorkspacePackages59674(t *testing.T) {
	const src = `
-- a/go.mod --
module example.com/a
go 1.12

-- b/go.mod --
module example.com/b
go 1.12

-- c/go.mod --
module example.com/c
go 1.12

-- lib/go.mod --
module example.com/lib
go 1.12

-- go.work --
use ./a
use ./b
// don't use ./c
use ./lib

-- a/a.go --
package a

import "example.com/lib"

var _ = lib.F // query here

-- b/b.go --
package b

import "example.com/lib"

var _ = lib.F // also found by references

-- c/c.go --
package c

import "example.com/lib"

var _ = lib.F // this reference should not be reported

-- lib/lib.go --
package lib

func F() {} // declaration
`
	Run(t, src, func(t *testing.T, env *Env) {
		env.OpenFile("a/a.go")
		refLoc := env.RegexpSearch("a/a.go", "F")
		got := fileLocations(env, env.References(refLoc))
		want := []string{"a/a.go:5", "b/b.go:5", "lib/lib.go:3"}
		if diff := cmp.Diff(want, got); diff != "" {
			t.Errorf("incorrect References (-want +got):\n%s", diff)
		}
	})
}

// Test an 'implementation' query on a type that implements 'error'.
// (Unfortunately builtin locations cannot be expressed using @loc
// in the marker test framework.)
func TestImplementationsOfError(t *testing.T) {
	const src = `
-- go.mod --
module example.com
go 1.12

-- a.go --
package a

type Error2 interface {
	Error() string
}

type MyError int
func (MyError) Error() string { return "" }

type MyErrorPtr int
func (*MyErrorPtr) Error() string { return "" }
`
	Run(t, src, func(t *testing.T, env *Env) {
		env.OpenFile("a.go")

		for _, test := range []struct {
			re   string
			want []string
		}{
			// error type
			{"Error2", []string{"a.go:10", "a.go:7", "std:builtin/builtin.go"}},
			{"MyError", []string{"a.go:3", "std:builtin/builtin.go"}},
			{"MyErrorPtr", []string{"a.go:3", "std:builtin/builtin.go"}},
			// error.Error method
			{"(Error).. string", []string{"a.go:11", "a.go:8", "std:builtin/builtin.go"}},
			{"MyError. (Error)", []string{"a.go:4", "std:builtin/builtin.go"}},
			{"MyErrorPtr. (Error)", []string{"a.go:4", "std:builtin/builtin.go"}},
		} {
			matchLoc := env.RegexpSearch("a.go", test.re)
			impls := env.Implementations(matchLoc)
			got := fileLocations(env, impls)
			if !reflect.DeepEqual(got, test.want) {
				t.Errorf("Implementations(%q) = %q, want %q",
					test.re, got, test.want)
			}
		}
	})
}

// fileLocations returns a new sorted array of the
// relative file name and line number of each location.
// Duplicates are not removed.
// Standard library filenames are abstracted for robustness.
func fileLocations(env *integration.Env, locs []protocol.Location) []string {
	got := make([]string, 0, len(locs))
	for _, loc := range locs {
		path := env.Sandbox.Workdir.URIToPath(loc.URI) // (slashified)
		if i := strings.LastIndex(path, "/src/"); i >= 0 && filepath.IsAbs(path) {
			// Absolute path with "src" segment: assume it's in GOROOT.
			// Strip directory and don't add line/column since they are fragile.
			path = "std:" + path[i+len("/src/"):]
		} else {
			path = fmt.Sprintf("%s:%d", path, loc.Range.Start.Line+1)
		}
		got = append(got, path)
	}
	sort.Strings(got)
	return got
}
