// Copyright 2023 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 inline_test

import (
	"flag"
	"fmt"
	"go/ast"
	"go/parser"
	"go/types"
	"log"
	"os"
	"path/filepath"
	"slices"
	"strings"
	"testing"

	"golang.org/x/tools/go/packages"
	"golang.org/x/tools/go/types/typeutil"
	"golang.org/x/tools/internal/diff"
	"golang.org/x/tools/internal/refactor/inline"
	"golang.org/x/tools/internal/testenv"
)

var packagesFlag = flag.String("packages", "", "set of packages for TestEverything")

// TestEverything invokes the inliner on every single call site in a
// given package. and checks that it produces either a reasonable
// error, or output that parses and type-checks.
//
// It does nothing during ordinary testing, but may be used to find
// inlining bugs in large corpora.
//
// Use this command to inline everything in golang.org/x/tools:
//
// $ go test ./internal/refactor/inline/ -run=Everything -packages=../../../
//
// And these commands to inline everything in the kubernetes repository:
//
// $ go test -c -o /tmp/everything ./internal/refactor/inline/
// $ (cd kubernetes && /tmp/everything -test.run=Everything -packages=./...)
//
// TODO(adonovan):
//   - report counters (number of attempts, failed AnalyzeCallee, failed
//     Inline, etc.)
//   - Make a pretty log of the entire output so that we can peruse it
//     for opportunities for systematic improvement.
func TestEverything(t *testing.T) {
	testenv.NeedsGoPackages(t)
	if testing.Short() {
		t.Skipf("skipping slow test in -short mode")
	}
	if *packagesFlag == "" {
		return
	}

	// Load this package plus dependencies from typed syntax.
	cfg := &packages.Config{
		Mode: packages.LoadAllSyntax,
		Env: append(os.Environ(),
			"GO111MODULES=on",
			"GOPATH=",
			"GOWORK=off",
			"GOPROXY=off"),
	}
	pkgs, err := packages.Load(cfg, *packagesFlag)
	if err != nil {
		t.Errorf("Load: %v", err)
	}
	// Report parse/type errors.
	// Also, build transitive dependency mapping.
	deps := make(map[string]*packages.Package) // key is PkgPath
	packages.Visit(pkgs, nil, func(pkg *packages.Package) {
		deps[pkg.Types.Path()] = pkg
		for _, err := range pkg.Errors {
			t.Fatal(err)
		}
	})

	// Memoize repeated calls for same file.
	fileContent := make(map[string][]byte)
	readFile := func(filename string) ([]byte, error) {
		content, ok := fileContent[filename]
		if !ok {
			var err error
			content, err = os.ReadFile(filename)
			if err != nil {
				return nil, err
			}
			fileContent[filename] = content
		}
		return content, nil
	}

	for _, callerPkg := range pkgs {
		// Find all static function calls in the package.
		for _, callerFile := range callerPkg.Syntax {
			noMutCheck := checkNoMutation(callerFile)
			ast.Inspect(callerFile, func(n ast.Node) bool {
				call, ok := n.(*ast.CallExpr)
				if !ok {
					return true
				}
				fn := typeutil.StaticCallee(callerPkg.TypesInfo, call)
				if fn == nil {
					return true
				}

				// Prepare caller info.
				callPosn := callerPkg.Fset.PositionFor(call.Lparen, false)
				callerContent, err := readFile(callPosn.Filename)
				if err != nil {
					t.Fatal(err)
				}
				caller := &inline.Caller{
					Fset:    callerPkg.Fset,
					Types:   callerPkg.Types,
					Info:    callerPkg.TypesInfo,
					File:    callerFile,
					Call:    call,
					Content: callerContent,
				}

				// Analyze callee.
				calleePkg, ok := deps[fn.Pkg().Path()]
				if !ok {
					t.Fatalf("missing package for callee %v", fn)
				}
				calleePosn := callerPkg.Fset.PositionFor(fn.Pos(), false)
				calleeDecl, err := findFuncByPosition(calleePkg, calleePosn)
				if err != nil {
					t.Fatal(err)
				}
				calleeContent, err := readFile(calleePosn.Filename)
				if err != nil {
					t.Fatal(err)
				}

				// Create a subtest for each inlining operation.
				name := fmt.Sprintf("%s@%v", fn.Name(), filepath.Base(callPosn.String()))
				t.Run(name, func(t *testing.T) {
					// TODO(adonovan): add a panic handler.

					t.Logf("callee declared at %v",
						filepath.Base(calleePosn.String()))

					t.Logf("run this command to reproduce locally:\n$ gopls codeaction -kind=refactor.inline -exec -diff %s:#%d",
						callPosn.Filename, callPosn.Offset)

					callee, err := inline.AnalyzeCallee(
						t.Logf,
						calleePkg.Fset,
						calleePkg.Types,
						calleePkg.TypesInfo,
						calleeDecl,
						calleeContent)
					if err != nil {
						// Ignore the expected kinds of errors.
						for _, ignore := range []string{
							"has no body",
							"type parameters are not yet",
							"line directives",
							"cgo-generated",
						} {
							if strings.Contains(err.Error(), ignore) {
								return
							}
						}
						t.Fatalf("AnalyzeCallee: %v", err)
					}
					if err := checkTranscode(callee); err != nil {
						t.Fatal(err)
					}

					res, err := inline.Inline(caller, callee, &inline.Options{
						Logf: t.Logf,
					})
					if err != nil {
						// Write error to a log, but this ok.
						t.Log(err)
						return
					}
					got := res.Content

					// Print the diff.
					t.Logf("Got diff:\n%s",
						diff.Unified("old", "new", string(callerContent), string(res.Content)))

					// Parse and type-check the transformed source.
					f, err := parser.ParseFile(caller.Fset, callPosn.Filename, got, parser.SkipObjectResolution)
					if err != nil {
						t.Fatalf("transformed source does not parse: %v", err)
					}
					// Splice into original file list.
					syntax := slices.Clone(callerPkg.Syntax)
					for i := range callerPkg.Syntax {
						if syntax[i] == callerFile {
							syntax[i] = f
							break
						}
					}

					var typeErrors []string
					conf := &types.Config{
						Error: func(err error) {
							typeErrors = append(typeErrors, err.Error())
						},
						Importer: importerFunc(func(importPath string) (*types.Package, error) {
							// Note: deps is properly keyed by package path,
							// not import path, but we can't assume
							// Package.Imports[importPath] exists in the
							// case of newly added imports of indirect
							// dependencies. Seems not to matter to this test.
							dep, ok := deps[importPath]
							if ok {
								return dep.Types, nil
							}
							return nil, fmt.Errorf("missing package: %q", importPath)
						}),
					}
					if _, err := conf.Check("p", caller.Fset, syntax, nil); err != nil {
						t.Fatalf("transformed package has type errors:\n\n%s\n\nTransformed file:\n\n%s",
							strings.Join(typeErrors, "\n"),
							got)
					}
				})
				return true
			})
			noMutCheck()
		}
	}
	log.Printf("Analyzed %d packages", len(pkgs))
}

type importerFunc func(path string) (*types.Package, error)

func (f importerFunc) Import(path string) (*types.Package, error) {
	return f(path)
}
