/*
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.
*/

package warn

import (
	"fmt"
	"strings"

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

var ambiguousNames = map[string]bool{
	"I": true,
	"l": true,
	"O": true,
}

// ambiguousNameCheck checks for the names of idents and functions
func ambiguousNameCheck(expr build.Expr, name string, findings []*LinterFinding) []*LinterFinding {
	if ambiguousNames[name] {
		findings = append(findings,
			makeLinterFinding(expr, `Never use 'l', 'I', or 'O' as names (they're too easily confused with 'I', 'l', or '0').`))
	}
	return findings
}

func confusingNameWarning(f *build.File) []*LinterFinding {
	var findings []*LinterFinding
	// check for global variable names
	for _, ident := range collectLocalVariables(f.Stmt) {
		findings = ambiguousNameCheck(ident, ident.Name, findings)
	}

	build.Walk(f, func(expr build.Expr, stack []build.Expr) {
		switch expr := expr.(type) {
		case *build.DefStmt:
			findings = ambiguousNameCheck(expr, expr.Name, findings)
			for _, param := range expr.Params {
				name, _ := build.GetParamName(param)
				findings = ambiguousNameCheck(param, name, findings)
			}
			for _, ident := range collectLocalVariables(expr.Body) {
				findings = ambiguousNameCheck(ident, ident.Name, findings)
			}
		case *build.Comprehension:
			for _, clause := range expr.Clauses {
				forClause, ok := clause.(*build.ForClause)
				if !ok {
					continue
				}
				for _, ident := range bzlenv.CollectLValues(forClause.Vars) {
					findings = ambiguousNameCheck(ident, ident.Name, findings)
				}
			}
		}
	})

	return findings
}

func isUpperCamelCase(name string) bool {
	if strings.HasPrefix(name, "_") {
		// Private providers are allowed
		name = name[1:]
	}
	return !strings.ContainsRune(name, '_') && name == strings.Title(name)
}

func isLowerSnakeCase(name string) bool {
	return name == strings.ToLower(name)
}

func isUpperSnakeCase(name string) bool {
	return name == strings.ToUpper(name)
}

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

	build.WalkStatements(f, func(stmt build.Expr, stack []build.Expr) (err error) {
		// looking for provider declaration statements: `xxx = provider()`
		// note that the code won't trigger on complex assignments, such as `x, y = foo, provider()`
		binary, ok := stmt.(*build.AssignExpr)
		if !ok {
			return
		}
		for _, ident := range bzlenv.CollectLValues(binary.LHS) {
			if isLowerSnakeCase(ident.Name) || isUpperSnakeCase(ident.Name) {
				continue
			}
			if isUpperCamelCase(ident.Name) && strings.HasSuffix(ident.Name, "Info") {
				continue
			}
			findings = append(findings,
				makeLinterFinding(ident,
					fmt.Sprintf(`Variable name "%s" should be lower_snake_case (for variables), UPPER_SNAKE_CASE (for constants), or UpperCamelCase ending with 'Info' (for providers).`, ident.Name)))
		}
		return
	})

	return findings
}
