// Copyright (C) 2019 The Android Open Source Project
//
// 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"
	"sort"
	"strings"

	"github.com/google/blueprint"
	"github.com/google/blueprint/proptools"
)

// sdkAwareWithoutModule is provided simply to improve code navigation with the IDE.
type sdkAwareWithoutModule interface {
	// SdkMemberComponentName will return the name to use for a component of this module based on the
	// base name of this module.
	//
	// The baseName is the name returned by ModuleBase.BaseModuleName(), i.e. the name specified in
	// the name property in the .bp file so will not include the prebuilt_ prefix.
	//
	// The componentNameCreator is a func for creating the name of a component from the base name of
	// the module, e.g. it could just append ".component" to the name passed in.
	//
	// This is intended to be called by prebuilt modules that create component models. It is because
	// prebuilt module base names come in a variety of different forms:
	// * unversioned - this is the same as the source module.
	// * internal to an sdk - this is the unversioned name prefixed by the base name of the sdk
	//   module.
	// * versioned - this is the same as the internal with the addition of an "@<version>" suffix.
	//
	// While this can be called from a source module in that case it will behave the same way as the
	// unversioned name and return the result of calling the componentNameCreator func on the supplied
	// base name.
	//
	// e.g. Assuming the componentNameCreator func simply appends ".component" to the name passed in
	// then this will work as follows:
	// * An unversioned name of "foo" will return "foo.component".
	// * An internal to the sdk name of "sdk_foo" will return "sdk_foo.component".
	// * A versioned name of "sdk_foo@current" will return "sdk_foo.component@current".
	//
	// Note that in the latter case the ".component" suffix is added before the version. Adding it
	// after would change the version.
	SdkMemberComponentName(baseName string, componentNameCreator func(string) string) string

	sdkBase() *SdkBase
	MakeMemberOf(sdk SdkRef)
	IsInAnySdk() bool

	// IsVersioned determines whether the module is versioned, i.e. has a name of the form
	// <name>@<version>
	IsVersioned() bool

	ContainingSdk() SdkRef
	MemberName() string
}

// SdkAware is the interface that must be supported by any module to become a member of SDK or to be
// built with SDK
type SdkAware interface {
	Module
	sdkAwareWithoutModule
}

// SdkRef refers to a version of an SDK
type SdkRef struct {
	Name    string
	Version string
}

// Unversioned determines if the SdkRef is referencing to the unversioned SDK module
func (s SdkRef) Unversioned() bool {
	return s.Version == ""
}

// String returns string representation of this SdkRef for debugging purpose
func (s SdkRef) String() string {
	if s.Name == "" {
		return "(No Sdk)"
	}
	if s.Unversioned() {
		return s.Name
	}
	return s.Name + string(SdkVersionSeparator) + s.Version
}

// SdkVersionSeparator is a character used to separate an sdk name and its version
const SdkVersionSeparator = '@'

// ParseSdkRef parses a `name@version` style string into a corresponding SdkRef struct
func ParseSdkRef(ctx BaseModuleContext, str string, property string) SdkRef {
	tokens := strings.Split(str, string(SdkVersionSeparator))
	if len(tokens) < 1 || len(tokens) > 2 {
		ctx.PropertyErrorf(property, "%q does not follow name@version syntax", str)
		return SdkRef{Name: "invalid sdk name", Version: "invalid sdk version"}
	}

	name := tokens[0]

	var version string
	if len(tokens) == 2 {
		version = tokens[1]
	}

	return SdkRef{Name: name, Version: version}
}

type SdkRefs []SdkRef

// Contains tells if the given SdkRef is in this list of SdkRef's
func (refs SdkRefs) Contains(s SdkRef) bool {
	for _, r := range refs {
		if r == s {
			return true
		}
	}
	return false
}

type sdkProperties struct {
	// The SDK that this module is a member of. nil if it is not a member of any SDK
	ContainingSdk *SdkRef `blueprint:"mutated"`

	// Name of the module that this sdk member is representing
	Sdk_member_name *string
}

// SdkBase is a struct that is expected to be included in module types to implement the SdkAware
// interface. InitSdkAwareModule should be called to initialize this struct.
type SdkBase struct {
	properties sdkProperties
	module     SdkAware
}

func (s *SdkBase) sdkBase() *SdkBase {
	return s
}

