// Copyright 2020 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 cc

// This file contains image variant related things, including image mutator functions, utility
// functions to determine where a module is installed, etc.

import (
	"fmt"
	"reflect"
	"strings"

	"android/soong/android"
	"android/soong/snapshot"
)

var _ android.ImageInterface = (*Module)(nil)

type ImageVariantType string

const (
	coreImageVariant          ImageVariantType = "core"
	vendorImageVariant        ImageVariantType = "vendor"
	productImageVariant       ImageVariantType = "product"
	ramdiskImageVariant       ImageVariantType = "ramdisk"
	vendorRamdiskImageVariant ImageVariantType = "vendor_ramdisk"
	recoveryImageVariant      ImageVariantType = "recovery"
	hostImageVariant          ImageVariantType = "host"
)

const (
	// VendorVariationPrefix is the variant prefix used for /vendor code that compiles
	// against the VNDK.
	VendorVariationPrefix = "vendor."

	// ProductVariationPrefix is the variant prefix used for /product code that compiles
	// against the VNDK.
	ProductVariationPrefix = "product."
)

func (ctx *moduleContext) ProductSpecific() bool {
	return ctx.ModuleContext.ProductSpecific() || ctx.mod.productSpecificModuleContext()
}

func (ctx *moduleContext) SocSpecific() bool {
	return ctx.ModuleContext.SocSpecific() || ctx.mod.socSpecificModuleContext()
}

func (ctx *moduleContext) DeviceSpecific() bool {
	return ctx.ModuleContext.DeviceSpecific() || ctx.mod.deviceSpecificModuleContext()
}

func (ctx *moduleContextImpl) inProduct() bool {
	return ctx.mod.InProduct()
}

func (ctx *moduleContextImpl) inVendor() bool {
	return ctx.mod.InVendor()
}

func (ctx *moduleContextImpl) inRamdisk() bool {
	return ctx.mod.InRamdisk()
}

func (ctx *moduleContextImpl) inVendorRamdisk() bool {
	return ctx.mod.InVendorRamdisk()
}

func (ctx *moduleContextImpl) inRecovery() bool {
	return ctx.mod.InRecovery()
}

func (c *Module) productSpecificModuleContext() bool {
	// Additionally check if this module is inProduct() that means it is a "product" variant of a
	// module. As well as product specific modules, product variants must be installed to /product.
	return c.InProduct()
}

func (c *Module) socSpecificModuleContext() bool {
	// Additionally check if this module is inVendor() that means it is a "vendor" variant of a
	// module. As well as SoC specific modules, vendor variants must be installed to /vendor
	// unless they have "odm_available: true".
	return c.HasVendorVariant() && c.InVendor() && !c.VendorVariantToOdm()
}

func (c *Module) deviceSpecificModuleContext() bool {
	// Some vendor variants want to be installed to /odm by setting "odm_available: true".
	return c.InVendor() && c.VendorVariantToOdm()
}

// Returns true when this module is configured to have core and vendor variants.
func (c *Module) HasVendorVariant() bool {
	return Bool(c.VendorProperties.Vendor_available) || Bool(c.VendorProperties.Odm_available)
}

// Returns true when this module creates a vendor variant and wants to install the vendor variant
// to the odm partition.
func (c *Module) VendorVariantToOdm() bool {
	return Bool(c.VendorProperties.Odm_available)
}

// Returns true when this module is configured to have core and product variants.
func (c *Module) HasProductVariant() bool {
	return Bool(c.VendorProperties.Product_available)
}

// Returns true when this module is configured to have core and either product or vendor variants.
func (c *Module) HasNonSystemVariants() bool {
	return c.HasVendorVariant() || c.HasProductVariant()
}

// Returns true if the module is "product" variant. Usually these modules are installed in /product
func (c *Module) InProduct() bool {
	return c.Properties.ImageVariationPrefix == ProductVariationPrefix
}

// Returns true if the module is "vendor" variant. Usually these modules are installed in /vendor
func (c *Module) InVendor() bool {
	return c.Properties.ImageVariationPrefix == VendorVariationPrefix
}

