/* Copyright 2016 The Bazel Authors. All rights reserved.

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

   http://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 merger provides functions for merging generated rules into
// existing build files.
//
// Gazelle's normal workflow is roughly as follows:
//
// 1. Read metadata from sources.
//
// 2. Generate new rules.
//
// 3. Merge newly generated rules with rules in the existing build file
// if there is one.
//
// 4. Build an index of merged library rules for dependency resolution.
//
// 5. Resolve dependencies (i.e., convert import strings to deps labels).
//
// 6. Merge the newly resolved dependencies.
//
// 7. Write the merged file back to disk.
//
// This package is used for sets 3 and 6 above.
package merger

import (
	"fmt"
	"sort"
	"strings"

	"github.com/bazelbuild/bazel-gazelle/rule"
)

// Phase indicates which attributes should be merged in matching rules.
type Phase int

const (
	// The pre-resolve merge is performed before rules are indexed for dependency
	// resolution. All attributes not related to dependencies are merged
	// (i.e., rule.KindInfo.MergeableAttrs). This merge must be performed
	// before indexing because attributes related to indexing (e.g.,
	// srcs, importpath) will be affected.
	PreResolve Phase = iota

	// The post-resolve merge is performed after rules are indexed. All attributes
	// related to dependencies are merged (i.e., rule.KindInfo.ResolveAttrs).
	PostResolve
)

// UnstableInsertIndexKey is the name of an internal attribute that may be set
// on newly generated rules. When MergeFile is given a generated rule that
// doesn't match any existing rule, MergeFile will insert the rule at the index
// indicated by this key instead of at the end of the file.
//
// This definition is unstable and may be removed in the future.
//
// TODO(jayconrod): make this stable *or* find a better way to express it.
const UnstableInsertIndexKey = "_gazelle_insert_index"

// MergeFile combines information from newly generated rules with matching
// rules in an existing build file. MergeFile can also delete rules which
// are empty after merging.
//
// oldFile is the file to merge. It must not be nil.
//
// emptyRules is a list of stub rules (with no attributes other than name)
// which were not generated. These are merged with matching rules. The merged
// rules are deleted if they contain no attributes that make them buildable
// (e.g., srcs, deps, anything in rule.KindInfo.NonEmptyAttrs).
//
// genRules is a list of newly generated rules. These are merged with
// matching rules. A rule matches if it has the same kind and name or if
// some other attribute in rule.KindInfo.MatchAttrs matches (e.g.,
// "importpath" in go_library). Elements of genRules that don't match
// any existing rule are appended to the end of oldFile.
//
// phase indicates whether this is a pre- or post-resolve merge. Different
// attributes (rule.KindInfo.MergeableAttrs or ResolveAttrs) will be merged.
//
// kinds maps rule kinds (e.g., "go_library") to metadata that helps merge
// rules of that kind.
//
// When a generated and existing rule are merged, each attribute is merged
// separately. If an attribute is mergeable (according to KindInfo), values
// from the existing attribute are replaced by values from the generated
// attribute. Comments are preserved on values that are present in both
// versions of the attribute. If at attribute is not mergeable, the generated
// version of the attribute will be added if no existing attribute is present;
// otherwise, the existing attribute will be preserved.
//
// Note that "# keep" comments affect merging. If a value within an existing
// attribute is marked with a "# keep" comment, it will not be removed.
// If an attribute is marked with a "# keep" comment, it will not be merged.
// If a rule is marked with a "# keep" comment, the whole rule will not
// be modified.
func MergeFile(oldFile *rule.File, emptyRules, genRules []*rule.Rule, phase Phase, kinds map[string]rule.KindInfo, aliasedKinds map[string]string) {
	getMergeAttrs := func(r *rule.Rule) map[string]bool {
		if phase == PreResolve {
			return kinds[r.Kind()].MergeableAttrs
		} else {
			return kinds[r.Kind()].ResolveAttrs
		}
	}

	// Merge empty rules into the file and delete any rules which become empty.
	for _, emptyRule := range emptyRules {
		if oldRule, _ := match(oldFile.Rules, emptyRule, kinds[emptyRule.Kind()], false, aliasedKinds); oldRule != nil {
			if oldRule.ShouldKeep() {
				continue
			}
			rule.MergeRules(emptyRule, oldRule, getMergeAttrs(emptyRule), oldFile.Path)
			if oldRule.IsEmpty(kinds[oldRule.Kind()]) {
				oldRule.Delete()
			}
		}
	}
	oldFile.Sync()

	// Match generated rules with existing rules in the file. Keep track of
	// rules with non-standard names.
	matchRules := make([]*rule.Rule, len(genRules))
	matchErrors := make([]error, len(genRules))
	substitutions := make(map[string]string)
	for i, genRule := range genRules {
		oldRule, err := Match(oldFile.Rules, genRule, kinds[genRule.Kind()], aliasedKinds)
		if err != nil {
			// TODO(jayconrod): add a verbose mode and log errors. They are too chatty
			// to print by default.
			matchErrors[i] = err
			continue
		}
		matchRules[i] = oldRule
		if oldRule != nil {
			if oldRule.Name() != genRule.Name() {
				substitutions[genRule.Name()] = oldRule.Name()
			}
		}
	}

	// Rename labels in generated rules that refer to other generated rules.
	if len(substitutions) > 0 {
		for _, genRule := range genRules {
			substituteRule(genRule, substitutions, kinds[genRule.Kind()])
		}
	}

	// Merge generated rules with existing rules or append to the end of the file.
	for i, genRule := range genRules {
		if matchErrors[i] != nil {
			continue
		}
		if matchRules[i] == nil {
			if index, ok := genRule.PrivateAttr(UnstableInsertIndexKey).(int); ok {
				genRule.InsertAt(oldFile, index)
			} else {
				genRule.Insert(oldFile)
			}
		} else {
			rule.MergeRules(genRule, matchRules[i], getMergeAttrs(genRule), oldFile.Path)
		}
	}
}

// substituteRule replaces local labels (those beginning with ":", referring to
// targets in the same package) according to a substitution map. This is used
// to update generated rules before merging when the corresponding existing
// rules have different names. If substituteRule replaces a string, it returns
// a new expression; it will not modify the original expression.
func substituteRule(r *rule.Rule, substitutions map[string]string, info rule.KindInfo) {
	for attr := range info.SubstituteAttrs {
		if expr := r.Attr(attr); expr != nil {
			expr = rule.MapExprStrings(expr, func(s string) string {
				if rename, ok := substitutions[strings.TrimPrefix(s, ":")]; ok {
					return ":" + rename
				} else {
					return s
				}
			})
			r.SetAttr(attr, expr)
		}
	}
}

// Match searches for a rule that can be merged with x in rules.
//
// A rule is considered a match if its kind is equal to x's kind AND either its
// name is equal OR at least one of the attributes in matchAttrs is equal.
//
// If there are no matches, nil and nil are returned.
//
// If a rule has the same name but a different kind, nill and an error
// are returned.
//
// If there is exactly one match, the rule and nil are returned.
//
// If there are multiple matches, match will attempt to disambiguate, based on
// the quality of the match (name match is best, then attribute match in the
// order that attributes are listed). If disambiguation is successful,
// the rule and nil are returned. Otherwise, nil and an error are returned.
func Match(rules []*rule.Rule, x *rule.Rule, info rule.KindInfo, aliasedKinds map[string]string) (*rule.Rule, error) {
	return match(rules, x, info, true, aliasedKinds)
}

func match(rules []*rule.Rule, x *rule.Rule, info rule.KindInfo, wantError bool, aliasedKinds map[string]string) (*rule.Rule, error) {
	xname := x.Name()
	xkind := x.Kind()
	var nameMatches []*rule.Rule
	var kindMatches []*rule.Rule
	for _, y := range rules {
		if xname == y.Name() {
			nameMatches = append(nameMatches, y)
		}
		if xkind == y.Kind() || aliasedKinds[y.Kind()] == xkind {
			kindMatches = append(kindMatches, y)
		}
	}

	if len(nameMatches) == 1 {
		y := nameMatches[0]
		if xkind == y.Kind() || xkind == aliasedKinds[y.Kind()] {
			return y, nil
		}
		if !wantError {
			return nil, nil
		}
		return nil, fmt.Errorf("could not merge %s(%s): a rule of the same name has kind %s", xkind, xname, y.Kind())
	}
	if len(nameMatches) > 1 {
		if !wantError {
			return nil, nil
		}
		return nil, fmt.Errorf("could not merge %s(%s): multiple rules have the same name", xkind, xname)
	}

	for _, key := range info.MatchAttrs {
		var attrMatches []*rule.Rule
		for _, y := range kindMatches {
			if attrMatch(x, y, key) {
				attrMatches = append(attrMatches, y)
			}
		}
		if len(attrMatches) == 1 {
			return attrMatches[0], nil
		} else if len(attrMatches) > 1 {
			if !wantError {
				return nil, nil
			}
			return nil, fmt.Errorf("could not merge %s(%s): multiple rules have the same attribute %s", xkind, xname, key)
		}
	}

	if info.MatchAny {
		if len(kindMatches) == 1 {
			return kindMatches[0], nil
		} else if len(kindMatches) > 1 {
			if !wantError {
				return nil, nil
			}
			return nil, fmt.Errorf("could not merge %s(%s): multiple rules have the same kind but different names", xkind, xname)
		}
	}

	return nil, nil
}

func attrMatch(x, y *rule.Rule, key string) bool {
	xValue := x.AttrString(key)
	if xValue != "" && xValue == y.AttrString(key) {
		return true
	}
	xValues := x.AttrStrings(key)
	yValues := y.AttrStrings(key)
	if xValues == nil || yValues == nil || len(xValues) != len(yValues) {
		return false
	}
	sort.Strings(xValues)
	sort.Strings(yValues)
	for i, v := range xValues {
		if v != yValues[i] {
			return false
		}
	}
	return true
}