func (s *SdkBase) SdkMemberComponentName(baseName string, componentNameCreator func(string) string) string {
	if s.MemberName() == "" {
		return componentNameCreator(baseName)
	} else {
		index := strings.LastIndex(baseName, "@")
		unversionedName := baseName[:index]
		unversionedComponentName := componentNameCreator(unversionedName)
		versionSuffix := baseName[index:]
		return unversionedComponentName + versionSuffix
	}
}

// MakeMemberOf sets this module to be a member of a specific SDK
func (s *SdkBase) MakeMemberOf(sdk SdkRef) {
	s.properties.ContainingSdk = &sdk
}

// IsInAnySdk returns true if this module is a member of any SDK
func (s *SdkBase) IsInAnySdk() bool {
	return s.properties.ContainingSdk != nil
}

// IsVersioned returns true if this module is versioned.
func (s *SdkBase) IsVersioned() bool {
	return strings.Contains(s.module.Name(), "@")
}

// ContainingSdk returns the SDK that this module is a member of
func (s *SdkBase) ContainingSdk() SdkRef {
	if s.properties.ContainingSdk != nil {
		return *s.properties.ContainingSdk
	}
	return SdkRef{Name: "", Version: ""}
}

// MemberName returns the name of the module that this SDK member is overriding
func (s *SdkBase) MemberName() string {
	return proptools.String(s.properties.Sdk_member_name)
}

// InitSdkAwareModule initializes the SdkBase struct. This must be called by all modules including
// SdkBase.
func InitSdkAwareModule(m SdkAware) {
	base := m.sdkBase()
	base.module = m
	m.AddProperties(&base.properties)
}

// IsModuleInVersionedSdk returns true if the module is an versioned sdk.
func IsModuleInVersionedSdk(module Module) bool {
	if s, ok := module.(SdkAware); ok {
		if !s.ContainingSdk().Unversioned() {
			return true
		}
	}
	return false
}

// SnapshotBuilder provides support for generating the build rules which will build the snapshot.
type SnapshotBuilder interface {
	// CopyToSnapshot generates a rule that will copy the src to the dest (which is a snapshot
	// relative path) and add the dest to the zip.
	CopyToSnapshot(src Path, dest string)

	// EmptyFile returns the path to an empty file.
	//
	// This can be used by sdk member types that need to create an empty file in the snapshot, simply
	// pass the value returned from this to the CopyToSnapshot() method.
	EmptyFile() Path

	// UnzipToSnapshot generates a rule that will unzip the supplied zip into the snapshot relative
	// directory destDir.
	UnzipToSnapshot(zipPath Path, destDir string)

	// AddPrebuiltModule adds a new prebuilt module to the snapshot.
	//
	// It is intended to be called from SdkMemberType.AddPrebuiltModule which can add module type
	// specific properties that are not variant specific. The following properties will be
	// automatically populated before returning.
	//
	// * name
	// * sdk_member_name
	// * prefer
	//
	// Properties that are variant specific will be handled by SdkMemberProperties structure.
	//
	// Each module created by this method can be output to the generated Android.bp file in two
	// different forms, depending on the setting of the SOONG_SDK_SNAPSHOT_VERSION build property.
	// The two forms are:
	// 1. A versioned Soong module that is referenced from a corresponding similarly versioned
	//    snapshot module.
	// 2. An unversioned Soong module that.
	//
	// See sdk/update.go for more information.
	AddPrebuiltModule(member SdkMember, moduleType string) BpModule

	// SdkMemberReferencePropertyTag returns a property tag to use when adding a property to a
	// BpModule that contains references to other sdk members.
	//
	// Using this will ensure that the reference is correctly output for both versioned and
	// unversioned prebuilts in the snapshot.
	//
	// "required: true" means that the property must only contain references to other members of the
	// sdk. Passing a reference to a module that is not a member of the sdk will result in a build
	// error.
	//
	// "required: false" means that the property can contain references to modules that are either
	// members or not members of the sdk. If a reference is to a module that is a non member then the
	// reference is left unchanged, i.e. it is not transformed as references to members are.
	//
	// The handling of the member names is dependent on whether it is an internal or exported member.
	// An exported member is one whose name is specified in one of the member type specific
	// properties. An internal member is one that is added due to being a part of an exported (or
	// other internal) member and is not itself an exported member.
	//
	// Member names are handled as follows:
	// * When creating the unversioned form of the module the name is left unchecked unless the member
	//   is internal in which case it is transformed into an sdk specific name, i.e. by prefixing with
	//   the sdk name.
	//
	// * When creating the versioned form of the module the name is transformed into a versioned sdk
	//   specific name, i.e. by prefixing with the sdk name and suffixing with the version.
	//
	// e.g.
	// bpPropertySet.AddPropertyWithTag("libs", []string{"member1", "member2"}, builder.SdkMemberReferencePropertyTag(true))
	SdkMemberReferencePropertyTag(required bool) BpPropertyTag
}