func (c *Module) InRamdisk() bool {
	return c.ModuleBase.InRamdisk() || c.ModuleBase.InstallInRamdisk()
}

func (c *Module) InVendorRamdisk() bool {
	return c.ModuleBase.InVendorRamdisk() || c.ModuleBase.InstallInVendorRamdisk()
}

func (c *Module) InRecovery() bool {
	return c.ModuleBase.InRecovery() || c.ModuleBase.InstallInRecovery()
}

func (c *Module) OnlyInRamdisk() bool {
	return c.ModuleBase.InstallInRamdisk()
}

func (c *Module) OnlyInVendorRamdisk() bool {
	return c.ModuleBase.InstallInVendorRamdisk()
}

func (c *Module) OnlyInRecovery() bool {
	return c.ModuleBase.InstallInRecovery()
}

func visitPropsAndCompareVendorAndProductProps(v reflect.Value) bool {
	if v.Kind() != reflect.Struct {
		return true
	}
	for i := 0; i < v.NumField(); i++ {
		prop := v.Field(i)
		if prop.Kind() == reflect.Struct && v.Type().Field(i).Name == "Target" {
			vendor_prop := prop.FieldByName("Vendor")
			product_prop := prop.FieldByName("Product")
			if vendor_prop.Kind() != reflect.Struct && product_prop.Kind() != reflect.Struct {
				// Neither Target.Vendor nor Target.Product is defined
				continue
			}
			if vendor_prop.Kind() != reflect.Struct || product_prop.Kind() != reflect.Struct ||
				!reflect.DeepEqual(vendor_prop.Interface(), product_prop.Interface()) {
				// If only one of either Target.Vendor or Target.Product is
				// defined or they have different values, it fails the build
				// since VNDK must have the same properties for both vendor
				// and product variants.
				return false
			}
		} else if !visitPropsAndCompareVendorAndProductProps(prop) {
			// Visit the substructures to find Target.Vendor and Target.Product
			return false
		}
	}
	return true
}

// In the case of VNDK, vendor and product variants must have the same properties.
// VNDK installs only one file and shares it for both vendor and product modules on
// runtime. We may not define different versions of a VNDK lib for each partition.
// This function is used only for the VNDK modules that is available to both vendor
// and product partitions.
func (c *Module) compareVendorAndProductProps() bool {
	if !c.IsVndk() && !Bool(c.VendorProperties.Product_available) {
		panic(fmt.Errorf("This is only for product available VNDK libs. %q is not a VNDK library or not product available", c.Name()))
	}
	for _, properties := range c.GetProperties() {
		if !visitPropsAndCompareVendorAndProductProps(reflect.ValueOf(properties).Elem()) {
			return false
		}
	}
	return true
}

// ImageMutatableModule provides a common image mutation interface for  LinkableInterface modules.
type ImageMutatableModule interface {
	android.Module
	LinkableInterface

	// AndroidModuleBase returns the android.ModuleBase for this module
	AndroidModuleBase() *android.ModuleBase

	// VendorAvailable returns true if this module is available on the vendor image.
	VendorAvailable() bool

	// OdmAvailable returns true if this module is available on the odm image.
	OdmAvailable() bool

	// ProductAvailable returns true if this module is available on the product image.
	ProductAvailable() bool

	// RamdiskAvailable returns true if this module is available on the ramdisk image.
	RamdiskAvailable() bool

	// RecoveryAvailable returns true if this module is available on the recovery image.
	RecoveryAvailable() bool

	// VendorRamdiskAvailable returns true if this module is available on the vendor ramdisk image.
	VendorRamdiskAvailable() bool

	// IsSnapshotPrebuilt returns true if this module is a snapshot prebuilt.
	IsSnapshotPrebuilt() bool

	// SnapshotVersion returns the snapshot version for this module.
	SnapshotVersion(mctx android.BaseModuleContext) string

	// SdkVersion returns the SDK version for this module.
	SdkVersion() string

	// ExtraVariants returns the list of extra variants this module requires.
	ExtraVariants() []string

	// AppendExtraVariant returns an extra variant to the list of extra variants this module requires.
	AppendExtraVariant(extraVariant string)

	// SetRamdiskVariantNeeded sets whether the Ramdisk Variant is needed.
	SetRamdiskVariantNeeded(b bool)

	// SetVendorRamdiskVariantNeeded sets whether the Vendor Ramdisk Variant is needed.
	SetVendorRamdiskVariantNeeded(b bool)

	// SetRecoveryVariantNeeded sets whether the Recovery Variant is needed.
	SetRecoveryVariantNeeded(b bool)

	// SetCoreVariantNeeded sets whether the Core Variant is needed.
	SetCoreVariantNeeded(b bool)
}

