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

// Rewriting of high-level (not purely syntactic) BUILD constructs.

package build

import (
	"path"
	"path/filepath"
	"regexp"
	"sort"
	"strings"

	"github.com/bazel-contrib/buildtools/v10/labels"
	"github.com/bazel-contrib/buildtools/v10/tables"
)

// DisableRewrites disables certain rewrites (for debugging).
var DisableRewrites []string

// disabled reports whether the named rewrite is disabled.
func disabled(name string) bool {
	for _, x := range DisableRewrites {
		if name == x {
			return true
		}
	}
	return false
}

// AllowSort allows sorting of these lists even with sorting otherwise disabled (for debugging).
var AllowSort []string

// allowedSort reports whether sorting is allowed in the named context.
func allowedSort(name string) bool {
	for _, x := range AllowSort {
		if name == x {
			return true
		}
	}
	return false
}

// Rewriter controls the rewrites to be applied.
//
// If non-nil, the rewrites with the specified names will be run. If
// nil, a default set of rewrites will be used that is determined by
// the type (BUILD vs default starlark) of the file being rewritten.
type Rewriter struct {
	RewriteSet                      []string
	IsLabelArg                      map[string]bool
	LabelDenyList                   map[string]bool
	IsSortableListArg               map[string]bool
	SortableDenylist                map[string]bool
	SortableAllowlist               map[string]bool
	NamePriority                    map[string]int
	StripLabelLeadingSlashes        bool
	ShortenAbsoluteLabelsToRelative bool
}

// Rewrite applies rewrites to a file
func Rewrite(f *File) {
	var rewriter = &Rewriter{
		IsLabelArg:                      tables.IsLabelArg,
		LabelDenyList:                   tables.LabelDenylist,
		IsSortableListArg:               tables.IsSortableListArg,
		SortableDenylist:                tables.SortableDenylist,
		SortableAllowlist:               tables.SortableAllowlist,
		NamePriority:                    tables.NamePriority,
		StripLabelLeadingSlashes:        tables.StripLabelLeadingSlashes,
		ShortenAbsoluteLabelsToRelative: tables.ShortenAbsoluteLabelsToRelative,
	}
	rewriter.Rewrite(f)
}

// Rewrite applies the rewrites to a file
func (w *Rewriter) Rewrite(f *File) {
	for _, r := range rewrites {
		// f.Type&r.scope is a bitwise comparison. Because starlark files result in a scope that will
		// not be changed by rewrites, we have included another check looking on the right side.
		// If we have an empty rewrite set, we do not want any rewrites to happen.
		if (!disabled(r.name) && (f.Type&r.scope != 0) && w.RewriteSet == nil) || (w.RewriteSet != nil && rewriteSetContains(w, r.name)) {
			r.fn(f, w)
		}
	}
}

func rewriteSetContains(w *Rewriter, name string) bool {
	for _, value := range w.RewriteSet {
		if value == name {
			return true
		}
	}
	return false
}

// Each rewrite function can be either applied for BUILD files, other files (such as .bzl),
// or all files.
const (
	scopeDefault = TypeDefault | TypeBzl                                          // .bzl and generic Starlark files
	scopeBuild   = TypeBuild | TypeWorkspace | TypeModule | TypeRepo | TypeVendor // BUILD, WORKSPACE, MODULE, REPO, and VENDOR files
	scopeBoth    = scopeDefault | scopeBuild
)

// rewrites is the list of all Buildifier rewrites, in the order in which they are applied.
// The order here matters: for example, label canonicalization must happen
// before sorting lists of strings.
var rewrites = []struct {
	name  string
	fn    func(*File, *Rewriter)
	scope FileType
}{
	{"removeParens", removeParens, scopeBuild},
	{"callsort", sortCallArgs, scopeBuild},
	{"label", fixLabels, scopeBuild},
	{"listsort", sortStringLists, scopeBoth},
	{"multiplus", fixMultilinePlus, scopeBuild},
	{"loadTop", moveLoadOnTop, scopeBoth},
	{"sameOriginLoad", compressSameOriginLoads, scopeBoth},
	{"sortLoadStatements", sortLoadStatements, scopeBoth},
	{"loadsort", sortAllLoadArgs, scopeBoth},
	{"useRepoPositionalsSort", sortUseRepoPositionals, TypeModule},
	{"formatdocstrings", formatDocstrings, scopeBoth},
	{"reorderarguments", reorderArguments, scopeBoth},
	{"editoctal", editOctals, scopeBoth},
	{"editfloat", editFloats, scopeBoth},
	{"collapseEmpty", collapseEmpty, scopeBoth},
}

// leaveAlone reports whether any of the nodes on the stack are marked
// with a comment containing "buildifier: leave-alone".
func leaveAlone(stk []Expr, final Expr) bool {
	for _, x := range stk {
		if leaveAlone1(x) {
			return true
		}
	}
	if final != nil && leaveAlone1(final) {
		return true
	}
	return false
}

// hasComment reports whether x is marked with a comment that
// after being converted to lower case, contains the specified text.
func hasComment(x Expr, text string) bool {
	if x == nil {
		return false
	}
	for _, com := range x.Comment().Before {
		if strings.Contains(strings.ToLower(com.Token), text) {
			return true
		}
	}
	for _, com := range x.Comment().After {
		if strings.Contains(strings.ToLower(com.Token), text) {
			return true
		}
	}
	for _, com := range x.Comment().Suffix {
		if strings.Contains(strings.ToLower(com.Token), text) {
			return true
		}
	}
	return false
}