// BpPropertyTag is a marker interface that can be associated with properties in a BpPropertySet to
// provide additional information which can be used to customize their behavior.
type BpPropertyTag interface{}

// BpPropertySet is a set of properties for use in a .bp file.
type BpPropertySet interface {
	// AddProperty adds a property.
	//
	// The value can be one of the following types:
	// * string
	// * array of the above
	// * bool
	// For these types it is an error if multiple properties with the same name
	// are added.
	//
	// * pointer to a struct
	// * BpPropertySet
	//
	// A pointer to a Blueprint-style property struct is first converted into a
	// BpPropertySet by traversing the fields and adding their values as
	// properties in a BpPropertySet. A field with a struct value is itself
	// converted into a BpPropertySet before adding.
	//
	// Adding a BpPropertySet is done as follows:
	// * If no property with the name exists then the BpPropertySet is added
	//   directly to this property. Care must be taken to ensure that it does not
	//   introduce a cycle.
	// * If a property exists with the name and the current value is a
	//   BpPropertySet then every property of the new BpPropertySet is added to
	//   the existing BpPropertySet.
	// * Otherwise, if a property exists with the name then it is an error.
	AddProperty(name string, value interface{})

	// AddPropertyWithTag adds a property with an associated property tag.
	AddPropertyWithTag(name string, value interface{}, tag BpPropertyTag)

	// AddPropertySet adds a property set with the specified name and returns it so that additional
	// properties can be added to it.
	AddPropertySet(name string) BpPropertySet

	// AddCommentForProperty adds a comment for the named property (or property set).
	AddCommentForProperty(name, text string)
}

// BpModule represents a module definition in a .bp file.
type BpModule interface {
	BpPropertySet

	// ModuleType returns the module type of the module
	ModuleType() string

	// Name returns the name of the module or "" if no name has been specified.
	Name() string
}

// BpPrintable is a marker interface that must be implemented by any struct that is added as a
// property value.
type BpPrintable interface {
	bpPrintable()
}

// BpPrintableBase must be embedded within any struct that is added as a
// property value.
type BpPrintableBase struct {
}

func (b BpPrintableBase) bpPrintable() {
}

var _ BpPrintable = BpPrintableBase{}

// sdkRegisterable defines the interface that must be implemented by objects that can be registered
// in an sdkRegistry.
type sdkRegisterable interface {
	// SdkPropertyName returns the name of the corresponding property on an sdk module.
	SdkPropertyName() string
}

// sdkRegistry provides support for registering and retrieving objects that define properties for
// use by sdk and module_exports module types.
type sdkRegistry struct {
	// The list of registered objects sorted by property name.
	list []sdkRegisterable
}

// copyAndAppend creates a new sdkRegistry that includes all the traits registered in
// this registry plus the supplied trait.
func (r *sdkRegistry) copyAndAppend(registerable sdkRegisterable) *sdkRegistry {
	oldList := r.list

	// Make sure that list does not already contain the property. Uses a simple linear search instead
	// of a binary search even though the list is sorted. That is because the number of items in the
	// list is small and so not worth the overhead of a binary search.
	found := false
	newPropertyName := registerable.SdkPropertyName()
	for _, r := range oldList {
		if r.SdkPropertyName() == newPropertyName {
			found = true
			break
		}
	}
	if found {
		names := []string{}
		for _, r := range oldList {
			names = append(names, r.SdkPropertyName())
		}
		panic(fmt.Errorf("duplicate properties found, %q already exists in %q", newPropertyName, names))
	}

	// Copy the slice just in case this is being read while being modified, e.g. when testing.
	list := make([]sdkRegisterable, 0, len(oldList)+1)
	list = append(list, oldList...)
	list = append(list, registerable)

	// Sort the registered objects by their property name to ensure that registry order has no effect
	// on behavior.
	sort.Slice(list, func(i1, i2 int) bool {
		t1 := list[i1]
		t2 := list[i2]

		return t1.SdkPropertyName() < t2.SdkPropertyName()
	})

	// Create a new registry so the pointer uniquely identifies the set of registered types.
	return &sdkRegistry{
		list: list,
	}
}