var _ ImageMutatableModule = (*Module)(nil)

func (m *Module) ImageMutatorBegin(mctx android.BaseModuleContext) {
	m.CheckVndkProperties(mctx)
	MutateImage(mctx, m)
}

// CheckVndkProperties checks whether the VNDK-related properties are set correctly.
// If properties are not set correctly, results in a module context property error.
func (m *Module) CheckVndkProperties(mctx android.BaseModuleContext) {
	vendorSpecific := mctx.SocSpecific() || mctx.DeviceSpecific()
	productSpecific := mctx.ProductSpecific()

	if vndkdep := m.vndkdep; vndkdep != nil {
		if vndkdep.isVndk() {
			if vendorSpecific || productSpecific {
				if !vndkdep.isVndkExt() {
					mctx.PropertyErrorf("vndk",
						"must set `extends: \"...\"` to vndk extension")
				} else if Bool(m.VendorProperties.Vendor_available) {
					mctx.PropertyErrorf("vendor_available",
						"must not set at the same time as `vndk: {extends: \"...\"}`")
				} else if Bool(m.VendorProperties.Product_available) {
					mctx.PropertyErrorf("product_available",
						"must not set at the same time as `vndk: {extends: \"...\"}`")
				}
			} else {
				if vndkdep.isVndkExt() {
					mctx.PropertyErrorf("vndk",
						"must set `vendor: true` or `product_specific: true` to set `extends: %q`",
						m.getVndkExtendsModuleName())
				}
				if !Bool(m.VendorProperties.Vendor_available) {
					mctx.PropertyErrorf("vndk",
						"vendor_available must be set to true when `vndk: {enabled: true}`")
				}
				if Bool(m.VendorProperties.Product_available) {
					// If a VNDK module creates both product and vendor variants, they
					// must have the same properties since they share a single VNDK
					// library on runtime.
					if !m.compareVendorAndProductProps() {
						mctx.ModuleErrorf("product properties must have the same values with the vendor properties for VNDK modules")
					}
				}
			}
		} else {
			if vndkdep.isVndkSp() {
				mctx.PropertyErrorf("vndk",
					"must set `enabled: true` to set `support_system_process: true`")
			}
			if vndkdep.isVndkExt() {
				mctx.PropertyErrorf("vndk",
					"must set `enabled: true` to set `extends: %q`",
					m.getVndkExtendsModuleName())
			}
		}
	}
}

func (m *Module) VendorAvailable() bool {
	return Bool(m.VendorProperties.Vendor_available)
}

func (m *Module) OdmAvailable() bool {
	return Bool(m.VendorProperties.Odm_available)
}

func (m *Module) ProductAvailable() bool {
	return Bool(m.VendorProperties.Product_available)
}

func (m *Module) RamdiskAvailable() bool {
	return Bool(m.Properties.Ramdisk_available)
}

func (m *Module) VendorRamdiskAvailable() bool {
	return Bool(m.Properties.Vendor_ramdisk_available)
}

func (m *Module) AndroidModuleBase() *android.ModuleBase {
	return &m.ModuleBase
}

func (m *Module) RecoveryAvailable() bool {
	return Bool(m.Properties.Recovery_available)
}