// isCommentAnywhere checks whether there's a comment containing the given text
// anywhere in the file.
func isCommentAnywhere(f *File, text string) bool {
	commentExists := false
	WalkInterruptable(f, func(node Expr, stack []Expr) (err error) {
		if hasComment(node, text) {
			commentExists = true
			return &StopTraversalError{}
		}
		return nil
	})
	return commentExists
}

// leaveAlone1 reports whether x is marked with a comment containing
// "buildifier: leave-alone", case-insensitive.
func leaveAlone1(x Expr) bool {
	return hasComment(x, "buildifier: leave-alone")
}

// doNotSort reports whether x is marked with a comment containing
// "do not sort", case-insensitive.
func doNotSort(x Expr) bool {
	return hasComment(x, "do not sort")
}

// keepSorted reports whether x is marked with a comment containing
// "keep sorted", case-insensitive.
func keepSorted(x Expr) bool {
	return hasComment(x, "keep sorted")
}

// labelRE matches label strings, e.g. @r//x/y/z:abc
// where $1 is @r//x/y/z, $2 is @r//, $3 is r, $4 is z, $5 is abc.
func makeLabelRe(labelPrefix string) *regexp.Regexp {
	return regexp.MustCompile(`^(((?:@(\w+))?//|` + labelPrefix + `)(?:.+/)?([^:]*))(?::([^:]+))?$`)
}

var leadingSlashesLabelRe = makeLabelRe("//")
var stripLeadingSlashesLabelRe = makeLabelRe("")

// fixLabels rewrites labels into a canonical form.
//
// First, it joins labels written as string addition, turning
// "//x" + ":y" (usually split across multiple lines) into "//x:y".
//
// Second, it removes redundant target qualifiers, turning labels like
// "//third_party/m4:m4" into "//third_party/m4" as well as ones like
// "@foo//:foo" into "@foo".
func fixLabels(f *File, w *Rewriter) {
	joinLabel := func(p *Expr) {
		add, ok := (*p).(*BinaryExpr)
		if !ok || add.Op != "+" {
			return
		}
		str1, ok := add.X.(*StringExpr)
		if !ok || !strings.HasPrefix(str1.Value, "//") || strings.Contains(str1.Value, " ") {
			return
		}
		str2, ok := add.Y.(*StringExpr)
		if !ok || strings.Contains(str2.Value, " ") {
			return
		}
		str1.Value += str2.Value

		// Deleting nodes add and str2.
		// Merge comments from add, str1, and str2 and save in str1.
		com1 := add.Comment()
		com2 := str1.Comment()
		com3 := str2.Comment()
		com1.Before = append(com1.Before, com2.Before...)
		com1.Before = append(com1.Before, com3.Before...)
		com1.Suffix = append(com1.Suffix, com2.Suffix...)
		com1.Suffix = append(com1.Suffix, com3.Suffix...)
		*str1.Comment() = *com1

		*p = str1
	}

	labelPrefix := "//"
	labelRE := leadingSlashesLabelRe
	if w.StripLabelLeadingSlashes {
		labelPrefix = ""
		labelRE = stripLeadingSlashesLabelRe
	}

	shortenLabel := func(v Expr) {
		str, ok := v.(*StringExpr)
		if !ok {
			return
		}

		if w.StripLabelLeadingSlashes && strings.HasPrefix(str.Value, "//") {
			if filepath.Dir(f.Path) == "." || !strings.HasPrefix(str.Value, "//:") {
				str.Value = str.Value[2:]
			}
		}
		if w.ShortenAbsoluteLabelsToRelative {
			thisPackage := labelPrefix + filepath.Dir(f.Path)
			// filepath.Dir on Windows uses backslashes as separators, while labels always have slashes.
			if filepath.Separator != '/' {
				thisPackage = strings.Replace(thisPackage, string(filepath.Separator), "/", -1)
			}

			if str.Value == thisPackage {
				str.Value = ":" + path.Base(str.Value)
			} else if strings.HasPrefix(str.Value, thisPackage+":") {
				str.Value = str.Value[len(thisPackage):]
			}
		}

		m := labelRE.FindStringSubmatch(str.Value)
		if m == nil {
			return
		}
		if m[4] != "" && m[4] == m[5] { // e.g. //foo:foo
			str.Value = m[1]
		} else if m[3] != "" && m[4] == "" && m[3] == m[5] { // e.g. @foo//:foo
			str.Value = "@" + m[3]
		}
	}

	// Join and shorten labels within a container of labels (which can be a single
	// label, e.g. a single string expression or a concatenation of them).
	// Gracefully finish if the argument is of a different type.
	fixLabelsWithinAContainer := func(e *Expr) {
		if list, ok := (*e).(*ListExpr); ok {
			for i := range list.List {
				if leaveAlone1(list.List[i]) {
					continue
				}
				joinLabel(&list.List[i])
				shortenLabel(list.List[i])
			}
		}
		if set, ok := (*e).(*SetExpr); ok {
			for i := range set.List {
				if leaveAlone1(set.List[i]) {
					continue
				}
				joinLabel(&set.List[i])
				shortenLabel(set.List[i])
			}
		} else {
			joinLabel(e)
			shortenLabel(*e)
		}
	}

	Walk(f, func(v Expr, stk []Expr) {
		switch v := v.(type) {
		case *CallExpr:
			if leaveAlone(stk, v) {
				return
			}
			for i := range v.List {
				if leaveAlone1(v.List[i]) {
					continue
				}
				as, ok := v.List[i].(*AssignExpr)
				if !ok {
					continue
				}
				key, ok := as.LHS.(*Ident)
				if !ok || !w.IsLabelArg[key.Name] || w.LabelDenyList[callName(v)+"."+key.Name] {
					continue
				}
				if leaveAlone1(as.RHS) {
					continue
				}

				findAndModifyStrings(&as.RHS, fixLabelsWithinAContainer)
			}
		}
	})
}

