// Copyright 2019 Google Inc. 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 android

import (
	"fmt"
	"regexp"
	"sort"
	"strings"
	"sync"

	"github.com/google/blueprint"
)

// Enforces visibility rules between modules.
//
// Multi stage process:
// * First stage works bottom up, before defaults expansion, to check the syntax of the visibility
//   rules that have been specified.
//
// * Second stage works bottom up to extract the package info for each package and store them in a
//   map by package name. See package.go for functionality for this.
//
// * Third stage works bottom up to extract visibility information from the modules, parse it,
//   create visibilityRule structures and store them in a map keyed by the module's
//   qualifiedModuleName instance, i.e. //<pkg>:<name>. The map is stored in the context rather
//   than a global variable for testing. Each test has its own Config so they do not share a map
//   and so can be run in parallel. If a module has no visibility specified then it uses the
//   default package visibility if specified.
//
// * Fourth stage works top down and iterates over all the deps for each module. If the dep is in
//   the same package then it is automatically visible. Otherwise, for each dep it first extracts
//   its visibilityRule from the config map. If one could not be found then it assumes that it is
//   publicly visible. Otherwise, it calls the visibility rule to check that the module can see
//   the dependency. If it cannot then an error is reported.
//
// TODO(b/130631145) - Make visibility work properly with prebuilts.
// TODO(b/130796911) - Make visibility work properly with defaults.

// Patterns for the values that can be specified in visibility property.
const (
	packagePattern        = `//([^/:]+(?:/[^/:]+)*)`
	namePattern           = `:([^/:]+)`
	visibilityRulePattern = `^(?:` + packagePattern + `)?(?:` + namePattern + `)?$`
)

var visibilityRuleRegexp = regexp.MustCompile(visibilityRulePattern)

// A visibility rule is associated with a module and determines which other modules it is visible
// to, i.e. which other modules can depend on the rule's module.
type visibilityRule interface {
	// Check to see whether this rules matches m.
	// Returns true if it does, false otherwise.
	matches(m qualifiedModuleName) bool

	String() string
}

// Describes the properties provided by a module that contain visibility rules.
type visibilityPropertyImpl struct {
	name            string
	stringsProperty *[]string
}

type visibilityProperty interface {
	getName() string
	getStrings() []string
}

func newVisibilityProperty(name string, stringsProperty *[]string) visibilityProperty {
	return visibilityPropertyImpl{
		name:            name,
		stringsProperty: stringsProperty,
	}
}

func (p visibilityPropertyImpl) getName() string {
	return p.name
}

func (p visibilityPropertyImpl) getStrings() []string {
	return *p.stringsProperty
}

// A compositeRule is a visibility rule composed from a list of atomic visibility rules.
//
// The list corresponds to the list of strings in the visibility property after defaults expansion.
// Even though //visibility:public is not allowed together with other rules in the visibility list
// of a single module, it is allowed here to permit a module to override an inherited visibility
// spec with public visibility.
//
// //visibility:private is not allowed in the same way, since we'd need to check for it during the
// defaults expansion to make that work. No non-private visibility rules are allowed in a
// compositeRule containing a privateRule.
//
// This array will only be [] if all the rules are invalid and will behave as if visibility was
// ["//visibility:private"].
type compositeRule []visibilityRule

// A compositeRule matches if and only if any of its rules matches.
func (c compositeRule) matches(m qualifiedModuleName) bool {
	for _, r := range c {
		if r.matches(m) {
			return true
		}
	}
	return false
}

func (c compositeRule) String() string {
	return "[" + strings.Join(c.Strings(), ", ") + "]"
}

func (c compositeRule) Strings() []string {
	s := make([]string, 0, len(c))
	for _, r := range c {
		s = append(s, r.String())
	}
	return s
}

// A packageRule is a visibility rule that matches modules in a specific package (i.e. directory).
type packageRule struct {
	pkg string
}

func (r packageRule) matches(m qualifiedModuleName) bool {
	return m.pkg == r.pkg
}

func (r packageRule) String() string {
	return fmt.Sprintf("//%s", r.pkg) // :__pkg__ is the default, so skip it.
}

// A subpackagesRule is a visibility rule that matches modules in a specific package (i.e.
// directory) or any of its subpackages (i.e. subdirectories).
type subpackagesRule struct {
	pkgPrefix string
}

func (r subpackagesRule) matches(m qualifiedModuleName) bool {
	return isAncestor(r.pkgPrefix, m.pkg)
}

func isAncestor(p1 string, p2 string) bool {
	return strings.HasPrefix(p2+"/", p1+"/")
}

func (r subpackagesRule) String() string {
	return fmt.Sprintf("//%s:__subpackages__", r.pkgPrefix)
}

// visibilityRule for //visibility:public
type publicRule struct{}