func (m *Module) ExtraVariants() []string {
	return m.Properties.ExtraVersionedImageVariations
}

func (m *Module) AppendExtraVariant(extraVariant string) {
	m.Properties.ExtraVersionedImageVariations = append(m.Properties.ExtraVersionedImageVariations, extraVariant)
}

func (m *Module) SetRamdiskVariantNeeded(b bool) {
	m.Properties.RamdiskVariantNeeded = b
}

func (m *Module) SetVendorRamdiskVariantNeeded(b bool) {
	m.Properties.VendorRamdiskVariantNeeded = b
}

func (m *Module) SetRecoveryVariantNeeded(b bool) {
	m.Properties.RecoveryVariantNeeded = b
}

func (m *Module) SetCoreVariantNeeded(b bool) {
	m.Properties.CoreVariantNeeded = b
}

func (m *Module) SnapshotVersion(mctx android.BaseModuleContext) string {
	if snapshot, ok := m.linker.(SnapshotInterface); ok {
		return snapshot.Version()
	} else {
		mctx.ModuleErrorf("version is unknown for snapshot prebuilt")
		// Should we be panicking here instead?
		return ""
	}
}

func (m *Module) KernelHeadersDecorator() bool {
	if _, ok := m.linker.(*kernelHeadersDecorator); ok {
		return true
	}
	return false
}