// callName returns the name of the rule being called by call.
// If the call is not to a literal rule name or a dot expression, callName
// returns "".
func callName(call *CallExpr) string {
	return (&Rule{call, ""}).Kind()
}

// sortCallArgs sorts lists of named arguments to a call.
func sortCallArgs(f *File, w *Rewriter) {

	Walk(f, func(v Expr, stk []Expr) {
		call, ok := v.(*CallExpr)
		if !ok {
			return
		}
		if leaveAlone(stk, call) {
			return
		}
		rule := callName(call)
		if rule == "" {
			rule = "<complex rule kind>"
		}

		// Find the tail of the argument list with named arguments.
		start := len(call.List)
		for start > 0 && argName(call.List[start-1]) != "" {
			start--
		}

		// Record information about each arg into a sortable list.
		var args namedArgs
		for i, x := range call.List[start:] {
			name := argName(x)
			args = append(args, namedArg{ruleNamePriority(w, rule, name), name, i, x})
		}

		// Sort the list and put the args back in the new order.
		if sort.IsSorted(args) {
			return
		}
		sort.Sort(args)
		for i, x := range args {
			call.List[start+i] = x.expr
		}
	})
}

// ruleNamePriority maps a rule argument name to its sorting priority.
// It could use the auto-generated per-rule tables but for now it just
// falls back to the original list.
func ruleNamePriority(w *Rewriter, rule, arg string) int {
	ruleArg := rule + "." + arg
	if val, ok := w.NamePriority[ruleArg]; ok {
		return val
	}
	return w.NamePriority[arg]

	/*
		list := ruleArgOrder[rule]
		if len(list) == 0 {
			return tables.NamePriority[arg]
		}
		for i, x := range list {
			if x == arg {
				return i
			}
		}
		return len(list)
	*/
}

// If x is of the form key=value, argName returns the string key.
// Otherwise argName returns "".
func argName(x Expr) string {
	if as, ok := x.(*AssignExpr); ok {
		if id, ok := as.LHS.(*Ident); ok {
			return id.Name
		}
	}
	return ""
}

// A namedArg records information needed for sorting
// a named call argument into its proper position.
type namedArg struct {
	priority int    // kind of name; first sort key
	name     string // name; second sort key
	index    int    // original index; final sort key
	expr     Expr   // name=value argument
}

// namedArgs is a slice of namedArg that implements sort.Interface
type namedArgs []namedArg

func (x namedArgs) Len() int      { return len(x) }
func (x namedArgs) Swap(i, j int) { x[i], x[j] = x[j], x[i] }

func (x namedArgs) Less(i, j int) bool {
	p := x[i]
	q := x[j]
	if p.priority != q.priority {
		return p.priority < q.priority
	}
	if p.name != q.name {
		return p.name < q.name
	}
	return p.index < q.index
}

// sortStringLists sorts lists of string literals used as specific rule or function arguments.
func sortStringLists(f *File, w *Rewriter) {
	sortStringList := func(x *Expr) {
		SortStringList(*x)
	}

	Walk(f, func(e Expr, stk []Expr) {
		switch v := e.(type) {
		case *CallExpr:
			if f.Type == TypeDefault {
				// Rule parameters, not applicable to default file types
				return
			}
			if leaveAlone(stk, v) {
				return
			}
			if f.Type == TypeBzl {
				if name, ok := v.X.(*Ident); ok && name.Name == "visibility" {
					// Call args to the native "visibility function should be sorted per default.
					for _, arg := range v.List {
						findAndModifyStrings(&arg, sortStringList)
					}
				}
				return
			}
			rule := callName(v)
			for _, arg := range v.List {
				if leaveAlone1(arg) {
					continue
				}
				as, ok := arg.(*AssignExpr)
				if !ok || leaveAlone1(as) {
					continue
				}
				key, ok := as.LHS.(*Ident)
				if !ok {
					continue
				}
				context := rule + "." + key.Name
				if w.SortableDenylist[context] {
					continue
				}
				if w.IsSortableListArg[key.Name] ||
					w.SortableAllowlist[context] ||
					(!disabled("unsafesort") && allowedSort(context)) {
					if doNotSort(as) {
						deduplicateStringList(as.RHS)
					} else {
						findAndModifyStrings(&as.RHS, sortStringList)
					}
				}
			}
		case *AssignExpr:
			if disabled("unsafesort") {
				return
			}
			// "keep sorted" comment on x = list forces sorting of list.
			if keepSorted(v) {
				findAndModifyStrings(&v.RHS, sortStringList)
			}
		case *KeyValueExpr:
			if disabled("unsafesort") {
				return
			}
			// "keep sorted" before key: list also forces sorting of list.
			if keepSorted(v) {
				findAndModifyStrings(&v.Value, sortStringList)
			}
		case *ListExpr:
			if disabled("unsafesort") {
				return
			}
			// "keep sorted" comment above first list element also forces sorting of list.
			if len(v.List) > 0 && (keepSorted(v) || keepSorted(v.List[0])) {
				findAndModifyStrings(&e, sortStringList)
			}
		}
	})
}

