// Copyright 2021 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 safetoken_test

import (
	"fmt"
	"go/parser"
	"go/token"
	"go/types"
	"os"
	"testing"

	"golang.org/x/tools/go/packages"
	"golang.org/x/tools/gopls/internal/util/safetoken"
	"golang.org/x/tools/internal/testenv"
)

func TestWorkaroundIssue57490(t *testing.T) {
	// During error recovery the parser synthesizes various close
	// tokens at EOF, causing the End position of incomplete
	// syntax nodes, computed as Rbrace+len("}"), to be beyond EOF.
	src := `package p; func f() { var x struct`
	fset := token.NewFileSet()
	file, _ := parser.ParseFile(fset, "a.go", src, 0)
	tf := fset.File(file.Pos())

	// Add another file to the FileSet.
	file2, _ := parser.ParseFile(fset, "b.go", "package q", 0)

	// This is the ambiguity of #57490...
	if file.End() != file2.Pos() {
		t.Errorf("file.End() %d != %d file2.Pos()", file.End(), file2.Pos())
	}
	// ...which causes these statements to panic.
	if false {
		tf.Offset(file.End())   // panic: invalid Pos value 36 (should be in [1, 35])
		tf.Position(file.End()) // panic: invalid Pos value 36 (should be in [1, 35])
	}

	// The offset of the EOF position is the file size.
	offset, err := safetoken.Offset(tf, file.End()-1)
	if err != nil || offset != tf.Size() {
		t.Errorf("Offset(EOF) = (%d, %v), want token.File.Size %d", offset, err, tf.Size())
	}

	// The offset of the file.End() position, 1 byte beyond EOF,
	// is also the size of the file.
	offset, err = safetoken.Offset(tf, file.End())
	if err != nil || offset != tf.Size() {
		t.Errorf("Offset(ast.File.End()) = (%d, %v), want token.File.Size %d", offset, err, tf.Size())
	}

	if got, want := safetoken.Position(tf, file.End()).String(), "a.go:1:35"; got != want {
		t.Errorf("Position(ast.File.End()) = %s, want %s", got, want)
	}

	if got, want := safetoken.EndPosition(fset, file.End()).String(), "a.go:1:35"; got != want {
		t.Errorf("EndPosition(ast.File.End()) = %s, want %s", got, want)
	}

	// Note that calling StartPosition on an end may yield the wrong file:
	if got, want := safetoken.StartPosition(fset, file.End()).String(), "b.go:1:1"; got != want {
		t.Errorf("StartPosition(ast.File.End()) = %s, want %s", got, want)
	}
}

// To reduce the risk of panic, or bugs for which this package
// provides a workaround, this test statically reports references to
// forbidden methods of token.File or FileSet throughout gopls and
// suggests alternatives.
func TestGoplsSourceDoesNotCallTokenFileMethods(t *testing.T) {
	testenv.NeedsGoPackages(t)
	testenv.NeedsLocalXTools(t)

	cfg := &packages.Config{
		Mode: packages.NeedName | packages.NeedModule | packages.NeedCompiledGoFiles | packages.NeedTypes | packages.NeedTypesInfo | packages.NeedSyntax | packages.NeedImports | packages.NeedDeps,
	}
	cfg.Env = os.Environ()
	cfg.Env = append(cfg.Env,
		"GOPACKAGESDRIVER=off",
		"GOWORK=off", // necessary for -mod=mod below
		"GOFLAGS=-mod=mod",
	)

	pkgs, err := packages.Load(cfg, "go/token", "golang.org/x/tools/gopls/...")
	if err != nil {
		t.Fatal(err)
	}
	var tokenPkg *packages.Package
	for _, pkg := range pkgs {
		if pkg.PkgPath == "go/token" {
			tokenPkg = pkg
			break
		}
	}
	if tokenPkg == nil {
		t.Fatal("missing package go/token")
	}

	File := tokenPkg.Types.Scope().Lookup("File")
	FileSet := tokenPkg.Types.Scope().Lookup("FileSet")

	alternative := make(map[types.Object]string)
	setAlternative := func(recv types.Object, old, new string) {
		oldMethod, _, _ := types.LookupFieldOrMethod(recv.Type(), true, recv.Pkg(), old)
		alternative[oldMethod] = new
	}
	setAlternative(File, "Line", "safetoken.Line")
	setAlternative(File, "Offset", "safetoken.Offset")
	setAlternative(File, "Position", "safetoken.Position")
	setAlternative(File, "PositionFor", "safetoken.Position")
	setAlternative(FileSet, "Position", "safetoken.StartPosition or EndPosition")
	setAlternative(FileSet, "PositionFor", "safetoken.StartPosition or EndPosition")

	for _, pkg := range pkgs {
		switch pkg.PkgPath {
		case "go/token", "golang.org/x/tools/gopls/internal/util/safetoken":
			continue // allow calls within these packages
		}

		for ident, obj := range pkg.TypesInfo.Uses {
			if alt, ok := alternative[obj]; ok {
				posn := safetoken.StartPosition(pkg.Fset, ident.Pos())
				fmt.Fprintf(os.Stderr, "%s: forbidden use of %v; use %s instead.\n", posn, obj, alt)
				t.Fail()
			}
		}
	}
}
