/*
Copyright 2020 Google LLC

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    https://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

// Warnings for incompatible changes in the Bazel API

package warn

import (
	"fmt"
	"sort"

	"github.com/bazelbuild/buildtools/build"
	"github.com/bazelbuild/buildtools/bzlenv"
	"github.com/bazelbuild/buildtools/edit"
	"github.com/bazelbuild/buildtools/tables"
)

// Bazel API-specific warnings

// negateExpression returns an expression which is a negation of the input.
// If it's a boolean literal (true or false), just return the opposite literal.
// If it's a unary expression with a unary `not` operator, just remove it.
// Otherwise, insert a `not` operator.
// It's assumed that input is no longer needed as it may be mutated or reused by the function.
func negateExpression(expr build.Expr) build.Expr {
	paren, ok := expr.(*build.ParenExpr)
	if ok {
		newParen := *paren
		newParen.X = negateExpression(paren.X)
		return &newParen
	}

	unary, ok := expr.(*build.UnaryExpr)
	if ok && unary.Op == "not" {
		return unary.X
	}

	boolean, ok := expr.(*build.Ident)
	if ok {
		newBoolean := *boolean
		if boolean.Name == "True" {
			newBoolean.Name = "False"
		} else {
			newBoolean.Name = "True"
		}
		return &newBoolean
	}

	return &build.UnaryExpr{
		Op: "not",
		X:  expr,
	}
}

// getParam search for a param with a given name in a given list of function arguments
// and returns it with its index
func getParam(attrs []build.Expr, paramName string) (int, *build.Ident, *build.AssignExpr) {
	for i, attr := range attrs {
		as, ok := attr.(*build.AssignExpr)
		if !ok {
			continue
		}
		name, ok := (as.LHS).(*build.Ident)
		if !ok || name.Name != paramName {
			continue
		}
		return i, name, as
	}
	return -1, nil, nil
}

// isFunctionCall checks whether expr is a call of a function with a given name
func isFunctionCall(expr build.Expr, name string) (*build.CallExpr, bool) {
	call, ok := expr.(*build.CallExpr)
	if !ok {
		return nil, false
	}
	if ident, ok := call.X.(*build.Ident); ok && ident.Name == name {
		return call, true
	}
	return nil, false
}

// globalVariableUsageCheck checks whether there's a usage of a given global variable in the file.
// It's ok to shadow the name with a local variable and use it.
func globalVariableUsageCheck(f *build.File, global, alternative string) []*LinterFinding {
	var findings []*LinterFinding

	if f.Type != build.TypeBzl {
		return findings
	}

	var walk func(e *build.Expr, env *bzlenv.Environment)
	walk = func(e *build.Expr, env *bzlenv.Environment) {
		defer bzlenv.WalkOnceWithEnvironment(*e, env, walk)

		ident, ok := (*e).(*build.Ident)
		if !ok {
			return
		}
		if ident.Name != global {
			return
		}
		if binding := env.Get(ident.Name); binding != nil {
			return
		}

		// Fix
		newIdent := *ident
		newIdent.Name = alternative

		findings = append(findings, makeLinterFinding(ident,
			fmt.Sprintf(`Global variable %q is deprecated in favor of %q. Please rename it.`, global, alternative),
			LinterReplacement{e, &newIdent}))
	}
	var expr build.Expr = f
	walk(&expr, bzlenv.NewEnvironment())

	return findings
}

// insertLoad returns a *LinterReplacement object representing a replacement required for inserting
// an additional load statement. Returns nil if nothing needs to be changed.
func insertLoad(f *build.File, module string, symbols []string) *LinterReplacement {
	// Try to find an existing load statement
	for i, stmt := range f.Stmt {
		load, ok := stmt.(*build.LoadStmt)
		if !ok || load.Module.Value != module {
			continue
		}

		// Modify an existing load statement
		newLoad := *load
		if !edit.AppendToLoad(&newLoad, symbols, symbols) {
			return nil
		}
		return &LinterReplacement{&(f.Stmt[i]), &newLoad}
	}

	// Need to insert a new load statement. Can't modify the tree here, so just insert a placeholder
	// nil statement and return a replacement for it.
	i := 0
	for i = range f.Stmt {
		stmt := f.Stmt[i]
		_, isComment := stmt.(*build.CommentBlock)
		_, isString := stmt.(*build.StringExpr)
		isDocString := isString && i == 0
		if !isComment && !isDocString {
			// Insert a nil statement here
			break
		}
	}
	stmts := append([]build.Expr{}, f.Stmt[:i]...)
	stmts = append(stmts, nil)
	stmts = append(stmts, f.Stmt[i:]...)
	f.Stmt = stmts

	return &LinterReplacement{&(f.Stmt[i]), edit.NewLoad(module, symbols, symbols)}
}

func notLoadedFunctionUsageCheckInternal(expr *build.Expr, env *bzlenv.Environment, globals []string, loadFrom string) ([]string, []*LinterFinding) {
	var loads []string
	var findings []*LinterFinding

	call, ok := (*expr).(*build.CallExpr)
	if !ok {
		return loads, findings
	}

	var name string
	var replacements []LinterReplacement
	switch node := call.X.(type) {
	case *build.DotExpr:
		// Maybe native.`global`?
		ident, ok := node.X.(*build.Ident)
		if !ok || ident.Name != "native" {
			return loads, findings
		}

		name = node.Name
		// Replace `native.foo()` with `foo()`
		newCall := *call
		newCall.X = &build.Ident{Name: node.Name}
		replacements = append(replacements, LinterReplacement{expr, &newCall})
	case *build.Ident:
		// Maybe `global`()?
		if binding := env.Get(node.Name); binding != nil {
			return loads, findings
		}
		name = node.Name
	default:
		return loads, findings
	}

	for _, global := range globals {
		if name == global {
			loads = append(loads, name)
			findings = append(findings,
				makeLinterFinding(call.X, fmt.Sprintf(`Function %q is not global anymore and needs to be loaded from %q.`, global, loadFrom), replacements...))
			break
		}
	}

	return loads, findings
}

func notLoadedSymbolUsageCheckInternal(expr *build.Expr, env *bzlenv.Environment, globals []string, loadFrom string) ([]string, []*LinterFinding) {
	var loads []string
	var findings []*LinterFinding

	ident, ok := (*expr).(*build.Ident)
	if !ok {
		return loads, findings
	}
	if binding := env.Get(ident.Name); binding != nil {
		return loads, findings
	}

	for _, global := range globals {
		if ident.Name == global {
			loads = append(loads, ident.Name)
			findings = append(findings,
				makeLinterFinding(ident, fmt.Sprintf(`Symbol %q is not global anymore and needs to be loaded from %q.`, global, loadFrom)))
			break
		}
	}

	return loads, findings
}

// notLoadedUsageCheck checks whether there's a usage of a given not imported function or symbol in the file
// and adds a load statement if necessary.
func notLoadedUsageCheck(f *build.File, functions, symbols []string, loadFrom string) []*LinterFinding {
	toLoad := make(map[string]bool)
	var findings []*LinterFinding

	var walk func(expr *build.Expr, env *bzlenv.Environment)
	walk = func(expr *build.Expr, env *bzlenv.Environment) {
		defer bzlenv.WalkOnceWithEnvironment(*expr, env, walk)

		functionLoads, functionFindings := notLoadedFunctionUsageCheckInternal(expr, env, functions, loadFrom)
		findings = append(findings, functionFindings...)
		for _, load := range functionLoads {
			toLoad[load] = true
		}

		symbolLoads, symbolFindings := notLoadedSymbolUsageCheckInternal(expr, env, symbols, loadFrom)
		findings = append(findings, symbolFindings...)
		for _, load := range symbolLoads {
			toLoad[load] = true
		}
	}
	var expr build.Expr = f
	walk(&expr, bzlenv.NewEnvironment())

	if len(toLoad) == 0 {
		return nil
	}

	loads := []string{}
	for l := range toLoad {
		loads = append(loads, l)
	}

	sort.Strings(loads)
	replacement := insertLoad(f, loadFrom, loads)
	if replacement != nil {
		// Add the same replacement to all relevant findings.
		for _, f := range findings {
			f.Replacement = append(f.Replacement, *replacement)
		}
	}

	return findings
}

// NotLoadedFunctionUsageCheck checks whether there's a usage of a given not imported function in the file
// and adds a load statement if necessary.
func NotLoadedFunctionUsageCheck(f *build.File, globals []string, loadFrom string) []*LinterFinding {
	return notLoadedUsageCheck(f, globals, []string{}, loadFrom)
}

// makePositional makes the function argument positional (removes the keyword if it exists)
func makePositional(argument build.Expr) build.Expr {
	if binary, ok := argument.(*build.AssignExpr); ok {
		return binary.RHS
	}
	return argument
}

// makeKeyword makes the function argument keyword (adds or edits the keyword name)
func makeKeyword(argument build.Expr, name string) build.Expr {
	assign, ok := argument.(*build.AssignExpr)
	if !ok {
		return &build.AssignExpr{
			LHS: &build.Ident{Name: name},
			Op:  "=",
			RHS: argument,
		}
	}
	ident, ok := assign.LHS.(*build.Ident)
	if ok && ident.Name == name {
		// Nothing to change
		return argument
	}

	// Technically it's possible that the LHS is not an ident, but that is a syntax error anyway.
	newAssign := *assign
	newAssign.LHS = &build.Ident{Name: name}
	return &newAssign
}

func attrConfigurationWarning(f *build.File) []*LinterFinding {
	if f.Type != build.TypeBzl {
		return nil
	}

	var findings []*LinterFinding
	build.WalkPointers(f, func(expr *build.Expr, stack []build.Expr) {
		// Find nodes that match the following pattern: attr.xxxx(..., cfg = "data", ...) and attr.xxxx(..., cfg = "host", ...)
		call, ok := (*expr).(*build.CallExpr)
		if !ok {
			return
		}
		dot, ok := (call.X).(*build.DotExpr)
		if !ok {
			return
		}
		base, ok := dot.X.(*build.Ident)
		if !ok || base.Name != "attr" {
			return
		}
		i, _, param := getParam(call.List, "cfg")
		if param == nil {
			return
		}
		value, ok := (param.RHS).(*build.StringExpr)
		if !ok {
			return
		}

		newCall := *call
		switch value.Value {
		case "data":
			newCall.List = append(newCall.List[:i], newCall.List[i+1:]...)
			findings = append(findings,
				makeLinterFinding(param, `cfg = "data" for attr definitions has no effect and should be removed.`,
					LinterReplacement{expr, &newCall}))

		case "host":
			{
				newCall.List = append([]build.Expr{}, newCall.List...)
				newParam := newCall.List[i].Copy().(*build.AssignExpr)
				newRHS := newParam.RHS.Copy().(*build.StringExpr)
				newRHS.Value = "exec"
				newParam.RHS = newRHS
				newCall.List[i] = newParam
				findings = append(findings,
					makeLinterFinding(param, `cfg = "host" for attr definitions should be replaced by cfg = "exec".`,
						LinterReplacement{expr, &newCall}))
			}

		default:
			// value not matched.
			return
		}
	})
	return findings
}

func depsetItemsWarning(f *build.File) []*LinterFinding {
	var findings []*LinterFinding

	types := DetectTypes(f)
	build.WalkPointers(f, func(expr *build.Expr, stack []build.Expr) {
		call, ok := (*expr).(*build.CallExpr)
		if !ok {
			return
		}
		base, ok := call.X.(*build.Ident)
		if !ok || base.Name != "depset" {
			return
		}
		if len(call.List) == 0 {
			return
		}
		_, _, param := getParam(call.List, "items")
		if param != nil {
			findings = append(findings,
				makeLinterFinding(param, `Parameter "items" is deprecated, use "direct" and/or "transitive" instead.`))
			return
		}
		if _, ok := call.List[0].(*build.AssignExpr); ok {
			return
		}
		// We have an unnamed first parameter. Check the type.
		if types[call.List[0]] == Depset {
			findings = append(findings,
				makeLinterFinding(call.List[0], `Giving a depset as first unnamed parameter to depset() is deprecated, use the "transitive" parameter instead.`))
		}
	})
	return findings
}

func attrNonEmptyWarning(f *build.File) []*LinterFinding {
	if f.Type != build.TypeBzl {
		return nil
	}

	var findings []*LinterFinding
	build.WalkPointers(f, func(expr *build.Expr, stack []build.Expr) {
		// Find nodes that match the following pattern: attr.xxxx(..., non_empty = ..., ...)
		call, ok := (*expr).(*build.CallExpr)
		if !ok {
			return
		}
		dot, ok := (call.X).(*build.DotExpr)
		if !ok {
			return
		}
		base, ok := dot.X.(*build.Ident)
		if !ok || base.Name != "attr" {
			return
		}
		_, name, param := getParam(call.List, "non_empty")
		if param == nil {
			return
		}

		// Fix
		newName := *name
		newName.Name = "allow_empty"
		negatedRHS := negateExpression(param.RHS)

		findings = append(findings,
			makeLinterFinding(param, "non_empty attributes for attr definitions are deprecated in favor of allow_empty.",
				LinterReplacement{&param.LHS, &newName},
				LinterReplacement{&param.RHS, negatedRHS},
			))
	})
	return findings
}

func attrSingleFileWarning(f *build.File) []*LinterFinding {
	if f.Type != build.TypeBzl {
		return nil
	}

	var findings []*LinterFinding
	build.WalkPointers(f, func(expr *build.Expr, stack []build.Expr) {
		// Find nodes that match the following pattern: attr.xxxx(..., single_file = ..., ...)
		call, ok := (*expr).(*build.CallExpr)
		if !ok {
			return
		}
		dot, ok := (call.X).(*build.DotExpr)
		if !ok {
			return
		}
		base, ok := dot.X.(*build.Ident)
		if !ok || base.Name != "attr" {
			return
		}
		singleFileIndex, singleFileKw, singleFileParam := getParam(call.List, "single_file")
		if singleFileParam == nil {
			return
		}

		// Fix
		newCall := *call
		newCall.List = append([]build.Expr{}, call.List...)

		newSingleFileKw := *singleFileKw
		newSingleFileKw.Name = "allow_single_file"
		singleFileValue := singleFileParam.RHS

		if boolean, ok := singleFileValue.(*build.Ident); ok && boolean.Name == "False" {
			// if the value is `False`, just remove the whole parameter
			newCall.List = append(newCall.List[:singleFileIndex], newCall.List[singleFileIndex+1:]...)
		} else {
			// search for `allow_files` parameter in the same attr definition and remove it
			allowFileIndex, _, allowFilesParam := getParam(call.List, "allow_files")
			if allowFilesParam != nil {
				singleFileValue = allowFilesParam.RHS
				newCall.List = append(newCall.List[:allowFileIndex], newCall.List[allowFileIndex+1:]...)
				if singleFileIndex > allowFileIndex {
					singleFileIndex--
				}
			}
		}
		findings = append(findings,
			makeLinterFinding(singleFileParam, "single_file is deprecated in favor of allow_single_file.",
				LinterReplacement{expr, &newCall},
				LinterReplacement{&singleFileParam.LHS, &newSingleFileKw},
				LinterReplacement{&singleFileParam.RHS, singleFileValue},
			))
	})
	return findings
}

func ctxActionsWarning(f *build.File) []*LinterFinding {
	if f.Type != build.TypeBzl {
		return nil
	}

	var findings []*LinterFinding
	build.WalkPointers(f, func(expr *build.Expr, stack []build.Expr) {
		// Find nodes that match the following pattern: ctx.xxxx(...)
		call, ok := (*expr).(*build.CallExpr)
		if !ok {
			return
		}
		dot, ok := (call.X).(*build.DotExpr)
		if !ok {
			return
		}
		base, ok := dot.X.(*build.Ident)
		if !ok || base.Name != "ctx" {
			return
		}

		switch dot.Name {
		case "new_file", "experimental_new_directory", "file_action", "action", "empty_action", "template_action":
			// fix
		default:
			return
		}

		// Fix
		newCall := *call
		newCall.List = append([]build.Expr{}, call.List...)
		newDot := *dot
		newCall.X = &newDot

		switch dot.Name {
		case "new_file":
			if len(call.List) > 2 {
				// Can't fix automatically because the new API doesn't support the 3 arguments signature
				findings = append(findings,
					makeLinterFinding(dot, fmt.Sprintf(`"ctx.new_file" is deprecated in favor of "ctx.actions.declare_file".`)))
				return
			}
			newDot.Name = "actions.declare_file"
			if len(call.List) == 2 {
				// swap arguments:
				// ctx.new_file(sibling, name) -> ctx.actions.declare_file(name, sibling=sibling)
				newCall.List[0], newCall.List[1] = makePositional(call.List[1]), makeKeyword(call.List[0], "sibling")
			}
		case "experimental_new_directory":
			newDot.Name = "actions.declare_directory"
		case "file_action":
			newDot.Name = "actions.write"
			i, ident, param := getParam(newCall.List, "executable")
			if ident != nil {
				newIdent := *ident
				newIdent.Name = "is_executable"
				newParam := *param
				newParam.LHS = &newIdent
				newCall.List[i] = &newParam
			}
		case "action":
			newDot.Name = "actions.run"
			if _, _, command := getParam(call.List, "command"); command != nil {
				newDot.Name = "actions.run_shell"
			}
		case "empty_action":
			newDot.Name = "actions.do_nothing"
		case "template_action":
			newDot.Name = "actions.expand_template"
			if i, ident, param := getParam(call.List, "executable"); ident != nil {
				newIdent := *ident
				newIdent.Name = "is_executable"
				newParam := *param
				newParam.LHS = &newIdent
				newCall.List[i] = &newParam
			}
		}

		findings = append(findings, makeLinterFinding(dot,
			fmt.Sprintf(`"ctx.%s" is deprecated in favor of "ctx.%s".`, dot.Name, newDot.Name),
			LinterReplacement{expr, &newCall}))
	})
	return findings
}

func fileTypeWarning(f *build.File) []*LinterFinding {
	if f.Type != build.TypeBzl {
		return nil
	}

	var findings []*LinterFinding
	var walk func(e *build.Expr, env *bzlenv.Environment)
	walk = func(e *build.Expr, env *bzlenv.Environment) {
		defer bzlenv.WalkOnceWithEnvironment(*e, env, walk)

		call, ok := isFunctionCall(*e, "FileType")
		if !ok {
			return
		}
		if binding := env.Get("FileType"); binding == nil {
			findings = append(findings,
				makeLinterFinding(call, "The FileType function is deprecated."))
		}
	}
	var expr build.Expr = f
	walk(&expr, bzlenv.NewEnvironment())

	return findings
}

func packageNameWarning(f *build.File) []*LinterFinding {
	return globalVariableUsageCheck(f, "PACKAGE_NAME", "native.package_name()")
}

func repositoryNameWarning(f *build.File) []*LinterFinding {
	return globalVariableUsageCheck(f, "REPOSITORY_NAME", "native.repository_name()")
}

func outputGroupWarning(f *build.File) []*LinterFinding {
	if f.Type != build.TypeBzl {
		return nil
	}

	var findings []*LinterFinding
	build.WalkPointers(f, func(expr *build.Expr, stack []build.Expr) {
		// Find nodes that match the following pattern: ctx.attr.xxx.output_group
		outputGroup, ok := (*expr).(*build.DotExpr)
		if !ok || outputGroup.Name != "output_group" {
			return
		}
		dep, ok := (outputGroup.X).(*build.DotExpr)
		if !ok {
			return
		}
		attr, ok := (dep.X).(*build.DotExpr)
		if !ok || attr.Name != "attr" {
			return
		}
		ctx, ok := (attr.X).(*build.Ident)
		if !ok || ctx.Name != "ctx" {
			return
		}

		// Replace `xxx.output_group` with `xxx[OutputGroupInfo]`
		findings = append(findings,
			makeLinterFinding(outputGroup,
				`"ctx.attr.dep.output_group" is deprecated in favor of "ctx.attr.dep[OutputGroupInfo]".`,
				LinterReplacement{expr, &build.IndexExpr{
					X: dep,
					Y: &build.Ident{Name: "OutputGroupInfo"},
				},
				}))
	})
	return findings
}

func nativeGitRepositoryWarning(f *build.File) []*LinterFinding {
	if f.Type != build.TypeBzl {
		return nil
	}
	return NotLoadedFunctionUsageCheck(f, []string{"git_repository", "new_git_repository"}, "@bazel_tools//tools/build_defs/repo:git.bzl")
}

func nativeHTTPArchiveWarning(f *build.File) []*LinterFinding {
	if f.Type != build.TypeBzl {
		return nil
	}
	return NotLoadedFunctionUsageCheck(f, []string{"http_archive"}, "@bazel_tools//tools/build_defs/repo:http.bzl")
}

func nativeAndroidRulesWarning(f *build.File) []*LinterFinding {
	if f.Type != build.TypeBzl && f.Type != build.TypeBuild {
		return nil
	}
	return NotLoadedFunctionUsageCheck(f, tables.AndroidNativeRules, tables.AndroidLoadPath)
}

func nativeCcRulesWarning(f *build.File) []*LinterFinding {
	if f.Type != build.TypeBzl && f.Type != build.TypeBuild {
		return nil
	}
	return NotLoadedFunctionUsageCheck(f, tables.CcNativeRules, tables.CcLoadPath)
}

func nativeJavaRulesWarning(f *build.File) []*LinterFinding {
	if f.Type != build.TypeBzl && f.Type != build.TypeBuild {
		return nil
	}
	return NotLoadedFunctionUsageCheck(f, tables.JavaNativeRules, tables.JavaLoadPath)
}

func nativePyRulesWarning(f *build.File) []*LinterFinding {
	if f.Type != build.TypeBzl && f.Type != build.TypeBuild {
		return nil
	}
	return NotLoadedFunctionUsageCheck(f, tables.PyNativeRules, tables.PyLoadPath)
}

func nativeProtoRulesWarning(f *build.File) []*LinterFinding {
	if f.Type != build.TypeBzl && f.Type != build.TypeBuild {
		return nil
	}
	return notLoadedUsageCheck(f, tables.ProtoNativeRules, tables.ProtoNativeSymbols, tables.ProtoLoadPath)
}

func contextArgsAPIWarning(f *build.File) []*LinterFinding {
	if f.Type != build.TypeBzl {
		return nil
	}

	var findings []*LinterFinding
	types := DetectTypes(f)

	build.WalkPointers(f, func(expr *build.Expr, stack []build.Expr) {
		// Search for `<ctx.actions.args>.add()` nodes
		call, ok := (*expr).(*build.CallExpr)
		if !ok {
			return
		}
		dot, ok := call.X.(*build.DotExpr)
		if !ok || dot.Name != "add" || types[dot.X] != CtxActionsArgs {
			return
		}

		// If neither before_each nor join_with nor map_fn is specified, the node is ok.
		// Otherwise if join_with is specified, use `.add_joined` instead.
		// Otherwise use `.add_all` instead.

		_, beforeEachKw, beforeEach := getParam(call.List, "before_each")
		_, _, joinWith := getParam(call.List, "join_with")
		_, mapFnKw, mapFn := getParam(call.List, "map_fn")
		if beforeEach == nil && joinWith == nil && mapFn == nil {
			// No deprecated API detected
			return
		}

		// Fix
		var replacements []LinterReplacement

		newDot := *dot
		newDot.Name = "add_all"
		replacements = append(replacements, LinterReplacement{&call.X, &newDot})

		if joinWith != nil {
			newDot.Name = "add_joined"
			if beforeEach != nil {
				// `add_joined` doesn't have a `before_each` parameter, replace it with `format_each`:
				// `before_each = foo` -> `format_each = foo + "%s"`
				newBeforeEachKw := *beforeEachKw
				newBeforeEachKw.Name = "format_each"

				replacements = append(replacements, LinterReplacement{&beforeEach.LHS, &newBeforeEachKw})
				replacements = append(replacements, LinterReplacement{&beforeEach.RHS, &build.BinaryExpr{
					X:  beforeEach.RHS,
					Op: "+",
					Y:  &build.StringExpr{Value: "%s"},
				}})
			}
		}
		if mapFnKw != nil {
			// Replace `map_fn = ...` with `map_each = ...`
			newMapFnKw := *mapFnKw
			newMapFnKw.Name = "map_each"
			replacements = append(replacements, LinterReplacement{&mapFn.LHS, &newMapFnKw})
		}

		findings = append(findings,
			makeLinterFinding(call,
				`"ctx.actions.args().add()" for multiple arguments is deprecated in favor of "add_all()" or "add_joined()".`,
				replacements...))

	})
	return findings
}

func attrOutputDefaultWarning(f *build.File) []*LinterFinding {
	if f.Type != build.TypeBzl {
		return nil
	}

	var findings []*LinterFinding
	build.Walk(f, func(expr build.Expr, stack []build.Expr) {
		// Find nodes that match the following pattern: attr.output(..., default = ...)
		call, ok := expr.(*build.CallExpr)
		if !ok {
			return
		}
		dot, ok := (call.X).(*build.DotExpr)
		if !ok || dot.Name != "output" {
			return
		}
		base, ok := dot.X.(*build.Ident)
		if !ok || base.Name != "attr" {
			return
		}
		_, _, param := getParam(call.List, "default")
		if param == nil {
			return
		}
		findings = append(findings,
			makeLinterFinding(param, `The "default" parameter for attr.output() is deprecated.`))
	})
	return findings
}

func attrLicenseWarning(f *build.File) []*LinterFinding {
	if f.Type != build.TypeBzl {
		return nil
	}

	var findings []*LinterFinding
	build.Walk(f, func(expr build.Expr, stack []build.Expr) {
		// Find nodes that match the following pattern: attr.license(...)
		call, ok := expr.(*build.CallExpr)
		if !ok {
			return
		}
		dot, ok := (call.X).(*build.DotExpr)
		if !ok || dot.Name != "license" {
			return
		}
		base, ok := dot.X.(*build.Ident)
		if !ok || base.Name != "attr" {
			return
		}
		findings = append(findings,
			makeLinterFinding(expr, `"attr.license()" is deprecated and shouldn't be used.`))
	})
	return findings
}

// ruleImplReturnWarning checks whether a rule implementation function returns an old-style struct
func ruleImplReturnWarning(f *build.File) []*LinterFinding {
	if f.Type != build.TypeBzl {
		return nil
	}

	var findings []*LinterFinding

	// iterate over rules and collect rule implementation function names
	implNames := make(map[string]bool)
	build.Walk(f, func(expr build.Expr, stack []build.Expr) {
		call, ok := isFunctionCall(expr, "rule")
		if !ok {
			return
		}

		// Try to get the implementaton parameter either by name or as the first argument
		var impl build.Expr
		_, _, param := getParam(call.List, "implementation")
		if param != nil {
			impl = param.RHS
		} else if len(call.List) > 0 {
			impl = call.List[0]
		}
		if name, ok := impl.(*build.Ident); ok {
			implNames[name.Name] = true
		}
	})

	// iterate over functions
	for _, stmt := range f.Stmt {
		def, ok := stmt.(*build.DefStmt)
		if !ok || !implNames[def.Name] {
			// either not a function or not used in the file as a rule implementation function
			continue
		}
		// traverse the function and find all of its return statements
		build.Walk(def, func(expr build.Expr, stack []build.Expr) {
			ret, ok := expr.(*build.ReturnStmt)
			if !ok {
				return
			}
			// check whether it returns a struct
			if _, ok := isFunctionCall(ret.Result, "struct"); ok {
				findings = append(findings, makeLinterFinding(ret, `Avoid using the legacy provider syntax.`))
			}
		})
	}

	return findings
}

type signature struct {
	Positional []string // These parameters are typePositional-only
	Keyword    []string // These parameters are typeKeyword-only
}

var signatures = map[string]signature{
	"all":     {[]string{"elements"}, []string{}},
	"any":     {[]string{"elements"}, []string{}},
	"tuple":   {[]string{"x"}, []string{}},
	"list":    {[]string{"x"}, []string{}},
	"len":     {[]string{"x"}, []string{}},
	"str":     {[]string{"x"}, []string{}},
	"repr":    {[]string{"x"}, []string{}},
	"bool":    {[]string{"x"}, []string{}},
	"int":     {[]string{"x"}, []string{}},
	"dir":     {[]string{"x"}, []string{}},
	"type":    {[]string{"x"}, []string{}},
	"hasattr": {[]string{"x", "name"}, []string{}},
	"getattr": {[]string{"x", "name", "default"}, []string{}},
	"select":  {[]string{"x"}, []string{}},
}

// functionName returns the name of the given function if it's a direct function call (e.g.
// `foo(...)` or `native.foo(...)`, but not `foo.bar(...)` or `x[3](...)`
func functionName(call *build.CallExpr) (string, bool) {
	if ident, ok := call.X.(*build.Ident); ok {
		return ident.Name, true
	}
	// Also check for `native.<name>`
	dot, ok := call.X.(*build.DotExpr)
	if !ok {
		return "", false
	}
	if ident, ok := dot.X.(*build.Ident); !ok || ident.Name != "native" {
		return "", false
	}
	return dot.Name, true
}

const (
	typePositional int = iota
	typeKeyword
	typeArgs
	typeKwargs
)

// paramType returns the type of the param. If it's a typeKeyword param, also returns its name
func paramType(param build.Expr) (int, string) {
	switch param := param.(type) {
	case *build.AssignExpr:
		if param.Op == "=" {
			ident, ok := param.LHS.(*build.Ident)
			if ok {
				return typeKeyword, ident.Name
			}
			return typeKeyword, ""
		}
	case *build.UnaryExpr:
		switch param.Op {
		case "*":
			return typeArgs, ""
		case "**":
			return typeKwargs, ""
		}
	}
	return typePositional, ""
}

// keywordPositionalParametersWarning checks for deprecated typeKeyword parameters of builtins
func keywordPositionalParametersWarning(f *build.File) []*LinterFinding {
	var findings []*LinterFinding

	// Check for legacy typeKeyword parameters
	build.WalkPointers(f, func(expr *build.Expr, stack []build.Expr) {
		call, ok := (*expr).(*build.CallExpr)
		if !ok || len(call.List) == 0 {
			return
		}
		function, ok := functionName(call)
		if !ok {
			return
		}

		// Findings and replacements for the current call expression
		var callFindings []*LinterFinding
		var callReplacements []LinterReplacement

		signature, ok := signatures[function]
		if !ok {
			return
		}

		var paramTypes []int // types of the parameters (typeKeyword or not) after the replacements has been applied.
		for i, parameter := range call.List {
			pType, name := paramType(parameter)
			paramTypes = append(paramTypes, pType)

			if pType == typeKeyword && i < len(signature.Positional) && signature.Positional[i] == name {
				// The parameter should be typePositional
				callFindings = append(callFindings, makeLinterFinding(
					parameter,
					fmt.Sprintf(`Keyword parameter %q for %q should be positional.`, signature.Positional[i], function),
				))
				callReplacements = append(callReplacements, LinterReplacement{&call.List[i], makePositional(parameter)})
				paramTypes[i] = typePositional
			}

			if pType == typePositional && i >= len(signature.Positional) && i < len(signature.Positional)+len(signature.Keyword) {
				// The parameter should be typeKeyword
				keyword := signature.Keyword[i-len(signature.Positional)]
				callFindings = append(callFindings, makeLinterFinding(
					parameter,
					fmt.Sprintf(`Parameter at the position %d for %q should be keyword (%s = ...).`, i+1, function, keyword),
				))
				callReplacements = append(callReplacements, LinterReplacement{&call.List[i], makeKeyword(parameter, keyword)})
				paramTypes[i] = typeKeyword
			}
		}

		if len(callFindings) == 0 {
			return
		}

		// Only apply the replacements if the signature is correct after they have been applied
		// (i.e. the order of the parameters is typePositional, typeKeyword, typeArgs, typeKwargs)
		// Otherwise the signature will be not correct, probably it was incorrect initially.
		// All the replacements should be applied to the first finding for the current node.

		if sort.IntsAreSorted(paramTypes) {
			// It's possible that the parameter list had `ForceCompact` set to true because it only contained
			// positional arguments, and now it has keyword arguments as well. Reset the flag to let the
			// printer decide how the function call should be formatted.
			for _, t := range paramTypes {
				if t == typeKeyword {
					// There's at least one keyword argument
					newCall := *call
					newCall.ForceCompact = false
					callFindings[0].Replacement = append(callFindings[0].Replacement, LinterReplacement{expr, &newCall})
					break
				}
			}
			// Attach all the parameter replacements to the first finding
			callFindings[0].Replacement = append(callFindings[0].Replacement, callReplacements...)
		}

		findings = append(findings, callFindings...)
	})

	return findings
}

func providerParamsWarning(f *build.File) []*LinterFinding {
	if f.Type != build.TypeBzl {
		return nil
	}

	var findings []*LinterFinding
	build.Walk(f, func(expr build.Expr, stack []build.Expr) {
		call, ok := isFunctionCall(expr, "provider")
		if !ok {
			return
		}

		_, _, fields := getParam(call.List, "fields")
		_, _, doc := getParam(call.List, "doc")
		// doc can also be the first positional argument
		hasPositional := false
		if len(call.List) > 0 {
			if _, ok := call.List[0].(*build.AssignExpr); !ok {
				hasPositional = true
			}
		}
		msg := ""
		if fields == nil {
			msg = "a list of fields"
		}
		if doc == nil && !hasPositional {
			if msg != "" {
				msg += " and "
			}
			msg += "a documentation"
		}
		if msg != "" {
			findings = append(findings, makeLinterFinding(call,
				`Calls to 'provider' should provide `+msg+`:\n`+
					`  provider("description", fields = [...])`))
		}
	})
	return findings
}


func attrNameWarning(f *build.File, names []string) []*LinterFinding {
	if f.Type != build.TypeBzl {
		return nil
	}

	var findings []*LinterFinding
	build.WalkPointers(f, func(expr *build.Expr, stack []build.Expr) {
		// Find nodes that match "attrs = {..., "license", ...}"
		dict, ok := (*expr).(*build.DictExpr)
		if !ok {
			return
		}
		for _, item := range dict.List {
			// include only string literal keys into consideration
			value, ok := item.Key.(*build.StringExpr)
			if !ok {
				continue
			}
			for _, name := range names {
				if value.Value == name {
					findings = append(findings, makeLinterFinding(dict,
						fmt.Sprintf(`Do not use '%s' as an attribute name.`+
							` It may cause unexpected behavior.`, value.Value)))

				}
			}
		}
	})
	return findings
}

func attrLicensesWarning(f *build.File) []*LinterFinding {
	return attrNameWarning(f, []string{"licenses"})
}

func attrApplicableLicensesWarning(f *build.File) []*LinterFinding {
	return attrNameWarning(f, []string{"applicable_licenses", "package_metadata"})
}