// deduplicateStringList removes duplicates from a list with string expressions
// without reordering its elements.
// Any suffix-comments are lost, any before- and after-comments are preserved.
func deduplicateStringList(x Expr) {
	list, ok := x.(*ListExpr)
	if !ok {
		return
	}

	list.List = deduplicateStringExprs(list.List)
}

// deduplicateStringExprs removes duplicate string expressions from a slice
// without reordering its elements.
// Any suffix-comments are lost, any before- and after-comments are preserved.
func deduplicateStringExprs(list []Expr) []Expr {
	var comments []Comment
	alreadySeen := make(map[string]bool)
	var deduplicated []Expr
	for _, value := range list {
		str, ok := value.(*StringExpr)
		if !ok {
			deduplicated = append(deduplicated, value)
			continue
		}
		strVal := str.Value
		if _, ok := alreadySeen[strVal]; ok {
			// This is a duplicate of a string above.
			// Collect comments so that they're not lost.
			comments = append(comments, str.Comment().Before...)
			comments = append(comments, str.Comment().After...)
			continue
		}
		alreadySeen[strVal] = true
		if len(comments) > 0 {
			comments = append(comments, value.Comment().Before...)
			value.Comment().Before = comments
			comments = nil
		}
		deduplicated = append(deduplicated, value)
	}
	return deduplicated
}

// SortStringList sorts x, a list of strings.
// The list is broken by non-strings and by blank lines and comments into chunks.
// Each chunk is sorted in place.
func SortStringList(x Expr) {
	list, ok := x.(*ListExpr)
	if !ok || len(list.List) < 2 {
		return
	}

	if doNotSort(list.List[0]) {
		list.List = deduplicateStringExprs(list.List)
		return
	}

	forceSort := keepSorted(list) || keepSorted(list.List[0])

	// TODO(bazel-team): Decide how to recognize lists that cannot
	// be sorted. Avoiding all lists with comments avoids sorting
	// lists that say explicitly, in some form or another, why they
	// cannot be sorted. For example, many cc_test rules require
	// certain order in their deps attributes.
	if !forceSort {
		if line, _ := hasComments(list); line {
			deduplicateStringList(list)
			return
		}
	}

	list.List = sortStringExprs(list.List)
}

// findAndModifyStrings finds and modifies string lists with a callback
// function recursively within  the given expression. It doesn't touch all
// string lists it can find, but only top-level lists, lists that are parts of
// concatenated expressions and lists within select statements.
// It calls the callback on the root node and on all relevant inner lists.
// The callback function should gracefully return if called with not appropriate
// arguments.
func findAndModifyStrings(x *Expr, callback func(*Expr)) {
	callback(x)
	switch x := (*x).(type) {
	case *BinaryExpr:
		if x.Op != "+" {
			return
		}
		findAndModifyStrings(&x.X, callback)
		findAndModifyStrings(&x.Y, callback)
	case *CallExpr:
		if ident, ok := x.X.(*Ident); !ok || ident.Name != "select" {
			return
		}
		if len(x.List) == 0 {
			return
		}
		dict, ok := x.List[0].(*DictExpr)
		if !ok {
			return
		}
		for _, kv := range dict.List {
			findAndModifyStrings(&kv.Value, callback)
		}
	}
}

func sortStringExprs(list []Expr) []Expr {
	if len(list) < 2 {
		return list
	}

	// Sort chunks of the list with no intervening blank lines or comments.
	for i := 0; i < len(list); {
		if _, ok := list[i].(*StringExpr); !ok {
			i++
			continue
		}

		j := i + 1
		for ; j < len(list); j++ {
			if str, ok := list[j].(*StringExpr); !ok || len(str.Before) > 0 {
				break
			}
		}

		chunk := make([]stringSortKey, 0, j-i)
		for index, x := range list[i:j] {
			chunk = append(chunk, makeSortKey(index, x.(*StringExpr)))
		}
		if !sort.IsSorted(byStringExpr(chunk)) || !isUniq(chunk) {
			before := chunk[0].x.Comment().Before
			chunk[0].x.Comment().Before = nil

			sort.Sort(byStringExpr(chunk))
			chunk = uniq(chunk)

			chunk[0].x.Comment().Before = before
			for offset, key := range chunk {
				list[i+offset] = key.x
			}
			list = append(list[:(i+len(chunk))], list[j:]...)
		}

		i = j
	}

	return list
}

// uniq removes duplicates from a list, which must already be sorted.
// It edits the list in place.
func uniq(sortedList []stringSortKey) []stringSortKey {
	out := sortedList[:0]
	for _, sk := range sortedList {
		if len(out) == 0 || sk.value != out[len(out)-1].value {
			out = append(out, sk)
		}
	}
	return out
}

// isUniq reports whether the sorted list only contains unique elements.
func isUniq(list []stringSortKey) bool {
	for i := range list {
		if i+1 < len(list) && list[i].value == list[i+1].value {
			return false
		}
	}
	return true
}

// A stringSortKey records information about a single string literal to be
// sorted. The strings are first grouped into four phases: most strings,
// strings beginning with ":", strings beginning with "//", and strings
// beginning with "@". The next significant part of the comparison is the list
// of elements in the value, where elements are split at `.' and `:'. Finally
// we compare by value and break ties by original index.
type stringSortKey struct {
	phase    int
	split    []string
	value    string
	original int
	x        Expr
}