// MutateImage handles common image mutations for ImageMutatableModule interfaces.
func MutateImage(mctx android.BaseModuleContext, m ImageMutatableModule) {
	// Validation check
	vendorSpecific := mctx.SocSpecific() || mctx.DeviceSpecific()
	productSpecific := mctx.ProductSpecific()

	if m.VendorAvailable() {
		if vendorSpecific {
			mctx.PropertyErrorf("vendor_available",
				"doesn't make sense at the same time as `vendor: true`, `proprietary: true`, or `device_specific: true`")
		}
		if m.OdmAvailable() {
			mctx.PropertyErrorf("vendor_available",
				"doesn't make sense at the same time as `odm_available: true`")
		}
	}

	if m.OdmAvailable() {
		if vendorSpecific {
			mctx.PropertyErrorf("odm_available",
				"doesn't make sense at the same time as `vendor: true`, `proprietary: true`, or `device_specific: true`")
		}
	}

	if m.ProductAvailable() {
		if productSpecific {
			mctx.PropertyErrorf("product_available",
				"doesn't make sense at the same time as `product_specific: true`")
		}
		if vendorSpecific {
			mctx.PropertyErrorf("product_available",
				"cannot provide product variant from a vendor module. Please use `product_specific: true` with `vendor_available: true`")
		}
	}

	var coreVariantNeeded bool = false
	var ramdiskVariantNeeded bool = false
	var vendorRamdiskVariantNeeded bool = false
	var recoveryVariantNeeded bool = false

	var vendorVariants []string
	var productVariants []string

	platformVndkVersion := mctx.DeviceConfig().PlatformVndkVersion()
	boardVndkVersion := mctx.DeviceConfig().VndkVersion()
	productVndkVersion := mctx.DeviceConfig().ProductVndkVersion()
	recoverySnapshotVersion := mctx.DeviceConfig().RecoverySnapshotVersion()
	usingRecoverySnapshot := recoverySnapshotVersion != "current" &&
		recoverySnapshotVersion != ""
	needVndkVersionVendorVariantForLlndk := false
	if boardVndkVersion != "" {
		boardVndkApiLevel, err := android.ApiLevelFromUser(mctx, boardVndkVersion)
		if err == nil && !boardVndkApiLevel.IsPreview() {
			// VNDK snapshot newer than v30 has LLNDK stub libraries.
			// Only the VNDK version less than or equal to v30 requires generating the vendor
			// variant of the VNDK version from the source tree.
			needVndkVersionVendorVariantForLlndk = boardVndkApiLevel.LessThanOrEqualTo(android.ApiLevelOrPanic(mctx, "30"))
		}
	}
	if boardVndkVersion == "current" {
		boardVndkVersion = platformVndkVersion
	}
	if productVndkVersion == "current" {
		productVndkVersion = platformVndkVersion
	}

	if m.NeedsLlndkVariants() {
		// This is an LLNDK library.  The implementation of the library will be on /system,
		// and vendor and product variants will be created with LLNDK stubs.
		// The LLNDK libraries need vendor variants even if there is no VNDK.
		coreVariantNeeded = true
		if platformVndkVersion != "" {
			vendorVariants = append(vendorVariants, platformVndkVersion)
			productVariants = append(productVariants, platformVndkVersion)
		}
		// Generate vendor variants for boardVndkVersion only if the VNDK snapshot does not
		// provide the LLNDK stub libraries.
		if needVndkVersionVendorVariantForLlndk {
			vendorVariants = append(vendorVariants, boardVndkVersion)
		}
		if productVndkVersion != "" {
			productVariants = append(productVariants, productVndkVersion)
		}
	} else if m.NeedsVendorPublicLibraryVariants() {
		// A vendor public library has the implementation on /vendor, with stub variants
		// for system and product.
		coreVariantNeeded = true
		vendorVariants = append(vendorVariants, boardVndkVersion)
		if platformVndkVersion != "" {
			productVariants = append(productVariants, platformVndkVersion)
		}
		if productVndkVersion != "" {
			productVariants = append(productVariants, productVndkVersion)
		}
	} else if boardVndkVersion == "" {
		// If the device isn't compiling against the VNDK, we always
		// use the core mode.
		coreVariantNeeded = true
	} else if m.IsSnapshotPrebuilt() {
		// Make vendor variants only for the versions in BOARD_VNDK_VERSION and
		// PRODUCT_EXTRA_VNDK_VERSIONS.
		if m.InstallInRecovery() {
			recoveryVariantNeeded = true
		} else {
			vendorVariants = append(vendorVariants, m.SnapshotVersion(mctx))
		}
	} else if m.HasNonSystemVariants() && !m.IsVndkExt() {
		// This will be available to /system unless it is product_specific
		// which will be handled later.
		coreVariantNeeded = true

		// We assume that modules under proprietary paths are compatible for
		// BOARD_VNDK_VERSION. The other modules are regarded as AOSP, or
		// PLATFORM_VNDK_VERSION.
		if m.HasVendorVariant() {
			if snapshot.IsVendorProprietaryModule(mctx) {
				vendorVariants = append(vendorVariants, boardVndkVersion)
			} else {
				vendorVariants = append(vendorVariants, platformVndkVersion)
			}
		}

		// product_available modules are available to /product.
		if m.HasProductVariant() {
			productVariants = append(productVariants, platformVndkVersion)
			// VNDK is always PLATFORM_VNDK_VERSION
			if !m.IsVndk() {
				productVariants = append(productVariants, productVndkVersion)
			}
		}
	} else if vendorSpecific && m.SdkVersion() == "" {
		// This will be available in /vendor (or /odm) only

		// kernel_headers is a special module type whose exported headers
		// are coming from DeviceKernelHeaders() which is always vendor
		// dependent. They'll always have both vendor variants.
		// For other modules, we assume that modules under proprietary
		// paths are compatible for BOARD_VNDK_VERSION. The other modules
		// are regarded as AOSP, which is PLATFORM_VNDK_VERSION.
		if m.KernelHeadersDecorator() {
			vendorVariants = append(vendorVariants,
				platformVndkVersion,
				boardVndkVersion,
			)
		} else if snapshot.IsVendorProprietaryModule(mctx) {
			vendorVariants = append(vendorVariants, boardVndkVersion)
		} else {
			vendorVariants = append(vendorVariants, platformVndkVersion)
		}
	} else {
		// This is either in /system (or similar: /data), or is a
		// module built with the NDK. Modules built with the NDK
		// will be restricted using the existing link type checks.
		coreVariantNeeded = true
	}

	if boardVndkVersion != "" && productVndkVersion != "" {
		if coreVariantNeeded && productSpecific && m.SdkVersion() == "" {
			// The module has "product_specific: true" that does not create core variant.
			coreVariantNeeded = false
			productVariants = append(productVariants, productVndkVersion)
		}
	} else {
		// Unless PRODUCT_PRODUCT_VNDK_VERSION is set, product partition has no
		// restriction to use system libs.
		// No product variants defined in this case.
		productVariants = []string{}
	}

	if m.RamdiskAvailable() {
		ramdiskVariantNeeded = true
	}

	if m.AndroidModuleBase().InstallInRamdisk() {
		ramdiskVariantNeeded = true
		coreVariantNeeded = false
	}

	if m.VendorRamdiskAvailable() {
		vendorRamdiskVariantNeeded = true
	}

	if m.AndroidModuleBase().InstallInVendorRamdisk() {
		vendorRamdiskVariantNeeded = true
		coreVariantNeeded = false
	}

	if m.RecoveryAvailable() {
		recoveryVariantNeeded = true
	}

	if m.AndroidModuleBase().InstallInRecovery() {
		recoveryVariantNeeded = true
		coreVariantNeeded = false
	}

	// If using a snapshot, the recovery variant under AOSP directories is not needed,
	// except for kernel headers, which needs all variants.
	if !m.KernelHeadersDecorator() &&
		!m.IsSnapshotPrebuilt() &&
		usingRecoverySnapshot &&
		!snapshot.IsRecoveryProprietaryModule(mctx) {
		recoveryVariantNeeded = false
	}

	for _, variant := range android.FirstUniqueStrings(vendorVariants) {
		m.AppendExtraVariant(VendorVariationPrefix + variant)
	}

	for _, variant := range android.FirstUniqueStrings(productVariants) {
		m.AppendExtraVariant(ProductVariationPrefix + variant)
	}

	m.SetRamdiskVariantNeeded(ramdiskVariantNeeded)
	m.SetVendorRamdiskVariantNeeded(vendorRamdiskVariantNeeded)
	m.SetRecoveryVariantNeeded(recoveryVariantNeeded)
	m.SetCoreVariantNeeded(coreVariantNeeded)

	// Disable the module if no variants are needed.
	if !ramdiskVariantNeeded &&
		!recoveryVariantNeeded &&
		!coreVariantNeeded &&
		len(m.ExtraVariants()) == 0 {
		m.Disable()
	}
}