// registeredObjects returns the list of registered instances.
func (r *sdkRegistry) registeredObjects() []sdkRegisterable {
	return r.list
}

// uniqueOnceKey returns a key that uniquely identifies this instance and can be used with
// OncePer.Once
func (r *sdkRegistry) uniqueOnceKey() OnceKey {
	// Use the pointer to the registry as the unique key. The pointer is used because it is guaranteed
	// to uniquely identify the contained list. The list itself cannot be used as slices are not
	// comparable. Using the pointer does mean that two separate registries with identical lists would
	// have different keys and so cause whatever information is cached to be created multiple times.
	// However, that is not an issue in practice as it should not occur outside tests. Constructing a
	// string representation of the list to use instead would avoid that but is an unnecessary
	// complication that provides no significant benefit.
	return NewCustomOnceKey(r)
}

// SdkMemberTrait represents a trait that members of an sdk module can contribute to the sdk
// snapshot.
//
// A trait is simply a characteristic of sdk member that is not required by default which may be
// required for some members but not others. Traits can cause additional information to be output
// to the sdk snapshot or replace the default information exported for a member with something else.
// e.g.
// * By default cc libraries only export the default image variants to the SDK. However, for some
//   members it may be necessary to export specific image variants, e.g. vendor, or recovery.
// * By default cc libraries export all the configured architecture variants except for the native
//   bridge architecture variants. However, for some members it may be necessary to export the
//   native bridge architecture variants as well.
// * By default cc libraries export the platform variant (i.e. sdk:). However, for some members it
//   may be necessary to export the sdk variant (i.e. sdk:sdk).
//
// A sdk can request a module to provide no traits, one trait or a collection of traits. The exact
// behavior of a trait is determined by how SdkMemberType implementations handle the traits. A trait
// could be specific to one SdkMemberType or many. Some trait combinations could be incompatible.
//
// The sdk module type will create a special traits structure that contains a property for each
// trait registered with RegisterSdkMemberTrait(). The property names are those returned from
// SdkPropertyName(). Each property contains a list of modules that are required to have that trait.
// e.g. something like this:
//
//   sdk {
//     name: "sdk",
//     ...
//     traits: {
//       recovery_image: ["module1", "module4", "module5"],
//       native_bridge: ["module1", "module2"],
//       native_sdk: ["module1", "module3"],
//       ...
//     },
//     ...
//   }
type SdkMemberTrait interface {
	// SdkPropertyName returns the name of the traits property on an sdk module.
	SdkPropertyName() string
}

var _ sdkRegisterable = (SdkMemberTrait)(nil)

// SdkMemberTraitBase is the base struct that must be embedded within any type that implements
// SdkMemberTrait.
type SdkMemberTraitBase struct {
	// PropertyName is the name of the property
	PropertyName string
}

func (b *SdkMemberTraitBase) SdkPropertyName() string {
	return b.PropertyName
}

// SdkMemberTraitSet is a set of SdkMemberTrait instances.
type SdkMemberTraitSet interface {
	// Empty returns true if this set is empty.
	Empty() bool

	// Contains returns true if this set contains the specified trait.
	Contains(trait SdkMemberTrait) bool

	// Subtract returns a new set containing all elements of this set except for those in the
	// other set.
	Subtract(other SdkMemberTraitSet) SdkMemberTraitSet

	// String returns a string representation of the set and its contents.
	String() string
}

func NewSdkMemberTraitSet(traits []SdkMemberTrait) SdkMemberTraitSet {
	if len(traits) == 0 {
		return EmptySdkMemberTraitSet()
	}

	m := sdkMemberTraitSet{}
	for _, trait := range traits {
		m[trait] = true
	}
	return m
}

func EmptySdkMemberTraitSet() SdkMemberTraitSet {
	return (sdkMemberTraitSet)(nil)
}

type sdkMemberTraitSet map[SdkMemberTrait]bool

var _ SdkMemberTraitSet = (sdkMemberTraitSet{})

func (s sdkMemberTraitSet) Empty() bool {
	return len(s) == 0
}

func (s sdkMemberTraitSet) Contains(trait SdkMemberTrait) bool {
	return s[trait]
}

func (s sdkMemberTraitSet) Subtract(other SdkMemberTraitSet) SdkMemberTraitSet {
	if other.Empty() {
		return s
	}

	var remainder []SdkMemberTrait
	for trait, _ := range s {
		if !other.Contains(trait) {
			remainder = append(remainder, trait)
		}
	}

	return NewSdkMemberTraitSet(remainder)
}