func makeSortKey(index int, x *StringExpr) stringSortKey {
	key := stringSortKey{
		value:    x.Value,
		original: index,
		x:        x,
	}

	switch {
	case strings.HasPrefix(x.Value, ":"):
		key.phase = 1
	case strings.HasPrefix(x.Value, "//") || (tables.StripLabelLeadingSlashes && !strings.HasPrefix(x.Value, "@")):
		key.phase = 2
	case strings.HasPrefix(x.Value, "@"):
		key.phase = 3
	}

	key.split = strings.Split(strings.Replace(x.Value, ":", ".", -1), ".")
	return key
}

// byStringExpr implements sort.Interface for a list of stringSortKey.
type byStringExpr []stringSortKey

func (x byStringExpr) Len() int      { return len(x) }
func (x byStringExpr) Swap(i, j int) { x[i], x[j] = x[j], x[i] }

func (x byStringExpr) Less(i, j int) bool {
	xi := x[i]
	xj := x[j]

	if xi.phase != xj.phase {
		return xi.phase < xj.phase
	}
	for k := 0; k < len(xi.split) && k < len(xj.split); k++ {
		if xi.split[k] != xj.split[k] {
			return xi.split[k] < xj.split[k]
		}
	}
	if len(xi.split) != len(xj.split) {
		return len(xi.split) < len(xj.split)
	}
	if xi.value != xj.value {
		return xi.value < xj.value
	}
	return xi.original < xj.original
}

// fixMultilinePlus turns
//
//	... +
//	[ ... ]
//
//	... +
//	call(...)
//
// into
//
//	... + [
//		...
//	]
//
//	... + call(
//		...
//	)
//
// which typically works better with our aggressively compact formatting.
func fixMultilinePlus(f *File, _ *Rewriter) {

	// List manipulation helpers.
	// As a special case, we treat f([...]) as a list, mainly
	// for glob.

	// isList reports whether x is a list.
	var isList func(x Expr) bool
	isList = func(x Expr) bool {
		switch x := x.(type) {
		case *ListExpr:
			return true
		case *CallExpr:
			if len(x.List) == 1 {
				return isList(x.List[0])
			}
		}
		return false
	}

	// isMultiLine reports whether x is a multiline list.
	var isMultiLine func(Expr) bool
	isMultiLine = func(x Expr) bool {
		switch x := x.(type) {
		case *ListExpr:
			return x.ForceMultiLine || len(x.List) > 1
		case *CallExpr:
			if x.ForceMultiLine || len(x.List) > 1 && !x.ForceCompact {
				return true
			}
			if len(x.List) == 1 {
				return isMultiLine(x.List[0])
			}
		}
		return false
	}

	// forceMultiLine tries to force the list x to use a multiline form.
	// It reports whether it was successful.
	var forceMultiLine func(Expr) bool
	forceMultiLine = func(x Expr) bool {
		switch x := x.(type) {
		case *ListExpr:
			// Already multi line?
			if x.ForceMultiLine {
				return true
			}
			// If this is a list containing a list, force the
			// inner list to be multiline instead.
			if len(x.List) == 1 && forceMultiLine(x.List[0]) {
				return true
			}
			x.ForceMultiLine = true
			return true

		case *CallExpr:
			if len(x.List) == 1 {
				return forceMultiLine(x.List[0])
			}
		}
		return false
	}

	skip := map[Expr]bool{}
	Walk(f, func(v Expr, stk []Expr) {
		if skip[v] {
			return
		}
		bin, ok := v.(*BinaryExpr)
		if !ok || bin.Op != "+" {
			return
		}

		// Found a +.
		// w + x + y + z parses as ((w + x) + y) + z,
		// so chase down the left side to make a list of
		// all the things being added together, separated
		// by the BinaryExprs that join them.
		// Mark them as "skip" so that when Walk recurses
		// into the subexpressions, we won't reprocess them.
		var all []Expr
		for {
			all = append(all, bin.Y, bin)
			bin1, ok := bin.X.(*BinaryExpr)
			if !ok || bin1.Op != "+" {
				break
			}
			bin = bin1
			skip[bin] = true
		}
		all = append(all, bin.X)

		// Because the outermost expression was the
		// rightmost one, the list is backward. Reverse it.
		for i, j := 0, len(all)-1; i < j; i, j = i+1, j-1 {
			all[i], all[j] = all[j], all[i]
		}

		// The 'all' slice is alternating addends and BinaryExpr +'s:
		//	w, +, x, +, y, +, z
		// If there are no lists involved, don't rewrite anything.
		haveList := false
		for i := 0; i < len(all); i += 2 {
			if isList(all[i]) {
				haveList = true
				break
			}
		}
		if !haveList {
			return
		}

		// Okay, there are lists.
		// Consider each + next to a line break.
		for i := 1; i < len(all); i += 2 {
			bin := all[i].(*BinaryExpr)
			if !bin.LineBreak {
				continue
			}

			// We're going to break the line after the +.
			// If it is followed by a list, force that to be
			// multiline instead.
			if forceMultiLine(all[i+1]) {
				bin.LineBreak = false
				continue
			}

			// If the previous list was multiline already,
			// don't bother with the line break after
			// the +.
			if isMultiLine(all[i-1]) {
				bin.LineBreak = false
				continue
			}
		}
	})
}

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