func (r publicRule) matches(_ qualifiedModuleName) bool {
	return true
}

func (r publicRule) String() string {
	return "//visibility:public"
}

// visibilityRule for //visibility:private
type privateRule struct{}

func (r privateRule) matches(_ qualifiedModuleName) bool {
	return false
}

func (r privateRule) String() string {
	return "//visibility:private"
}

var visibilityRuleMap = NewOnceKey("visibilityRuleMap")

// The map from qualifiedModuleName to visibilityRule.
func moduleToVisibilityRuleMap(config Config) *sync.Map {
	return config.Once(visibilityRuleMap, func() interface{} {
		return &sync.Map{}
	}).(*sync.Map)
}

// Marker interface that identifies dependencies that are excluded from visibility
// enforcement.
type ExcludeFromVisibilityEnforcementTag interface {
	blueprint.DependencyTag

	// Method that differentiates this interface from others.
	ExcludeFromVisibilityEnforcement()
}

// The rule checker needs to be registered before defaults expansion to correctly check that
// //visibility:xxx isn't combined with other packages in the same list in any one module.
func RegisterVisibilityRuleChecker(ctx RegisterMutatorsContext) {
	ctx.BottomUp("visibilityRuleChecker", visibilityRuleChecker).Parallel()
}

// Registers the function that gathers the visibility rules for each module.
//
// Visibility is not dependent on arch so this must be registered before the arch phase to avoid
// having to process multiple variants for each module. This goes after defaults expansion to gather
// the complete visibility lists from flat lists and after the package info is gathered to ensure
// that default_visibility is available.
func RegisterVisibilityRuleGatherer(ctx RegisterMutatorsContext) {
	ctx.BottomUp("visibilityRuleGatherer", visibilityRuleGatherer).Parallel()
}

// This must be registered after the deps have been resolved.
func RegisterVisibilityRuleEnforcer(ctx RegisterMutatorsContext) {
	ctx.TopDown("visibilityRuleEnforcer", visibilityRuleEnforcer).Parallel()
}

// Checks the per-module visibility rule lists before defaults expansion.
func visibilityRuleChecker(ctx BottomUpMutatorContext) {
	qualified := createQualifiedModuleName(ctx)
	if m, ok := ctx.Module().(Module); ok {
		visibilityProperties := m.visibilityProperties()
		for _, p := range visibilityProperties {
			if visibility := p.getStrings(); visibility != nil {
				checkRules(ctx, qualified.pkg, p.getName(), visibility)
			}
		}
	}
}

func checkRules(ctx BaseModuleContext, currentPkg, property string, visibility []string) {
	ruleCount := len(visibility)
	if ruleCount == 0 {
		// This prohibits an empty list as its meaning is unclear, e.g. it could mean no visibility and
		// it could mean public visibility. Requiring at least one rule makes the owner's intent
		// clearer.
		ctx.PropertyErrorf(property, "must contain at least one visibility rule")
		return
	}

	for i, v := range visibility {
		ok, pkg, name := splitRule(ctx, v, currentPkg, property)
		if !ok {
			continue
		}

		if pkg == "visibility" {
			switch name {
			case "private", "public":
			case "legacy_public":
				ctx.PropertyErrorf(property, "//visibility:legacy_public must not be used")
				continue
			case "override":
				// This keyword does not create a rule so pretend it does not exist.
				ruleCount -= 1
			default:
				ctx.PropertyErrorf(property, "unrecognized visibility rule %q", v)
				continue
			}
			if name == "override" {
				if i != 0 {
					ctx.PropertyErrorf(property, `"%v" may only be used at the start of the visibility rules`, v)
				}
			} else if ruleCount != 1 {
				ctx.PropertyErrorf(property, "cannot mix %q with any other visibility rules", v)
				continue
			}
		}

		// If the current directory is not in the vendor tree then there are some additional
		// restrictions on the rules.
		if !isAncestor("vendor", currentPkg) {
			if !isAllowedFromOutsideVendor(pkg, name) {
				ctx.PropertyErrorf(property,
					"%q is not allowed. Packages outside //vendor cannot make themselves visible to specific"+
						" targets within //vendor, they can only use //vendor:__subpackages__.", v)
				continue
			}
		}
	}
}

// Gathers the flattened visibility rules after defaults expansion, parses the visibility
// properties, stores them in a map by qualifiedModuleName for retrieval during enforcement.
//
// See ../README.md#Visibility for information on the format of the visibility rules.
func visibilityRuleGatherer(ctx BottomUpMutatorContext) {
	m, ok := ctx.Module().(Module)
	if !ok {
		return
	}

	qualifiedModuleId := m.qualifiedModuleId(ctx)
	currentPkg := qualifiedModuleId.pkg

	// Parse the visibility rules that control access to the module and store them by id
	// for use when enforcing the rules.
	primaryProperty := m.base().primaryVisibilityProperty
	if primaryProperty != nil {
		if visibility := primaryProperty.getStrings(); visibility != nil {
			rule := parseRules(ctx, currentPkg, primaryProperty.getName(), visibility)
			if rule != nil {
				moduleToVisibilityRuleMap(ctx.Config()).Store(qualifiedModuleId, rule)
			}
		}
	}
}