func (s sdkMemberTraitSet) String() string {
	list := []string{}
	for trait, _ := range s {
		list = append(list, trait.SdkPropertyName())
	}
	sort.Strings(list)
	return fmt.Sprintf("[%s]", strings.Join(list, ","))
}

var registeredSdkMemberTraits = &sdkRegistry{}

// RegisteredSdkMemberTraits returns a OnceKey and a sorted list of registered traits.
//
// The key uniquely identifies the array of traits and can be used with OncePer.Once() to cache
// information derived from the array of traits.
func RegisteredSdkMemberTraits() (OnceKey, []SdkMemberTrait) {
	registerables := registeredSdkMemberTraits.registeredObjects()
	traits := make([]SdkMemberTrait, len(registerables))
	for i, registerable := range registerables {
		traits[i] = registerable.(SdkMemberTrait)
	}
	return registeredSdkMemberTraits.uniqueOnceKey(), traits
}

// RegisterSdkMemberTrait registers an SdkMemberTrait object to allow them to be used in the
// module_exports, module_exports_snapshot, sdk and sdk_snapshot module types.
func RegisterSdkMemberTrait(trait SdkMemberTrait) {
	registeredSdkMemberTraits = registeredSdkMemberTraits.copyAndAppend(trait)
}

// SdkMember is an individual member of the SDK.
//
// It includes all of the variants that the SDK depends upon.
type SdkMember interface {
	// Name returns the name of the member.
	Name() string

	// Variants returns all the variants of this module depended upon by the SDK.
	Variants() []SdkAware
}

// SdkMemberDependencyTag is the interface that a tag must implement in order to allow the
// dependent module to be automatically added to the sdk.
type SdkMemberDependencyTag interface {
	blueprint.DependencyTag

	// SdkMemberType returns the SdkMemberType that will be used to automatically add the child module
	// to the sdk.
	//
	// Returning nil will prevent the module being added to the sdk.
	SdkMemberType(child Module) SdkMemberType

	// ExportMember determines whether a module added to the sdk through this tag will be exported
	// from the sdk or not.
	//
	// An exported member is added to the sdk using its own name, e.g. if "foo" was exported from sdk
	// "bar" then its prebuilt would be simply called "foo". A member can be added to the sdk via
	// multiple tags and if any of those tags returns true from this method then the membe will be
	// exported. Every module added directly to the sdk via one of the member type specific
	// properties, e.g. java_libs, will automatically be exported.
	//
	// If a member is not exported then it is treated as an internal implementation detail of the
	// sdk and so will be added with an sdk specific name. e.g. if "foo" was an internal member of sdk
	// "bar" then its prebuilt would be called "bar_foo". Additionally its visibility will be set to
	// "//visibility:private" so it will not be accessible from outside its Android.bp file.
	ExportMember() bool
}

var _ SdkMemberDependencyTag = (*sdkMemberDependencyTag)(nil)
var _ ReplaceSourceWithPrebuilt = (*sdkMemberDependencyTag)(nil)

type sdkMemberDependencyTag struct {
	blueprint.BaseDependencyTag
	memberType SdkMemberType
	export     bool
}

func (t *sdkMemberDependencyTag) SdkMemberType(_ Module) SdkMemberType {
	return t.memberType
}

func (t *sdkMemberDependencyTag) ExportMember() bool {
	return t.export
}

// ReplaceSourceWithPrebuilt prevents dependencies from the sdk/module_exports onto their members
// from being replaced with a preferred prebuilt.
func (t *sdkMemberDependencyTag) ReplaceSourceWithPrebuilt() bool {
	return false
}

// DependencyTagForSdkMemberType creates an SdkMemberDependencyTag that will cause any
// dependencies added by the tag to be added to the sdk as the specified SdkMemberType and exported
// (or not) as specified by the export parameter.
func DependencyTagForSdkMemberType(memberType SdkMemberType, export bool) SdkMemberDependencyTag {
	return &sdkMemberDependencyTag{memberType: memberType, export: export}
}