// moveLoadOnTop moves all load statements to the top of the file
func moveLoadOnTop(f *File, _ *Rewriter) {
	if f.Type == TypeWorkspace {
		// Moving load statements in Workspace files can break the semantics
		return
	}
	if isCommentAnywhere(f, "disable=load-on-top") {
		// For backward compatibility. This rewrite used to be a suppressible warning,
		// in some cases it's hard to maintain the position of load statements (e.g.
		// when the file is automatically generated or has automatic transformations
		// applied to it). The rewrite checks for the comment anywhere in the file
		// because it's hard to determine which statement is out of order.
		return
	}

	// Find the misplaced load statements
	misplacedLoads := make(map[int]*LoadStmt)
	firstStmtIndex := -1 // index of the first seen non-load statement
	for i := 0; i < len(f.Stmt); i++ {
		stmt := f.Stmt[i]
		_, isString := stmt.(*StringExpr) // typically a docstring
		_, isComment := stmt.(*CommentBlock)
		isWorkspace := isFunctionCall(stmt, "workspace")
		if isString || isComment || isWorkspace || stmt == nil {
			continue
		}
		load, ok := stmt.(*LoadStmt)
		if !ok {
			if firstStmtIndex == -1 {
				firstStmtIndex = i
			}
			continue
		}
		if firstStmtIndex == -1 {
			continue
		}
		misplacedLoads[i] = load
	}

	// Calculate a fix
	if firstStmtIndex == -1 {
		firstStmtIndex = 0
	}
	offset := len(misplacedLoads)
	if offset == 0 {
		return
	}
	stmtCopy := append([]Expr{}, f.Stmt...)
	for i := range f.Stmt {
		if i < firstStmtIndex {
			// Docstring or a comment in the beginning, skip
			continue
		} else if _, ok := misplacedLoads[i]; ok {
			// A misplaced load statement, should be moved up to the `firstStmtIndex` position
			f.Stmt[firstStmtIndex] = stmtCopy[i]
			firstStmtIndex++
			offset--
			if offset == 0 {
				// No more statements should be moved
				break
			}
		} else {
			// An actual statement (not a docstring or a comment in the beginning), should be moved
			// `offset` positions down.
			f.Stmt[i+offset] = stmtCopy[i]
		}
	}
}

// compressSameOriginLoads merges loads from the same source into one load statement
func compressSameOriginLoads(f *File, _ *Rewriter) {
	// Load statements grouped by their source files
	loads := make(map[string]*LoadStmt)

	for stmtIndex := 0; stmtIndex < len(f.Stmt); stmtIndex++ {
		load, ok := f.Stmt[stmtIndex].(*LoadStmt)
		if !ok {
			continue
		}

		previousLoad, ok := loads[load.Module.Value]
		if !ok {
			loads[load.Module.Value] = load
			continue
		}
		if hasComment(previousLoad, "disable=same-origin-load") ||
			hasComment(load, "disable=same-origin-load") {
			continue
		}

		// Move loaded symbols to the existing load statement
		previousLoad.From = append(previousLoad.From, load.From...)
		previousLoad.To = append(previousLoad.To, load.To...)
		// Remove the current statement
		f.Stmt[stmtIndex] = nil
	}
}

// comparePaths compares two strings as if they were paths (the path delimiter,
// '/', should be treated as smallest symbol).
func comparePaths(path1, path2 string) bool {
	if path1 == path2 {
		return false
	}

	chunks1 := strings.Split(path1, "/")
	chunks2 := strings.Split(path2, "/")

	for i, chunk1 := range chunks1 {
		if i >= len(chunks2) {
			return false
		}
		chunk2 := chunks2[i]
		// Compare case-insensitively
		chunk1Lower := strings.ToLower(chunk1)
		chunk2Lower := strings.ToLower(chunk2)
		if chunk1Lower != chunk2Lower {
			return chunk1Lower < chunk2Lower
		}
	}

	// No case-insensitive difference detected. Likely the difference is just in
	// the case of some symbols, compare case-sensitively for the determinism.
	return path1 <= path2
}

// compareLoadLabels compares two module names
// If one label has explicit repository path (starts with @), it goes first
// If the packages are different, labels are sorted by package name (empty package goes first)
// If the packages are the same, labels are sorted by their name
// Relative labels go last
func compareLoadLabels(load1Label, load2Label string) bool {
	// handle absolute labels with explicit repositories separately to
	// make sure they precede absolute and relative labels without repos
	isExplicitRepo1 := strings.HasPrefix(load1Label, "@")
	isExplicitRepo2 := strings.HasPrefix(load2Label, "@")

	if isExplicitRepo1 != isExplicitRepo2 {
		// Exactly one label has an explicit repository name, it should be the first one.
		return isExplicitRepo1
	}

	// ensure that relative labels go last by giving them a fake package name
	// that sorts after all valid package names
	label1 := labels.ParseRelative(load1Label, string(rune(0x7F)))
	label2 := labels.ParseRelative(load2Label, string(rune(0x7F)))

	if label1.Repository != label2.Repository {
		return label1.Repository < label2.Repository
	}

	// in case one of the packages is empty, the empty one goes first
	if (len(label1.Package) == 0) != (len(label2.Package) == 0) {
		return len(label1.Package) == 0
	}

	// both packages are non-empty and not equal, so compare them
	if label1.Package != label2.Package {
		return comparePaths(label1.Package, label2.Package)
	}

	// in case both packages are the same, use file names to break ties
	return comparePaths(label1.Target, label2.Target)
}

