// Copyright 2022 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 checker_test

import (
	"flag"
	"fmt"
	"go/token"
	"log"
	"os"
	"os/exec"
	"path"
	"regexp"
	"strings"
	"testing"

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

// These are the analyzers available to the multichecker.
// (Tests may add more in init functions as needed.)
var candidates = map[string]*analysis.Analyzer{
	renameAnalyzer.Name: renameAnalyzer,
	otherAnalyzer.Name:  otherAnalyzer,
}

func TestMain(m *testing.M) {
	// If the ANALYZERS=a,..,z environment is set, then this
	// process should behave like a multichecker with the
	// named analyzers.
	if s, ok := os.LookupEnv("ANALYZERS"); ok {
		var analyzers []*analysis.Analyzer
		for _, name := range strings.Split(s, ",") {
			a := candidates[name]
			if a == nil {
				log.Fatalf("no such analyzer: %q", name)
			}
			analyzers = append(analyzers, a)
		}
		multichecker.Main(analyzers...)
		panic("unreachable")
	}

	// ordinary test
	flag.Parse()
	os.Exit(m.Run())
}

const (
	exitCodeSuccess     = 0 // success (no diagnostics)
	exitCodeFailed      = 1 // analysis failed to run
	exitCodeDiagnostics = 3 // diagnostics were reported
)

// fix runs a multichecker subprocess with -fix in the specified
// directory, applying the comma-separated list of named analyzers to
// the packages matching the patterns. It returns the CombinedOutput.
func fix(t *testing.T, dir, analyzers string, wantExit int, patterns ...string) string {
	testenv.NeedsExec(t)
	testenv.NeedsTool(t, "go")

	cmd := exec.Command(os.Args[0], "-fix")
	cmd.Args = append(cmd.Args, patterns...)
	cmd.Env = append(os.Environ(),
		"ANALYZERS="+analyzers,
		"GOPATH="+dir,
		"GO111MODULE=off",
		"GOPROXY=off")

	clean := func(s string) string {
		return strings.ReplaceAll(s, os.TempDir(), "os.TempDir/")
	}
	outBytes, err := cmd.CombinedOutput()
	out := clean(string(outBytes))
	t.Logf("$ %s\n%s", clean(fmt.Sprint(cmd)), out)
	if err, ok := err.(*exec.ExitError); !ok {
		t.Fatalf("failed to execute multichecker: %v", err)
	} else if err.ExitCode() != wantExit {
		t.Errorf("exit code was %d, want %d", err.ExitCode(), wantExit)
	}
	return out
}

// TestFixes ensures that checker.Run applies fixes correctly.
// This test fork/execs the main function above.
func TestFixes(t *testing.T) {
	files := map[string]string{
		"rename/foo.go": `package rename

func Foo() {
	bar := 12
	_ = bar
}

// the end
`,
		"rename/intestfile_test.go": `package rename

func InTestFile() {
	bar := 13
	_ = bar
}

// the end
`,
		"rename/foo_test.go": `package rename_test

func Foo() {
	bar := 14
	_ = bar
}

// the end
`,
		"duplicate/dup.go": `package duplicate

func Foo() {
	bar := 14
	_ = bar
}

// the end
`,
	}
	fixed := map[string]string{
		"rename/foo.go": `package rename

func Foo() {
	baz := 12
	_ = baz
}

// the end
`,
		"rename/intestfile_test.go": `package rename

func InTestFile() {
	baz := 13
	_ = baz
}

// the end
`,
		"rename/foo_test.go": `package rename_test

func Foo() {
	baz := 14
	_ = baz
}

// the end
`,
		"duplicate/dup.go": `package duplicate

func Foo() {
	baz := 14
	_ = baz
}

// the end
`,
	}
	dir, cleanup, err := analysistest.WriteFiles(files)
	if err != nil {
		t.Fatalf("Creating test files failed with %s", err)
	}
	defer cleanup()

	fix(t, dir, "rename,other", exitCodeDiagnostics, "rename", "duplicate")

	for name, want := range fixed {
		path := path.Join(dir, "src", name)
		contents, err := os.ReadFile(path)
		if err != nil {
			t.Errorf("error reading %s: %v", path, err)
		}
		if got := string(contents); got != want {
			t.Errorf("contents of %s file did not match expectations. got=%s, want=%s", path, got, want)
		}
	}
}

// TestConflict ensures that checker.Run detects conflicts correctly.
// This test fork/execs the main function above.
func TestConflict(t *testing.T) {
	files := map[string]string{
		"conflict/foo.go": `package conflict

func Foo() {
	bar := 12
	_ = bar
}

// the end
`,
	}
	dir, cleanup, err := analysistest.WriteFiles(files)
	if err != nil {
		t.Fatalf("Creating test files failed with %s", err)
	}
	defer cleanup()

	out := fix(t, dir, "rename,other", exitCodeFailed, "conflict")

	pattern := `conflicting edits from rename and rename on .*foo.go`
	matched, err := regexp.MatchString(pattern, out)
	if err != nil {
		t.Errorf("error matching pattern %s: %v", pattern, err)
	} else if !matched {
		t.Errorf("output did not match pattern: %s", pattern)
	}

	// No files updated
	for name, want := range files {
		path := path.Join(dir, "src", name)
		contents, err := os.ReadFile(path)
		if err != nil {
			t.Errorf("error reading %s: %v", path, err)
		}
		if got := string(contents); got != want {
			t.Errorf("contents of %s file updated. got=%s, want=%s", path, got, want)
		}
	}
}

// TestOther ensures that checker.Run reports conflicts from
// distinct actions correctly.
// This test fork/execs the main function above.
func TestOther(t *testing.T) {
	files := map[string]string{
		"other/foo.go": `package other

func Foo() {
	bar := 12
	_ = bar
}

// the end
`,
	}
	dir, cleanup, err := analysistest.WriteFiles(files)
	if err != nil {
		t.Fatalf("Creating test files failed with %s", err)
	}
	defer cleanup()

	out := fix(t, dir, "rename,other", exitCodeFailed, "other")

	pattern := `.*conflicting edits from other and rename on .*foo.go`
	matched, err := regexp.MatchString(pattern, out)
	if err != nil {
		t.Errorf("error matching pattern %s: %v", pattern, err)
	} else if !matched {
		t.Errorf("output did not match pattern: %s", pattern)
	}

	// No files updated
	for name, want := range files {
		path := path.Join(dir, "src", name)
		contents, err := os.ReadFile(path)
		if err != nil {
			t.Errorf("error reading %s: %v", path, err)
		}
		if got := string(contents); got != want {
			t.Errorf("contents of %s file updated. got=%s, want=%s", path, got, want)
		}
	}
}

// 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) {
	files := map[string]string{
		"a/a.go": "package a\n\nfunc F() {}",
	}
	dir, cleanup, err := analysistest.WriteFiles(files)
	if err != nil {
		t.Fatalf("Creating test files failed with %s", err)
	}
	defer cleanup()

	fix(t, dir, "noend", exitCodeDiagnostics, "a")

	got, err := os.ReadFile(path.Join(dir, "src/a/a.go"))
	if err != nil {
		t.Fatal(err)
	}
	const want = "package a\n\n/*hello*/\nfunc F() {}\n"
	if string(got) != want {
		t.Errorf("new file contents were <<%s>>, want <<%s>>", got, want)
	}
}

func init() {
	candidates["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
		},
	}
}