// SdkMemberType is the interface that must be implemented for every type that can be a member of an
// sdk.
//
// The basic implementation should look something like this, where ModuleType is
// the name of the module type being supported.
//
//    type moduleTypeSdkMemberType struct {
//        android.SdkMemberTypeBase
//    }
//
//    func init() {
//        android.RegisterSdkMemberType(&moduleTypeSdkMemberType{
//            SdkMemberTypeBase: android.SdkMemberTypeBase{
//                PropertyName: "module_types",
//            },
//        }
//    }
//
//    ...methods...
//
type SdkMemberType interface {
	// SdkPropertyName returns the name of the member type property on an sdk module.
	SdkPropertyName() string

	// RequiresBpProperty returns true if this member type requires its property to be usable within
	// an Android.bp file.
	RequiresBpProperty() bool

	// UsableWithSdkAndSdkSnapshot returns true if the member type supports the sdk/sdk_snapshot,
	// false otherwise.
	UsableWithSdkAndSdkSnapshot() bool

	// IsHostOsDependent returns true if prebuilt host artifacts may be specific to the host OS. Only
	// applicable to modules where HostSupported() is true. If this is true, snapshots will list each
	// host OS variant explicitly and disable all other host OS'es.
	IsHostOsDependent() bool

	// SupportedLinkages returns the names of the linkage variants supported by this module.
	SupportedLinkages() []string

	// AddDependencies adds dependencies from the SDK module to all the module variants the member
	// type contributes to the SDK. `names` is the list of module names given in the member type
	// property (as returned by SdkPropertyName()) in the SDK module. The exact set of variants
	// required is determined by the SDK and its properties. The dependencies must be added with the
	// supplied tag.
	//
	// The BottomUpMutatorContext provided is for the SDK module.
	AddDependencies(ctx SdkDependencyContext, dependencyTag blueprint.DependencyTag, names []string)

	// IsInstance returns true if the supplied module is an instance of this member type.
	//
	// This is used to check the type of each variant before added to the SdkMember. Returning false
	// will cause an error to be logged explaining that the module is not allowed in whichever sdk
	// property it was added.
	IsInstance(module Module) bool

	// UsesSourceModuleTypeInSnapshot returns true when the AddPrebuiltModule() method returns a
	// source module type.
	UsesSourceModuleTypeInSnapshot() bool

	// AddPrebuiltModule is called to add a prebuilt module that the sdk will populate.
	//
	// The sdk module code generates the snapshot as follows:
	//
	// * A properties struct of type SdkMemberProperties is created for each variant and
	//   populated with information from the variant by calling PopulateFromVariant(SdkAware)
	//   on the struct.
	//
	// * An additional properties struct is created into which the common properties will be
	//   added.
	//
	// * The variant property structs are analysed to find exported (capitalized) fields which
	//   have common values. Those fields are cleared and the common value added to the common
	//   properties.
	//
	//   A field annotated with a tag of `sdk:"keep"` will be treated as if it
	//   was not capitalized, i.e. not optimized for common values.
	//
	//   A field annotated with a tag of `android:"arch_variant"` will be allowed to have
	//   values that differ by arch, fields not tagged as such must have common values across
	//   all variants.
	//
	// * Additional field tags can be specified on a field that will ignore certain values
	//   for the purpose of common value optimization. A value that is ignored must have the
	//   default value for the property type. This is to ensure that significant value are not
	//   ignored by accident. The purpose of this is to allow the snapshot generation to reflect
	//   the behavior of the runtime. e.g. if a property is ignored on the host then a property
	//   that is common for android can be treated as if it was common for android and host as
	//   the setting for host is ignored anyway.
	//   * `sdk:"ignored-on-host" - this indicates the property is ignored on the host variant.
	//
	// * The sdk module type populates the BpModule structure, creating the arch specific
	//   structure and calls AddToPropertySet(...) on the properties struct to add the member
	//   specific properties in the correct place in the structure.
	//
	AddPrebuiltModule(ctx SdkMemberContext, member SdkMember) BpModule

	// CreateVariantPropertiesStruct creates a structure into which variant specific properties can be
	// added.
	CreateVariantPropertiesStruct() SdkMemberProperties

	// SupportedTraits returns the set of traits supported by this member type.
	SupportedTraits() SdkMemberTraitSet

	// Overrides returns whether type overrides other SdkMemberType
	Overrides(SdkMemberType) bool
}

var _ sdkRegisterable = (SdkMemberType)(nil)

// SdkDependencyContext provides access to information needed by the SdkMemberType.AddDependencies()
// implementations.
type SdkDependencyContext interface {
	BottomUpMutatorContext

	// RequiredTraits returns the set of SdkMemberTrait instances that the sdk requires the named
	// member to provide.
	RequiredTraits(name string) SdkMemberTraitSet

	// RequiresTrait returns true if the sdk requires the member with the supplied name to provide the
	// supplied trait.
	RequiresTrait(name string, trait SdkMemberTrait) bool
}

