// Copyright 2019 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 deepequalerrors defines an Analyzer that checks for the use
// of reflect.DeepEqual with error values.
package deepequalerrors

import (
	"go/ast"
	"go/types"

	"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/go/types/typeutil"
	"golang.org/x/tools/internal/typesinternal"
)

const Doc = `check for calls of reflect.DeepEqual on error values

The deepequalerrors checker looks for calls of the form:

    reflect.DeepEqual(err1, err2)

where err1 and err2 are errors. Using reflect.DeepEqual to compare
errors is discouraged.`

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

func run(pass *analysis.Pass) (any, error) {
	if !typesinternal.Imports(pass.Pkg, "reflect") {
		return nil, nil // doesn't directly import reflect
	}

	inspect := pass.ResultOf[inspect.Analyzer].(*inspector.Inspector)

	nodeFilter := []ast.Node{
		(*ast.CallExpr)(nil),
	}
	inspect.Preorder(nodeFilter, func(n ast.Node) {
		call := n.(*ast.CallExpr)
		obj := typeutil.Callee(pass.TypesInfo, call)
		if typesinternal.IsFunctionNamed(obj, "reflect", "DeepEqual") && hasError(pass, call.Args[0]) && hasError(pass, call.Args[1]) {
			pass.ReportRangef(call, "avoid using reflect.DeepEqual with errors")
		}
	})
	return nil, nil
}

var errorType = types.Universe.Lookup("error").Type().Underlying().(*types.Interface)

// hasError reports whether the type of e contains the type error.
// See containsError, below, for the meaning of "contains".
func hasError(pass *analysis.Pass, e ast.Expr) bool {
	tv, ok := pass.TypesInfo.Types[e]
	if !ok { // no type info, assume good
		return false
	}
	return containsError(tv.Type)
}

// Report whether any type that typ could store and that could be compared is the
// error type. This includes typ itself, as well as the types of struct field, slice
// and array elements, map keys and elements, and pointers. It does not include
// channel types (incomparable), arg and result types of a Signature (not stored), or
// methods of a named or interface type (not stored).
func containsError(typ types.Type) bool {
	// Track types being processed, to avoid infinite recursion.
	// Using types as keys here is OK because we are checking for the identical pointer, not
	// type identity. See analysis/passes/printf/types.go.
	inProgress := make(map[types.Type]bool)

	var check func(t types.Type) bool
	check = func(t types.Type) bool {
		if t == errorType {
			return true
		}
		if inProgress[t] {
			return false
		}
		inProgress[t] = true
		switch t := t.(type) {
		case *types.Pointer:
			return check(t.Elem())
		case *types.Slice:
			return check(t.Elem())
		case *types.Array:
			return check(t.Elem())
		case *types.Map:
			return check(t.Key()) || check(t.Elem())
		case *types.Struct:
			for field := range t.Fields() {
				if check(field.Type()) {
					return true
				}
			}
		case *types.Named, *types.Alias:
			return check(t.Underlying())

		// We list the remaining valid type kinds for completeness.
		case *types.Basic:
		case *types.Chan: // channels store values, but they are not comparable
		case *types.Signature:
		case *types.Tuple: // tuples are only part of signatures
		case *types.Interface:
		}
		return false
	}

	return check(typ)
}