func (c *Module) CoreVariantNeeded(ctx android.BaseModuleContext) bool {
	return c.Properties.CoreVariantNeeded
}

func (c *Module) RamdiskVariantNeeded(ctx android.BaseModuleContext) bool {
	return c.Properties.RamdiskVariantNeeded
}

func (c *Module) VendorRamdiskVariantNeeded(ctx android.BaseModuleContext) bool {
	return c.Properties.VendorRamdiskVariantNeeded
}

func (c *Module) DebugRamdiskVariantNeeded(ctx android.BaseModuleContext) bool {
	return false
}

func (c *Module) RecoveryVariantNeeded(ctx android.BaseModuleContext) bool {
	return c.Properties.RecoveryVariantNeeded
}

func (c *Module) ExtraImageVariations(ctx android.BaseModuleContext) []string {
	return c.Properties.ExtraVersionedImageVariations
}

func squashVendorSrcs(m *Module) {
	if lib, ok := m.compiler.(*libraryDecorator); ok {
		lib.baseCompiler.Properties.Srcs = append(lib.baseCompiler.Properties.Srcs,
			lib.baseCompiler.Properties.Target.Vendor.Srcs...)

		lib.baseCompiler.Properties.Exclude_srcs = append(lib.baseCompiler.Properties.Exclude_srcs,
			lib.baseCompiler.Properties.Target.Vendor.Exclude_srcs...)

		lib.baseCompiler.Properties.Exclude_generated_sources = append(lib.baseCompiler.Properties.Exclude_generated_sources,
			lib.baseCompiler.Properties.Target.Vendor.Exclude_generated_sources...)
	}
}

