// Copyright 2018 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 analysistest_test

import (
	"fmt"
	"go/token"
	"log"
	"os"
	"reflect"
	"strings"
	"testing"

	"golang.org/x/tools/go/analysis"
	"golang.org/x/tools/go/analysis/analysistest"
	"golang.org/x/tools/go/analysis/passes/findcall"
	"golang.org/x/tools/internal/testenv"
)

func init() {
	// Run() decides when tests use GOPATH mode or modules.
	// We turn off GOPROXY just for good measure.
	if err := os.Setenv("GOPROXY", "off"); err != nil {
		log.Fatal(err)
	}
}

// TestTheTest tests the analysistest testing infrastructure.
func TestTheTest(t *testing.T) {
	testenv.NeedsTool(t, "go")

	// We'll simulate a partly failing test of the findcall analysis,
	// which (by default) reports calls to functions named 'println'.
	findcall.Analyzer.Flags.Set("name", "println")

	filemap := map[string]string{
		"a/b.go": `package main // want package:"found"

func main() {
	// The expectation is ill-formed:
	print() // want: "diagnostic"
	print() // want foo"fact"
	print() // want foo:
	print() // want "\xZZ scan error"

	// A diagnostic is reported at this line, but the expectation doesn't match:
	println("hello, world") // want "wrong expectation text"

	// An unexpected diagnostic is reported at this line:
	println() // trigger an unexpected diagnostic

	// No diagnostic is reported at this line:
	print()	// want "unsatisfied expectation"

	// OK
	println("hello, world") // want "call of println"

	// OK /* */-form.
	println("안녕, 세계") /* want "call of println" */

	// OK  (nested comment)
	println("Γειά σου, Κόσμε") // some comment // want "call of println"

	// OK (nested comment in /**/)
	println("你好，世界") /* some comment // want "call of println" */

	// OK (multiple expectations on same line)
	println(); println() // want "call of println(...)" "call of println(...)"

	// A Line that is not formatted correctly in the golden file.
}

// OK (facts and diagnostics on same line)
func println(...interface{}) { println() } // want println:"found" "call of println(...)"

`,
		"a/b.go.golden": `package main // want package:"found"

func main() {
	// The expectation is ill-formed:
	print() // want: "diagnostic"
	print() // want foo"fact"
	print() // want foo:
	print() // want "\xZZ scan error"

	// A diagnostic is reported at this line, but the expectation doesn't match:
	println_TEST_("hello, world") // want "wrong expectation text"

	// An unexpected diagnostic is reported at this line:
	println_TEST_() // trigger an unexpected diagnostic

	// No diagnostic is reported at this line:
	print() // want "unsatisfied expectation"

	// OK
	println_TEST_("hello, world") // want "call of println"

	// OK /* */-form.
	println_TEST_("안녕, 세계") /* want "call of println" */

	// OK  (nested comment)
	println_TEST_("Γειά σου, Κόσμε") // some comment // want "call of println"

	// OK (nested comment in /**/)
	println_TEST_("你好，世界") /* some comment // want "call of println" */

	// OK (multiple expectations on same line)
	println_TEST_()
	println_TEST_() // want "call of println(...)" "call of println(...)"
	
			// A Line that is not formatted correctly in the golden file.
}

// OK (facts and diagnostics on same line)
func println(...interface{}) { println_TEST_() } // want println:"found" "call of println(...)"
`,
		"a/b_test.go": `package main

// Test file shouldn't mess with things (issue #40574)
`,
	}
	dir, cleanup, err := analysistest.WriteFiles(filemap)
	if err != nil {
		t.Fatal(err)
	}
	defer cleanup()

	var got []string
	t2 := errorfunc(func(s string) { got = append(got, s) }) // a fake *testing.T
	analysistest.RunWithSuggestedFixes(t2, dir, findcall.Analyzer, "a")

	want := []string{
		`a/b.go:5: in 'want' comment: unexpected ":"`,
		`a/b.go:6: in 'want' comment: got String after foo, want ':'`,
		`a/b.go:7: in 'want' comment: got EOF, want regular expression`,
		`a/b.go:8: in 'want' comment: invalid char escape`,
		"a/b.go:11:9: diagnostic \"call of println(...)\" does not match pattern `wrong expectation text`",
		`a/b.go:14:9: unexpected diagnostic: call of println(...)`,
		"a/b.go:11: no diagnostic was reported matching `wrong expectation text`",
		"a/b.go:17: no diagnostic was reported matching `unsatisfied expectation`",
		// duplicate copies of each message from the test package (see issue #40574)
		`a/b.go:5: in 'want' comment: unexpected ":"`,
		`a/b.go:6: in 'want' comment: got String after foo, want ':'`,
		`a/b.go:7: in 'want' comment: got EOF, want regular expression`,
		`a/b.go:8: in 'want' comment: invalid char escape`,
		"a/b.go:11:9: diagnostic \"call of println(...)\" does not match pattern `wrong expectation text`",
		`a/b.go:14:9: unexpected diagnostic: call of println(...)`,
		"a/b.go:11: no diagnostic was reported matching `wrong expectation text`",
		"a/b.go:17: no diagnostic was reported matching `unsatisfied expectation`",
	}
	if !reflect.DeepEqual(got, want) {
		t.Errorf("got:\n%s\nwant:\n%s",
			strings.Join(got, "\n"),
			strings.Join(want, "\n"))
	}
}

// TestNoEnd tests that a missing SuggestedFix.End position is
// correctly interpreted as if equal to SuggestedFix.Pos (see issue #64199).
func TestNoEnd(t *testing.T) {
	noend := &analysis.Analyzer{
		Name: "noend",
		Doc:  "inserts /*hello*/ before first decl",
		Run: func(pass *analysis.Pass) (any, error) {
			decl := pass.Files[0].Decls[0]
			pass.Report(analysis.Diagnostic{
				Pos:     decl.Pos(),
				End:     token.NoPos,
				Message: "say hello",
				SuggestedFixes: []analysis.SuggestedFix{{
					Message: "say hello",
					TextEdits: []analysis.TextEdit{
						{
							Pos:     decl.Pos(),
							End:     token.NoPos,
							NewText: []byte("/*hello*/"),
						},
					},
				}},
			})
			return nil, nil
		},
	}

	filemap := map[string]string{
		"a/a.go": `package a

func F() {} // want "say hello"`,
		"a/a.go.golden": `package a

/*hello*/
func F() {} // want "say hello"`,
	}
	dir, cleanup, err := analysistest.WriteFiles(filemap)
	if err != nil {
		t.Fatal(err)
	}
	defer cleanup()

	analysistest.RunWithSuggestedFixes(t, dir, noend, "a")
}

type errorfunc func(string)

func (f errorfunc) Errorf(format string, args ...interface{}) {
	f(fmt.Sprintf(format, args...))
}