// sortLoadStatements reorders sorts loads lexicographically by the source file,
// but absolute loads have priority over local loads.
func sortLoadStatements(f *File, _ *Rewriter) {
	if isCommentAnywhere(f, "disable=out-of-order-load") {
		// For backward compatibility. This rewrite used to be a suppressible warning,
		// in some cases it's hard to maintain the position of load statements (e.g.
		// when the file is automatically generated or has automatic transformations
		// applied to it). The rewrite checks for the comment anywhere in the file
		// because it's hard to determine which statement is out of order.
		return
	}

	// Consequent chunks of load statements (i.e. without statements of other types between them)
	var loadsChunks [][]*LoadStmt
	newChunk := true // Create a new chunk for the next seen load statement

	for _, stmt := range f.Stmt {
		if stmt == nil {
			// nil statements are no-op and shouldn't break consecutive chains of
			// load statements
			continue
		}
		load, ok := stmt.(*LoadStmt)
		if !ok {
			newChunk = true
			continue
		}
		if newChunk {
			// There's a non-load statement between this load and the previous load
			loadsChunks = append(loadsChunks, []*LoadStmt{})
			newChunk = false
		}
		loadsChunks[len(loadsChunks)-1] = append(loadsChunks[len(loadsChunks)-1], load)
	}

	// Sort and flatten the chunks
	var sortedLoads []*LoadStmt
	for _, chunk := range loadsChunks {
		sortedChunk := append([]*LoadStmt{}, chunk...)

		sort.SliceStable(sortedChunk, func(i, j int) bool {
			load1Label := (sortedChunk)[i].Module.Value
			load2Label := (sortedChunk)[j].Module.Value
			return compareLoadLabels(load1Label, load2Label)
		})
		sortedLoads = append(sortedLoads, sortedChunk...)
	}

	// Calculate the replacements
	loadIndex := 0
	for stmtIndex := range f.Stmt {
		if _, ok := f.Stmt[stmtIndex].(*LoadStmt); !ok {
			continue
		}
		f.Stmt[stmtIndex] = sortedLoads[loadIndex]
		loadIndex++
	}
}

// sortAllLoadArgs sorts all load arguments in the file
func sortAllLoadArgs(f *File, _ *Rewriter) {
	Walk(f, func(v Expr, stk []Expr) {
		if load, ok := v.(*LoadStmt); ok {
			SortLoadArgs(load)
		}
	})
}

func sortUseRepoPositionals(f *File, _ *Rewriter) {
	Walk(f, func(v Expr, stk []Expr) {
		if call, ok := v.(*CallExpr); ok {
			// The first argument of a valid use_repo call is always a module extension proxy, so we
			// do not need to sort calls with less than three arguments.
			if ident, ok := call.X.(*Ident); !ok || ident.Name != "use_repo" || len(call.List) < 3 {
				return
			}
			// Respect the "do not sort" comment on both the first argument and the first repository
			// name.
			if doNotSort(call) || doNotSort(call.List[0]) || doNotSort(call.List[1]) {
				call.List = deduplicateStringExprs(call.List)
			} else {
				// Keyword arguments do not have to be sorted here as this has already been done by
				// the generic callsort rewriter pass.
				call.List = sortStringExprs(call.List)
			}
		}
	})
}

// hasComments reports whether any comments are associated with
// the list or its elements.
func hasComments(list *ListExpr) (line, suffix bool) {
	com := list.Comment()
	if len(com.Before) > 0 || len(com.After) > 0 || len(list.End.Before) > 0 {
		line = true
	}
	if len(com.Suffix) > 0 {
		suffix = true
	}
	for _, elem := range list.List {
		com := elem.Comment()
		if len(com.Before) > 0 {
			line = true
		}
		if len(com.Suffix) > 0 {
			suffix = true
		}
	}
	return
}

// A wrapper for a LoadStmt's From and To slices for consistent sorting of their contents.
// It's assumed that the following slices have the same length. The contents are sorted by
// the `To` attribute, but all items with equal "From" and "To" parts are placed before the items
// with different parts.
type loadArgs struct {
	From     []*Ident
	To       []*Ident
	modified bool
}

func (args *loadArgs) Len() int {
	return len(args.From)
}

func (args *loadArgs) Swap(i, j int) {
	args.From[i], args.From[j] = args.From[j], args.From[i]
	args.To[i], args.To[j] = args.To[j], args.To[i]
	args.modified = true
}

func (args *loadArgs) Less(i, j int) bool {
	// Arguments with equal "from" and "to" parts are prioritized
	equalI := args.From[i].Name == args.To[i].Name
	equalJ := args.From[j].Name == args.To[j].Name
	if equalI != equalJ {
		// If equalI and !equalJ, return true, otherwise false.
		// Equivalently, return equalI.
		return equalI
	}
	return args.To[i].Name < args.To[j].Name
}

// deduplicate assumes that the args are sorted and prioritize arguments that
// are defined later (e.g. `a = "x", a = "y"` is shortened to `a = "y"`).
func (args *loadArgs) deduplicate() {
	var from, to []*Ident
	for i := range args.To {
		if len(to) > 0 && to[len(to)-1].Name == args.To[i].Name {
			// Overwrite
			from[len(from)-1] = args.From[i]
			to[len(to)-1] = args.To[i]
			args.modified = true
		} else {
			// Just append
			from = append(from, args.From[i])
			to = append(to, args.To[i])
		}
	}
	args.From = from
	args.To = to
}

// SortLoadArgs sorts a load statement arguments (lexicographically, but positional first)
func SortLoadArgs(load *LoadStmt) bool {
	args := loadArgs{From: load.From, To: load.To}
	sort.Sort(&args)
	args.deduplicate()
	load.From = args.From
	load.To = args.To
	return args.modified
}

