// Copyright 2024 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 stdversion reports uses of standard library symbols that are
// "too new" for the Go version in force in the referring file.
package stdversion

import (
	"go/ast"
	"go/build"
	"go/types"
	"regexp"

	"golang.org/x/tools/go/analysis"
	"golang.org/x/tools/go/analysis/passes/inspect"
	"golang.org/x/tools/go/ast/inspector"
	"golang.org/x/tools/internal/typesinternal"
	"golang.org/x/tools/internal/versions"
)

const Doc = `report uses of too-new standard library symbols

The stdversion analyzer reports references to symbols in the standard
library that were introduced by a Go release higher than the one in
force in the referring file. (Recall that the file's Go version is
defined by the 'go' directive its module's go.mod file, or by a
"//go:build go1.X" build tag at the top of the file.)

The analyzer does not report a diagnostic for a reference to a "too
new" field or method of a type that is itself "too new", as this may
have false positives, for example if fields or methods are accessed
through a type alias that is guarded by a Go version constraint.
`

var Analyzer = &analysis.Analyzer{
	Name:             "stdversion",
	Doc:              Doc,
	Requires:         []*analysis.Analyzer{inspect.Analyzer},
	URL:              "https://pkg.go.dev/golang.org/x/tools/go/analysis/passes/stdversion",
	RunDespiteErrors: true,
	Run:              run,
}

func run(pass *analysis.Pass) (any, error) {
	// Prior to go1.22, versions.FileVersion returns only the
	// toolchain version, which is of no use to us, so
	// disable this analyzer on earlier versions.
	if !slicesContains(build.Default.ReleaseTags, "go1.22") {
		return nil, nil
	}

	// Don't report diagnostics for modules marked before go1.21,
	// since at that time the go directive wasn't clearly
	// specified as a toolchain requirement.
	//
	// TODO(adonovan): after go1.21, call GoVersion directly.
	pkgVersion := any(pass.Pkg).(interface{ GoVersion() string }).GoVersion()
	if !versions.AtLeast(pkgVersion, "go1.21") {
		return nil, nil
	}

	// disallowedSymbols returns the set of standard library symbols
	// in a given package that are disallowed at the specified Go version.
	type key struct {
		pkg     *types.Package
		version string
	}
	memo := make(map[key]map[types.Object]string) // records symbol's minimum Go version
	disallowedSymbols := func(pkg *types.Package, version string) map[types.Object]string {
		k := key{pkg, version}
		disallowed, ok := memo[k]
		if !ok {
			disallowed = typesinternal.TooNewStdSymbols(pkg, version)
			memo[k] = disallowed
		}
		return disallowed
	}

	// Scan the syntax looking for references to symbols
	// that are disallowed by the version of the file.
	inspect := pass.ResultOf[inspect.Analyzer].(*inspector.Inspector)
	nodeFilter := []ast.Node{
		(*ast.File)(nil),
		(*ast.Ident)(nil),
	}
	var fileVersion string // "" => no check
	inspect.Preorder(nodeFilter, func(n ast.Node) {
		switch n := n.(type) {
		case *ast.File:
			if isGenerated(n) {
				// Suppress diagnostics in generated files (such as cgo).
				fileVersion = ""
			} else {
				fileVersion = versions.Lang(versions.FileVersion(pass.TypesInfo, n))
				// (may be "" if unknown)
			}

		case *ast.Ident:
			if fileVersion != "" {
				if obj, ok := pass.TypesInfo.Uses[n]; ok && obj.Pkg() != nil {
					disallowed := disallowedSymbols(obj.Pkg(), fileVersion)
					if minVersion, ok := disallowed[origin(obj)]; ok {
						noun := "module"
						if fileVersion != pkgVersion {
							noun = "file"
						}
						pass.ReportRangef(n, "%s.%s requires %v or later (%s is %s)",
							obj.Pkg().Name(), obj.Name(), minVersion, noun, fileVersion)
					}
				}
			}
		}
	})
	return nil, nil
}

// Reduced from x/tools/gopls/internal/golang/util.go. Good enough for now.
// TODO(adonovan): use ast.IsGenerated in go1.21.
func isGenerated(f *ast.File) bool {
	for _, group := range f.Comments {
		for _, comment := range group.List {
			if matched := generatedRx.MatchString(comment.Text); matched {
				return true
			}
		}
	}
	return false
}

// Matches cgo generated comment as well as the proposed standard:
//
//	https://golang.org/s/generatedcode
var generatedRx = regexp.MustCompile(`// .*DO NOT EDIT\.?`)

// origin returns the original uninstantiated symbol for obj.
func origin(obj types.Object) types.Object {
	switch obj := obj.(type) {
	case *types.Var:
		return obj.Origin()
	case *types.Func:
		return obj.Origin()
	case *types.TypeName:
		if named, ok := obj.Type().(*types.Named); ok { // (don't unalias)
			return named.Origin().Obj()
		}
	}
	return obj
}

// TODO(adonovan): use go1.21 slices.Contains.
func slicesContains[S ~[]E, E comparable](slice S, x E) bool {
	for _, elem := range slice {
		if elem == x {
			return true
		}
	}
	return false
}