// SdkMemberTypeBase is the base type for SdkMemberType implementations and must be embedded in any
// struct that implements SdkMemberType.
type SdkMemberTypeBase struct {
	PropertyName string

	// Property names that this SdkMemberTypeBase can override, this is useful when a module type is a
	// superset of another module type.
	OverridesPropertyNames map[string]bool

	// The names of linkage variants supported by this module.
	SupportedLinkageNames []string

	// When set to true BpPropertyNotRequired indicates that the member type does not require the
	// property to be specifiable in an Android.bp file.
	BpPropertyNotRequired bool

	SupportsSdk     bool
	HostOsDependent bool

	// When set to true UseSourceModuleTypeInSnapshot indicates that the member type creates a source
	// module type in its SdkMemberType.AddPrebuiltModule() method. That prevents the sdk snapshot
	// code from automatically adding a prefer: true flag.
	UseSourceModuleTypeInSnapshot bool

	// The list of supported traits.
	Traits []SdkMemberTrait
}

func (b *SdkMemberTypeBase) SdkPropertyName() string {
	return b.PropertyName
}

func (b *SdkMemberTypeBase) RequiresBpProperty() bool {
	return !b.BpPropertyNotRequired
}

func (b *SdkMemberTypeBase) UsableWithSdkAndSdkSnapshot() bool {
	return b.SupportsSdk
}

func (b *SdkMemberTypeBase) IsHostOsDependent() bool {
	return b.HostOsDependent
}

func (b *SdkMemberTypeBase) UsesSourceModuleTypeInSnapshot() bool {
	return b.UseSourceModuleTypeInSnapshot
}

func (b *SdkMemberTypeBase) SupportedTraits() SdkMemberTraitSet {
	return NewSdkMemberTraitSet(b.Traits)
}

func (b *SdkMemberTypeBase) Overrides(other SdkMemberType) bool {
	return b.OverridesPropertyNames[other.SdkPropertyName()]
}

func (b *SdkMemberTypeBase) SupportedLinkages() []string {
	return b.SupportedLinkageNames
}

// registeredModuleExportsMemberTypes is the set of registered SdkMemberTypes for module_exports
// modules.
var registeredModuleExportsMemberTypes = &sdkRegistry{}

// registeredSdkMemberTypes is the set of registered registeredSdkMemberTypes for sdk modules.
var registeredSdkMemberTypes = &sdkRegistry{}

// RegisteredSdkMemberTypes returns a OnceKey and a sorted list of registered types.
//
// If moduleExports is true then the slice of types includes all registered types that can be used
// with the module_exports and module_exports_snapshot module types. Otherwise, the slice of types
// only includes those registered types that can be used with the sdk and sdk_snapshot module
// types.
//
// The key uniquely identifies the array of types and can be used with OncePer.Once() to cache
// information derived from the array of types.
func RegisteredSdkMemberTypes(moduleExports bool) (OnceKey, []SdkMemberType) {
	var registry *sdkRegistry
	if moduleExports {
		registry = registeredModuleExportsMemberTypes
	} else {
		registry = registeredSdkMemberTypes
	}

	registerables := registry.registeredObjects()
	types := make([]SdkMemberType, len(registerables))
	for i, registerable := range registerables {
		types[i] = registerable.(SdkMemberType)
	}
	return registry.uniqueOnceKey(), types
}

// RegisterSdkMemberType registers an SdkMemberType object to allow them to be used in the
// module_exports, module_exports_snapshot and (depending on the value returned from
// SdkMemberType.UsableWithSdkAndSdkSnapshot) the sdk and sdk_snapshot module types.
func RegisterSdkMemberType(memberType SdkMemberType) {
	// All member types are usable with module_exports.
	registeredModuleExportsMemberTypes = registeredModuleExportsMemberTypes.copyAndAppend(memberType)

	// Only those that explicitly indicate it are usable with sdk.
	if memberType.UsableWithSdkAndSdkSnapshot() {
		registeredSdkMemberTypes = registeredSdkMemberTypes.copyAndAppend(memberType)
	}
}