func squashProductSrcs(m *Module) {
	if lib, ok := m.compiler.(*libraryDecorator); ok {
		lib.baseCompiler.Properties.Srcs = append(lib.baseCompiler.Properties.Srcs,
			lib.baseCompiler.Properties.Target.Product.Srcs...)

		lib.baseCompiler.Properties.Exclude_srcs = append(lib.baseCompiler.Properties.Exclude_srcs,
			lib.baseCompiler.Properties.Target.Product.Exclude_srcs...)

		lib.baseCompiler.Properties.Exclude_generated_sources = append(lib.baseCompiler.Properties.Exclude_generated_sources,
			lib.baseCompiler.Properties.Target.Product.Exclude_generated_sources...)
	}
}

func squashRecoverySrcs(m *Module) {
	if lib, ok := m.compiler.(*libraryDecorator); ok {
		lib.baseCompiler.Properties.Srcs = append(lib.baseCompiler.Properties.Srcs,
			lib.baseCompiler.Properties.Target.Recovery.Srcs...)

		lib.baseCompiler.Properties.Exclude_srcs = append(lib.baseCompiler.Properties.Exclude_srcs,
			lib.baseCompiler.Properties.Target.Recovery.Exclude_srcs...)

		lib.baseCompiler.Properties.Exclude_generated_sources = append(lib.baseCompiler.Properties.Exclude_generated_sources,
			lib.baseCompiler.Properties.Target.Recovery.Exclude_generated_sources...)
	}
}

func squashVendorRamdiskSrcs(m *Module) {
	if lib, ok := m.compiler.(*libraryDecorator); ok {
		lib.baseCompiler.Properties.Exclude_srcs = append(lib.baseCompiler.Properties.Exclude_srcs, lib.baseCompiler.Properties.Target.Vendor_ramdisk.Exclude_srcs...)
	}
}

func squashRamdiskSrcs(m *Module) {
	if lib, ok := m.compiler.(*libraryDecorator); ok {
		lib.baseCompiler.Properties.Exclude_srcs = append(lib.baseCompiler.Properties.Exclude_srcs, lib.baseCompiler.Properties.Target.Ramdisk.Exclude_srcs...)
	}
}

func (c *Module) SetImageVariation(ctx android.BaseModuleContext, variant string, module android.Module) {
	m := module.(*Module)
	if variant == android.RamdiskVariation {
		m.MakeAsPlatform()
		squashRamdiskSrcs(m)
	} else if variant == android.VendorRamdiskVariation {
		m.MakeAsPlatform()
		squashVendorRamdiskSrcs(m)
	} else if variant == android.RecoveryVariation {
		m.MakeAsPlatform()
		squashRecoverySrcs(m)
	} else if strings.HasPrefix(variant, VendorVariationPrefix) {
		m.Properties.ImageVariationPrefix = VendorVariationPrefix
		m.Properties.VndkVersion = strings.TrimPrefix(variant, VendorVariationPrefix)
		squashVendorSrcs(m)

		// Makefile shouldn't know vendor modules other than BOARD_VNDK_VERSION.
		// Hide other vendor variants to avoid collision.
		vndkVersion := ctx.DeviceConfig().VndkVersion()
		if vndkVersion != "current" && vndkVersion != "" && vndkVersion != m.Properties.VndkVersion {
			m.Properties.HideFromMake = true
			m.HideFromMake()
		}
	} else if strings.HasPrefix(variant, ProductVariationPrefix) {
		m.Properties.ImageVariationPrefix = ProductVariationPrefix
		m.Properties.VndkVersion = strings.TrimPrefix(variant, ProductVariationPrefix)
		squashProductSrcs(m)
	}

	if c.NeedsVendorPublicLibraryVariants() &&
		(variant == android.CoreVariation || strings.HasPrefix(variant, ProductVariationPrefix)) {
		c.VendorProperties.IsVendorPublicLibrary = true
	}
}