// formatDocstrings fixes the indentation and trailing whitespace of docstrings
func formatDocstrings(f *File, _ *Rewriter) {
	Walk(f, func(v Expr, stk []Expr) {
		def, ok := v.(*DefStmt)
		if !ok || len(def.Body) == 0 {
			return
		}
		docstring, ok := def.Body[0].(*StringExpr)
		if !ok || !docstring.TripleQuote {
			return
		}

		oldIndentation := docstring.Start.LineRune - 1 // LineRune starts with 1
		newIndentation := nestedIndentation * len(stk)

		// Operate on Token, not Value, because their line breaks can be different if a line ends with
		// a backslash.
		updatedToken := formatString(docstring.Token, oldIndentation, newIndentation)
		if updatedToken != docstring.Token {
			docstring.Token = updatedToken
			// Update the value to keep it consistent with Token
			docstring.Value, _, _ = Unquote(updatedToken)
		}
	})
}

// formatString modifies a string value of a docstring to match the new indentation level and
// to remove trailing whitespace from its lines.
func formatString(value string, oldIndentation, newIndentation int) string {
	difference := newIndentation - oldIndentation
	lines := strings.Split(value, "\n")
	for i, line := range lines {
		if i == 0 {
			// The first line shouldn't be touched because it starts right after ''' or """
			continue
		}
		if difference > 0 {
			line = strings.Repeat(" ", difference) + line
		} else {
			for i, rune := range line {
				if i == -difference || rune != ' ' {
					line = line[i:]
					break
				}
			}
		}
		if i != len(lines)-1 {
			// Remove trailing space from the line unless it's the last line that's responsible
			// for the indentation of the closing `"""`
			line = strings.TrimRight(line, " ")
		}
		lines[i] = line
	}
	return strings.Join(lines, "\n")
}

// argumentType returns an integer by which funcall arguments can be sorted:
// 1 for positional, 2 for named, 3 for *args, 4 for **kwargs
func argumentType(expr Expr) int {
	switch expr := expr.(type) {
	case *UnaryExpr:
		switch expr.Op {
		case "**":
			return 4
		case "*":
			return 3
		}
	case *AssignExpr:
		return 2
	}
	return 1
}

// reorderArguments fixes the order of arguments of a function call
// (positional, named, *args, **kwargs)
func reorderArguments(f *File, _ *Rewriter) {
	Walk(f, func(expr Expr, stack []Expr) {
		call, ok := expr.(*CallExpr)
		if !ok {
			return
		}
		compare := func(i, j int) bool {
			// Keep nil nodes at their place. They are no-op for the formatter but can
			// be useful for the linter which expects them to not move.
			if call.List[i] == nil || call.List[j] == nil {
				return false
			}
			return argumentType(call.List[i]) < argumentType(call.List[j])
		}
		if !sort.SliceIsSorted(call.List, compare) {
			sort.SliceStable(call.List, compare)
		}
	})
}

// editOctals inserts 'o' into octal numbers to make it more obvious they are octal
// 0123 -> 0o123
func editOctals(f *File, _ *Rewriter) {
	Walk(f, func(expr Expr, stack []Expr) {
		l, ok := expr.(*LiteralExpr)
		if !ok {
			return
		}
		if len(l.Token) > 1 && l.Token[0] == '0' && l.Token[1] >= '0' && l.Token[1] <= '9' {
			l.Token = "0o" + l.Token[1:]
		}
	})
}

// editFloats inserts '0' before the decimal point in floats and normalizes the
// exponent part to lowercase, no plus sign, and no leading zero.
func editFloats(f *File, _ *Rewriter) {
	Walk(f, func(expr Expr, stack []Expr) {
		l, ok := expr.(*LiteralExpr)
		if !ok {
			return
		}
		if !strings.ContainsRune(l.Token, '.') {
			return
		}
		if strings.HasPrefix(l.Token, ".") {
			l.Token = "0" + l.Token
		}
		if !strings.ContainsAny(l.Token, "eE") {
			return
		}
		parts := strings.SplitN(l.Token, "e", 2)
		if len(parts) != 2 {
			parts = strings.SplitN(l.Token, "E", 2)
		}
		if len(parts) != 2 {
			// Invalid float, skip rewriting.
			return
		}
		l.Token = parts[0] + "e" + strings.TrimLeft(parts[1], "0+")
	})
}

// removeParens removes trivial parens
func removeParens(f *File, _ *Rewriter) {
	var simplify func(expr Expr, stack []Expr) Expr
	simplify = func(expr Expr, stack []Expr) Expr {
		// Look for parenthesized expressions, ignoring those with
		// comments and those that are intentionally multiline.
		pa, ok := expr.(*ParenExpr)
		if !ok || pa.ForceMultiLine {
			return expr
		}
		if len(pa.Comment().Before) > 0 || len(pa.Comment().After) > 0 || len(pa.Comment().Suffix) > 0 {
			return expr
		}

		switch x := pa.X.(type) {
		case *Comprehension, *DictExpr, *Ident, *ListExpr, *LiteralExpr, *ParenExpr, *SetExpr, *StringExpr:
			// These expressions don't need parens, remove them (recursively).
			return Edit(x, simplify)
		case *CallExpr:
			// Parens might be needed if the callable is multiline.
			start, end := x.X.Span()
			if start.Line == end.Line {
				return Edit(x, simplify)
			}
		}
		return expr
	}

	Edit(f, simplify)
}

// collapseEmpty unsets ForceMultiLine for empty call expressions.
func collapseEmpty(f *File, _ *Rewriter) {
	Walk(f, func(expr Expr, stack []Expr) {
		if c, ok := expr.(*CallExpr); ok && len(c.List) == 0 { // No arguments
			c.ForceMultiLine = false
		}
	})
}