// SdkMemberPropertiesBase is the base structure for all implementations of SdkMemberProperties and
// must be embedded in any struct that implements SdkMemberProperties.
//
// Contains common properties that apply across many different member types.
type SdkMemberPropertiesBase struct {
	// The number of unique os types supported by the member variants.
	//
	// If a member has a variant with more than one os type then it will need to differentiate
	// the locations of any of their prebuilt files in the snapshot by os type to prevent them
	// from colliding. See OsPrefix().
	//
	// This property is the same for all variants of a member and so would be optimized away
	// if it was not explicitly kept.
	Os_count int `sdk:"keep"`

	// The os type for which these properties refer.
	//
	// Provided to allow a member to differentiate between os types in the locations of their
	// prebuilt files when it supports more than one os type.
	//
	// This property is the same for all os type specific variants of a member and so would be
	// optimized away if it was not explicitly kept.
	Os OsType `sdk:"keep"`

	// The setting to use for the compile_multilib property.
	Compile_multilib string `android:"arch_variant"`
}

// OsPrefix returns the os prefix to use for any file paths in the sdk.
//
// Is an empty string if the member only provides variants for a single os type, otherwise
// is the OsType.Name.
func (b *SdkMemberPropertiesBase) OsPrefix() string {
	if b.Os_count == 1 {
		return ""
	} else {
		return b.Os.Name
	}
}

func (b *SdkMemberPropertiesBase) Base() *SdkMemberPropertiesBase {
	return b
}

// SdkMemberProperties is the interface to be implemented on top of a structure that contains
// variant specific information.
//
// Struct fields that are capitalized are examined for common values to extract. Fields that are not
// capitalized are assumed to be arch specific.
type SdkMemberProperties interface {
	// Base returns the base structure.
	Base() *SdkMemberPropertiesBase

	// PopulateFromVariant populates this structure with information from a module variant.
	//
	// It will typically be called once for each variant of a member module that the SDK depends upon.
	PopulateFromVariant(ctx SdkMemberContext, variant Module)

	// AddToPropertySet adds the information from this structure to the property set.
	//
	// This will be called for each instance of this structure on which the PopulateFromVariant method
	// was called and also on a number of different instances of this structure into which properties
	// common to one or more variants have been copied. Therefore, implementations of this must handle
	// the case when this structure is only partially populated.
	AddToPropertySet(ctx SdkMemberContext, propertySet BpPropertySet)
}

// SdkMemberContext provides access to information common to a specific member.
type SdkMemberContext interface {

	// SdkModuleContext returns the module context of the sdk common os variant which is creating the
	// snapshot.
	//
	// This is common to all members of the sdk and is not specific to the member being processed.
	// If information about the member being processed needs to be obtained from this ModuleContext it
	// must be obtained using one of the OtherModule... methods not the Module... methods.
	SdkModuleContext() ModuleContext

	// SnapshotBuilder the builder of the snapshot.
	SnapshotBuilder() SnapshotBuilder

	// MemberType returns the type of the member currently being processed.
	MemberType() SdkMemberType

	// Name returns the name of the member currently being processed.
	//
	// Provided for use by sdk members to create a member specific location within the snapshot
	// into which to copy the prebuilt files.
	Name() string

	// RequiresTrait returns true if this member is expected to provide the specified trait.
	RequiresTrait(trait SdkMemberTrait) bool
}

// ExportedComponentsInfo contains information about the components that this module exports to an
// sdk snapshot.
//
// A component of a module is a child module that the module creates and which forms an integral
// part of the functionality that the creating module provides. A component module is essentially
// owned by its creator and is tightly coupled to the creator and other components.
//
// e.g. the child modules created by prebuilt_apis are not components because they are not tightly
// coupled to the prebuilt_apis module. Once they are created the prebuilt_apis ignores them. The
// child impl and stub library created by java_sdk_library (and corresponding import) are components
// because the creating module depends upon them in order to provide some of its own functionality.
//
// A component is exported if it is part of an sdk snapshot. e.g. The xml and impl child modules are
// components but they are not exported as they are not part of an sdk snapshot.
//
// This information is used by the sdk snapshot generation code to ensure that it does not create
// an sdk snapshot that contains a declaration of the component module and the module that creates
// it as that would result in duplicate modules when attempting to use the snapshot. e.g. a snapshot
// that included the java_sdk_library_import "foo" and also a java_import "foo.stubs" would fail
// as there would be two modules called "foo.stubs".
type ExportedComponentsInfo struct {
	// The names of the exported components.
	Components []string
}

var ExportedComponentsInfoProvider = blueprint.NewProvider(ExportedComponentsInfo{})

// AdditionalSdkInfo contains additional properties to add to the generated SDK info file.
type AdditionalSdkInfo struct {
	Properties map[string]interface{}
}

var AdditionalSdkInfoProvider = blueprint.NewProvider(AdditionalSdkInfo{})