func parseRules(ctx BaseModuleContext, currentPkg, property string, visibility []string) compositeRule {
	rules := make(compositeRule, 0, len(visibility))
	hasPrivateRule := false
	hasPublicRule := false
	hasNonPrivateRule := false
	for _, v := range visibility {
		ok, pkg, name := splitRule(ctx, v, currentPkg, property)
		if !ok {
			continue
		}

		var r visibilityRule
		isPrivateRule := false
		if pkg == "visibility" {
			switch name {
			case "private":
				r = privateRule{}
				isPrivateRule = true
			case "public":
				r = publicRule{}
				hasPublicRule = true
			case "override":
				// Discard all preceding rules and any state based on them.
				rules = nil
				hasPrivateRule = false
				hasPublicRule = false
				hasNonPrivateRule = false
				// This does not actually create a rule so continue onto the next rule.
				continue
			}
		} else {
			switch name {
			case "__pkg__":
				r = packageRule{pkg}
			case "__subpackages__":
				r = subpackagesRule{pkg}
			default:
				ctx.PropertyErrorf(property, "invalid visibility pattern %q. Must match "+
					" //<package>:<scope>, //<package> or :<scope> "+
					"where <scope> is one of \"__pkg__\", \"__subpackages__\"",
					v)
			}
		}

		if isPrivateRule {
			hasPrivateRule = true
		} else {
			hasNonPrivateRule = true
		}

		rules = append(rules, r)
	}

	if hasPrivateRule && hasNonPrivateRule {
		ctx.PropertyErrorf("visibility",
			"cannot mix \"//visibility:private\" with any other visibility rules")
		return compositeRule{privateRule{}}
	}

	if hasPublicRule {
		// Public overrides all other rules so just return it.
		return compositeRule{publicRule{}}
	}

	return rules
}

func isAllowedFromOutsideVendor(pkg string, name string) bool {
	if pkg == "vendor" {
		if name == "__subpackages__" {
			return true
		}
		return false
	}

	return !isAncestor("vendor", pkg)
}

func splitRule(ctx BaseModuleContext, ruleExpression string, currentPkg, property string) (bool, string, string) {
	// Make sure that the rule is of the correct format.
	matches := visibilityRuleRegexp.FindStringSubmatch(ruleExpression)
	if ruleExpression == "" || matches == nil {
		// Visibility rule is invalid so ignore it. Keep going rather than aborting straight away to
		// ensure all the rules on this module are checked.
		ctx.PropertyErrorf(property,
			"invalid visibility pattern %q must match"+
				" //<package>:<scope>, //<package> or :<scope> "+
				"where <scope> is one of \"__pkg__\", \"__subpackages__\"",
			ruleExpression)
		return false, "", ""
	}

	// Extract the package and name.
	pkg := matches[1]
	name := matches[2]

	// Normalize the short hands
	if pkg == "" {
		pkg = currentPkg
	}
	if name == "" {
		name = "__pkg__"
	}

	return true, pkg, name
}

func visibilityRuleEnforcer(ctx TopDownMutatorContext) {
	if _, ok := ctx.Module().(Module); !ok {
		return
	}

	qualified := createQualifiedModuleName(ctx)

	// Visit all the dependencies making sure that this module has access to them all.
	ctx.VisitDirectDeps(func(dep Module) {
		// Ignore dependencies that have an ExcludeFromVisibilityEnforcementTag
		tag := ctx.OtherModuleDependencyTag(dep)
		if _, ok := tag.(ExcludeFromVisibilityEnforcementTag); ok {
			return
		}

		depName := ctx.OtherModuleName(dep)
		depDir := ctx.OtherModuleDir(dep)
		depQualified := qualifiedModuleName{depDir, depName}

		// Targets are always visible to other targets in their own package.
		if depQualified.pkg == qualified.pkg {
			return
		}

		rule := effectiveVisibilityRules(ctx.Config(), depQualified)
		if !rule.matches(qualified) {
			ctx.ModuleErrorf("depends on %s which is not visible to this module\nYou may need to add %q to its visibility", depQualified, "//"+ctx.ModuleDir())
		}
	})
}

// Default visibility is public.
var defaultVisibility = compositeRule{publicRule{}}

// Return the effective visibility rules.
//
// If no rules have been specified this will return the default visibility rule
// which is currently //visibility:public.
func effectiveVisibilityRules(config Config, qualified qualifiedModuleName) compositeRule {
	moduleToVisibilityRule := moduleToVisibilityRuleMap(config)
	value, ok := moduleToVisibilityRule.Load(qualified)
	var rule compositeRule
	if ok {
		rule = value.(compositeRule)
	} else {
		rule = packageDefaultVisibility(config, qualified)
	}

	// If no rule is specified then return the default visibility rule to avoid
	// every caller having to treat nil as public.
	if rule == nil {
		rule = defaultVisibility
	}
	return rule
}

func createQualifiedModuleName(ctx BaseModuleContext) qualifiedModuleName {
	moduleName := ctx.ModuleName()
	dir := ctx.ModuleDir()
	qualified := qualifiedModuleName{dir, moduleName}
	return qualified
}

func packageDefaultVisibility(config Config, moduleId qualifiedModuleName) compositeRule {
	moduleToVisibilityRule := moduleToVisibilityRuleMap(config)
	packageQualifiedId := moduleId.getContainingPackageId()
	for {
		value, ok := moduleToVisibilityRule.Load(packageQualifiedId)
		if ok {
			return value.(compositeRule)
		}

		if packageQualifiedId.isRootPackage() {
			return nil
		}

		packageQualifiedId = packageQualifiedId.getContainingPackageId()
	}
}

type VisibilityRuleSet interface {
	// Widen the visibility with some extra rules.
	Widen(extra []string) error

	Strings() []string
}

type visibilityRuleSet struct {
	rules []string
}

var _ VisibilityRuleSet = (*visibilityRuleSet)(nil)

func (v *visibilityRuleSet) Widen(extra []string) error {
	// Check the extra rules first just in case they are invalid. Otherwise, if
	// the current visibility is public then the extra rules will just be ignored.
	if len(extra) == 1 {
		singularRule := extra[0]
		switch singularRule {
		case "//visibility:public":
			// Public overrides everything so just discard any existing rules.
			v.rules = extra
			return nil
		case "//visibility:private":
			// Extending rule with private is an error.
			return fmt.Errorf("%q does not widen the visibility", singularRule)
		}
	}

	if len(v.rules) == 1 {
		switch v.rules[0] {
		case "//visibility:public":
			// No point in adding rules to something which is already public.
			return nil
		case "//visibility:private":
			// Adding any rules to private means it is no longer private so the
			// private can be discarded.
			v.rules = nil
		}
	}

	v.rules = FirstUniqueStrings(append(v.rules, extra...))
	sort.Strings(v.rules)
	return nil
}

func (v *visibilityRuleSet) Strings() []string {
	return v.rules
}

// Get the effective visibility rules, i.e. the actual rules that affect the visibility of the
// property irrespective of where they are defined.
//
// Includes visibility rules specified by package default_visibility and/or on defaults.
// Short hand forms, e.g. //:__subpackages__ are replaced with their full form, e.g.
// //package/containing/rule:__subpackages__.
func EffectiveVisibilityRules(ctx BaseModuleContext, module Module) VisibilityRuleSet {
	moduleName := ctx.OtherModuleName(module)
	dir := ctx.OtherModuleDir(module)
	qualified := qualifiedModuleName{dir, moduleName}

	rule := effectiveVisibilityRules(ctx.Config(), qualified)

	// Modules are implicitly visible to other modules in the same package,
	// without checking the visibility rules. Here we need to add that visibility
	// explicitly.
	if !rule.matches(qualified) {
		if len(rule) == 1 {
			if _, ok := rule[0].(privateRule); ok {
				// If the rule is //visibility:private we can't append another
				// visibility to it. Semantically we need to convert it to a package
				// visibility rule for the location where the result is used, but since
				// modules are implicitly visible within the package we get the same
				// result without any rule at all, so just make it an empty list to be
				// appended below.
				rule = nil
			}
		}
		rule = append(rule, packageRule{dir})
	}

	return &visibilityRuleSet{rule.Strings()}
}

// Clear the default visibility properties so they can be replaced.
func clearVisibilityProperties(module Module) {
	module.base().visibilityPropertyInfo = nil
}

// Add a property that contains visibility rules so that they are checked for
// correctness.
func AddVisibilityProperty(module Module, name string, stringsProperty *[]string) {
	addVisibilityProperty(module, name, stringsProperty)
}

func addVisibilityProperty(module Module, name string, stringsProperty *[]string) visibilityProperty {
	base := module.base()
	property := newVisibilityProperty(name, stringsProperty)
	base.visibilityPropertyInfo = append(base.visibilityPropertyInfo, property)
	return property
}

// Set the primary visibility property.
//
// Also adds the property to the list of properties to be validated.
func setPrimaryVisibilityProperty(module Module, name string, stringsProperty *[]string) {
	module.base().primaryVisibilityProperty = addVisibilityProperty(module, name, stringsProperty)
}
