// Copyright 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 rust

import (
	"fmt"
	"regexp"
	"strings"

	"android/soong/android"
	"android/soong/bazel"
	"android/soong/cc"

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

var (
	RlibStdlibSuffix = ".rlib-std"
)

func init() {
	android.RegisterModuleType("rust_library", RustLibraryFactory)
	android.RegisterModuleType("rust_library_dylib", RustLibraryDylibFactory)
	android.RegisterModuleType("rust_library_rlib", RustLibraryRlibFactory)
	android.RegisterModuleType("rust_library_host", RustLibraryHostFactory)
	android.RegisterModuleType("rust_library_host_dylib", RustLibraryDylibHostFactory)
	android.RegisterModuleType("rust_library_host_rlib", RustLibraryRlibHostFactory)
	android.RegisterModuleType("rust_ffi", RustFFIFactory)
	android.RegisterModuleType("rust_ffi_shared", RustFFISharedFactory)
	android.RegisterModuleType("rust_ffi_static", RustFFIStaticFactory)
	android.RegisterModuleType("rust_ffi_host", RustFFIHostFactory)
	android.RegisterModuleType("rust_ffi_host_shared", RustFFISharedHostFactory)
	android.RegisterModuleType("rust_ffi_host_static", RustFFIStaticHostFactory)
}

type VariantLibraryProperties struct {
	Enabled *bool    `android:"arch_variant"`
	Srcs    []string `android:"path,arch_variant"`
}

type LibraryCompilerProperties struct {
	Rlib   VariantLibraryProperties `android:"arch_variant"`
	Dylib  VariantLibraryProperties `android:"arch_variant"`
	Shared VariantLibraryProperties `android:"arch_variant"`
	Static VariantLibraryProperties `android:"arch_variant"`

	// path to include directories to pass to cc_* modules, only relevant for static/shared variants.
	Include_dirs []string `android:"path,arch_variant"`

	// Whether this library is part of the Rust toolchain sysroot.
	Sysroot *bool
}

type LibraryMutatedProperties struct {
	// Build a dylib variant
	BuildDylib bool `blueprint:"mutated"`
	// Build an rlib variant
	BuildRlib bool `blueprint:"mutated"`
	// Build a shared library variant
	BuildShared bool `blueprint:"mutated"`
	// Build a static library variant
	BuildStatic bool `blueprint:"mutated"`

	// This variant is a dylib
	VariantIsDylib bool `blueprint:"mutated"`
	// This variant is an rlib
	VariantIsRlib bool `blueprint:"mutated"`
	// This variant is a shared library
	VariantIsShared bool `blueprint:"mutated"`
	// This variant is a static library
	VariantIsStatic bool `blueprint:"mutated"`
	// This variant is a source provider
	VariantIsSource bool `blueprint:"mutated"`

	// This variant is disabled and should not be compiled
	// (used for SourceProvider variants that produce only source)
	VariantIsDisabled bool `blueprint:"mutated"`

	// Whether this library variant should be link libstd via rlibs
	VariantIsStaticStd bool `blueprint:"mutated"`
}

type libraryDecorator struct {
	*baseCompiler
	*flagExporter
	stripper Stripper

	Properties        LibraryCompilerProperties
	MutatedProperties LibraryMutatedProperties
	includeDirs       android.Paths
	sourceProvider    SourceProvider

	collectedSnapshotHeaders android.Paths

	// table-of-contents file for cdylib crates to optimize out relinking when possible
	tocFile android.OptionalPath
}

type libraryInterface interface {
	rlib() bool
	dylib() bool
	static() bool
	shared() bool
	sysroot() bool
	source() bool

	// Returns true if the build options for the module have selected a particular build type
	buildRlib() bool
	buildDylib() bool
	buildShared() bool
	buildStatic() bool

	// Sets a particular variant type
	setRlib()
	setDylib()
	setShared()
	setStatic()
	setSource()

	// libstd linkage functions
	rlibStd() bool
	setRlibStd()
	setDylibStd()

	// Build a specific library variant
	BuildOnlyFFI()
	BuildOnlyRust()
	BuildOnlyRlib()
	BuildOnlyDylib()
	BuildOnlyStatic()
	BuildOnlyShared()

	toc() android.OptionalPath
}

func (library *libraryDecorator) nativeCoverage() bool {
	return true
}

func (library *libraryDecorator) toc() android.OptionalPath {
	return library.tocFile
}

func (library *libraryDecorator) rlib() bool {
	return library.MutatedProperties.VariantIsRlib
}

func (library *libraryDecorator) sysroot() bool {
	return Bool(library.Properties.Sysroot)
}

func (library *libraryDecorator) dylib() bool {
	return library.MutatedProperties.VariantIsDylib
}

func (library *libraryDecorator) shared() bool {
	return library.MutatedProperties.VariantIsShared
}

func (library *libraryDecorator) static() bool {
	return library.MutatedProperties.VariantIsStatic
}

func (library *libraryDecorator) source() bool {
	return library.MutatedProperties.VariantIsSource
}

func (library *libraryDecorator) buildRlib() bool {
	return library.MutatedProperties.BuildRlib && BoolDefault(library.Properties.Rlib.Enabled, true)
}

func (library *libraryDecorator) buildDylib() bool {
	return library.MutatedProperties.BuildDylib && BoolDefault(library.Properties.Dylib.Enabled, true)
}

func (library *libraryDecorator) buildShared() bool {
	return library.MutatedProperties.BuildShared && BoolDefault(library.Properties.Shared.Enabled, true)
}

func (library *libraryDecorator) buildStatic() bool {
	return library.MutatedProperties.BuildStatic && BoolDefault(library.Properties.Static.Enabled, true)
}

func (library *libraryDecorator) setRlib() {
	library.MutatedProperties.VariantIsRlib = true
	library.MutatedProperties.VariantIsDylib = false
	library.MutatedProperties.VariantIsStatic = false
	library.MutatedProperties.VariantIsShared = false
}

func (library *libraryDecorator) setDylib() {
	library.MutatedProperties.VariantIsRlib = false
	library.MutatedProperties.VariantIsDylib = true
	library.MutatedProperties.VariantIsStatic = false
	library.MutatedProperties.VariantIsShared = false
}

func (library *libraryDecorator) rlibStd() bool {
	return library.MutatedProperties.VariantIsStaticStd
}

func (library *libraryDecorator) setRlibStd() {
	library.MutatedProperties.VariantIsStaticStd = true
}

func (library *libraryDecorator) setDylibStd() {
	library.MutatedProperties.VariantIsStaticStd = false
}

func (library *libraryDecorator) setShared() {
	library.MutatedProperties.VariantIsStatic = false
	library.MutatedProperties.VariantIsShared = true
	library.MutatedProperties.VariantIsRlib = false
	library.MutatedProperties.VariantIsDylib = false
}

func (library *libraryDecorator) setStatic() {
	library.MutatedProperties.VariantIsStatic = true
	library.MutatedProperties.VariantIsShared = false
	library.MutatedProperties.VariantIsRlib = false
	library.MutatedProperties.VariantIsDylib = false
}

func (library *libraryDecorator) setSource() {
	library.MutatedProperties.VariantIsSource = true
}

func (library *libraryDecorator) autoDep(ctx android.BottomUpMutatorContext) autoDep {
	if library.preferRlib() {
		return rlibAutoDep
	} else if library.rlib() || library.static() {
		return rlibAutoDep
	} else if library.dylib() || library.shared() {
		return dylibAutoDep
	} else {
		panic(fmt.Errorf("autoDep called on library %q that has no enabled variants.", ctx.ModuleName()))
	}
}

func (library *libraryDecorator) stdLinkage(ctx *depsContext) RustLinkage {
	if library.static() || library.MutatedProperties.VariantIsStaticStd {
		return RlibLinkage
	} else if library.baseCompiler.preferRlib() {
		return RlibLinkage
	}
	return DefaultLinkage
}

var _ compiler = (*libraryDecorator)(nil)
var _ libraryInterface = (*libraryDecorator)(nil)
var _ exportedFlagsProducer = (*libraryDecorator)(nil)

// rust_library produces all Rust variants (rust_library_dylib and
// rust_library_rlib).
func RustLibraryFactory() android.Module {
	module, library := NewRustLibrary(android.HostAndDeviceSupported)
	library.BuildOnlyRust()
	return module.Init()
}

// rust_ffi produces all FFI variants (rust_ffi_shared and
// rust_ffi_static).
func RustFFIFactory() android.Module {
	module, library := NewRustLibrary(android.HostAndDeviceSupported)
	library.BuildOnlyFFI()
	return module.Init()
}

// rust_library_dylib produces a Rust dylib (Rust crate type "dylib").
func RustLibraryDylibFactory() android.Module {
	module, library := NewRustLibrary(android.HostAndDeviceSupported)
	library.BuildOnlyDylib()
	return module.Init()
}

// rust_library_rlib produces an rlib (Rust crate type "rlib").
func RustLibraryRlibFactory() android.Module {
	module, library := NewRustLibrary(android.HostAndDeviceSupported)
	library.BuildOnlyRlib()
	return module.Init()
}

// rust_ffi_shared produces a shared library (Rust crate type
// "cdylib").
func RustFFISharedFactory() android.Module {
	module, library := NewRustLibrary(android.HostAndDeviceSupported)
	library.BuildOnlyShared()
	return module.Init()
}

// rust_ffi_static produces a static library (Rust crate type
// "staticlib").
func RustFFIStaticFactory() android.Module {
	module, library := NewRustLibrary(android.HostAndDeviceSupported)
	library.BuildOnlyStatic()
	return module.Init()
}

// rust_library_host produces all Rust variants for the host
// (rust_library_dylib_host and rust_library_rlib_host).
func RustLibraryHostFactory() android.Module {
	module, library := NewRustLibrary(android.HostSupported)
	library.BuildOnlyRust()
	return module.Init()
}

// rust_ffi_host produces all FFI variants for the host
// (rust_ffi_static_host and rust_ffi_shared_host).
func RustFFIHostFactory() android.Module {
	module, library := NewRustLibrary(android.HostSupported)
	library.BuildOnlyFFI()
	return module.Init()
}

// rust_library_dylib_host produces a dylib for the host (Rust crate
// type "dylib").
func RustLibraryDylibHostFactory() android.Module {
	module, library := NewRustLibrary(android.HostSupported)
	library.BuildOnlyDylib()
	return module.Init()
}

// rust_library_rlib_host produces an rlib for the host (Rust crate
// type "rlib").
func RustLibraryRlibHostFactory() android.Module {
	module, library := NewRustLibrary(android.HostSupported)
	library.BuildOnlyRlib()
	return module.Init()
}

// rust_ffi_static_host produces a static library for the host (Rust
// crate type "staticlib").
func RustFFIStaticHostFactory() android.Module {
	module, library := NewRustLibrary(android.HostSupported)
	library.BuildOnlyStatic()
	return module.Init()
}

// rust_ffi_shared_host produces an shared library for the host (Rust
// crate type "cdylib").
func RustFFISharedHostFactory() android.Module {
	module, library := NewRustLibrary(android.HostSupported)
	library.BuildOnlyShared()
	return module.Init()
}

func (library *libraryDecorator) BuildOnlyFFI() {
	library.MutatedProperties.BuildDylib = false
	library.MutatedProperties.BuildRlib = false
	library.MutatedProperties.BuildShared = true
	library.MutatedProperties.BuildStatic = true
}

func (library *libraryDecorator) BuildOnlyRust() {
	library.MutatedProperties.BuildDylib = true
	library.MutatedProperties.BuildRlib = true
	library.MutatedProperties.BuildShared = false
	library.MutatedProperties.BuildStatic = false
}

func (library *libraryDecorator) BuildOnlyDylib() {
	library.MutatedProperties.BuildDylib = true
	library.MutatedProperties.BuildRlib = false
	library.MutatedProperties.BuildShared = false
	library.MutatedProperties.BuildStatic = false
}

func (library *libraryDecorator) BuildOnlyRlib() {
	library.MutatedProperties.BuildDylib = false
	library.MutatedProperties.BuildRlib = true
	library.MutatedProperties.BuildShared = false
	library.MutatedProperties.BuildStatic = false
}

func (library *libraryDecorator) BuildOnlyStatic() {
	library.MutatedProperties.BuildRlib = false
	library.MutatedProperties.BuildDylib = false
	library.MutatedProperties.BuildShared = false
	library.MutatedProperties.BuildStatic = true
}

func (library *libraryDecorator) BuildOnlyShared() {
	library.MutatedProperties.BuildRlib = false
	library.MutatedProperties.BuildDylib = false
	library.MutatedProperties.BuildStatic = false
	library.MutatedProperties.BuildShared = true
}

func NewRustLibrary(hod android.HostOrDeviceSupported) (*Module, *libraryDecorator) {
	module := newModule(hod, android.MultilibBoth)

	android.InitBazelModule(module)

	library := &libraryDecorator{
		MutatedProperties: LibraryMutatedProperties{
			BuildDylib:  false,
			BuildRlib:   false,
			BuildShared: false,
			BuildStatic: false,
		},
		baseCompiler: NewBaseCompiler("lib", "lib64", InstallInSystem),
		flagExporter: NewFlagExporter(),
	}

	module.compiler = library

	return module, library
}

func (library *libraryDecorator) compilerProps() []interface{} {
	return append(library.baseCompiler.compilerProps(),
		&library.Properties,
		&library.MutatedProperties,
		&library.stripper.StripProperties)
}

func (library *libraryDecorator) compilerDeps(ctx DepsContext, deps Deps) Deps {
	deps = library.baseCompiler.compilerDeps(ctx, deps)

	if library.dylib() || library.shared() {
		if ctx.toolchain().Bionic() {
			deps = bionicDeps(ctx, deps, false)
			deps.CrtBegin = []string{"crtbegin_so"}
			deps.CrtEnd = []string{"crtend_so"}
		} else if ctx.Os() == android.LinuxMusl {
			deps = muslDeps(ctx, deps, false)
			deps.CrtBegin = []string{"libc_musl_crtbegin_so"}
			deps.CrtEnd = []string{"libc_musl_crtend_so"}
		}
	}

	return deps
}

func (library *libraryDecorator) sharedLibFilename(ctx ModuleContext) string {
	return library.getStem(ctx) + ctx.toolchain().SharedLibSuffix()
}

func (library *libraryDecorator) cfgFlags(ctx ModuleContext, flags Flags) Flags {
	flags = library.baseCompiler.cfgFlags(ctx, flags)
	if library.dylib() {
		// We need to add a dependency on std in order to link crates as dylibs.
		// The hack to add this dependency is guarded by the following cfg so
		// that we don't force a dependency when it isn't needed.
		library.baseCompiler.Properties.Cfgs = append(library.baseCompiler.Properties.Cfgs, "android_dylib")
	}

	flags.RustFlags = append(flags.RustFlags, library.baseCompiler.cfgsToFlags()...)
	flags.RustdocFlags = append(flags.RustdocFlags, library.baseCompiler.cfgsToFlags()...)

	return flags
}

func (library *libraryDecorator) compilerFlags(ctx ModuleContext, flags Flags) Flags {
	flags = library.baseCompiler.compilerFlags(ctx, flags)

	flags.RustFlags = append(flags.RustFlags, "-C metadata="+ctx.ModuleName())
	if library.shared() || library.static() {
		library.includeDirs = append(library.includeDirs, android.PathsForModuleSrc(ctx, library.Properties.Include_dirs)...)
	}
	if library.shared() {
		if ctx.Darwin() {
			flags.LinkFlags = append(
				flags.LinkFlags,
				"-dynamic_lib",
				"-install_name @rpath/"+library.sharedLibFilename(ctx),
			)
		} else {
			flags.LinkFlags = append(flags.LinkFlags, "-Wl,-soname="+library.sharedLibFilename(ctx))
		}
	}

	return flags
}

func (library *libraryDecorator) compile(ctx ModuleContext, flags Flags, deps PathDeps) buildOutput {
	var outputFile android.ModuleOutPath
	var ret buildOutput
	var fileName string
	crateRootPath := library.crateRootPath(ctx, deps)

	if library.sourceProvider != nil {
		deps.srcProviderFiles = append(deps.srcProviderFiles, library.sourceProvider.Srcs()...)
	}

	// Calculate output filename
	if library.rlib() {
		fileName = library.getStem(ctx) + ctx.toolchain().RlibSuffix()
		outputFile = android.PathForModuleOut(ctx, fileName)
		ret.outputFile = outputFile
	} else if library.dylib() {
		fileName = library.getStem(ctx) + ctx.toolchain().DylibSuffix()
		outputFile = android.PathForModuleOut(ctx, fileName)
		ret.outputFile = outputFile
	} else if library.static() {
		fileName = library.getStem(ctx) + ctx.toolchain().StaticLibSuffix()
		outputFile = android.PathForModuleOut(ctx, fileName)
		ret.outputFile = outputFile
	} else if library.shared() {
		fileName = library.sharedLibFilename(ctx)
		outputFile = android.PathForModuleOut(ctx, fileName)
		ret.outputFile = outputFile
	}

	if !library.rlib() && !library.static() && library.stripper.NeedsStrip(ctx) {
		strippedOutputFile := outputFile
		outputFile = android.PathForModuleOut(ctx, "unstripped", fileName)
		library.stripper.StripExecutableOrSharedLib(ctx, outputFile, strippedOutputFile)

		library.baseCompiler.strippedOutputFile = android.OptionalPathForPath(strippedOutputFile)
	}
	library.baseCompiler.unstrippedOutputFile = outputFile

	flags.RustFlags = append(flags.RustFlags, deps.depFlags...)
	flags.LinkFlags = append(flags.LinkFlags, deps.depLinkFlags...)
	flags.LinkFlags = append(flags.LinkFlags, deps.linkObjects...)

	if library.dylib() {
		// We need prefer-dynamic for now to avoid linking in the static stdlib. See:
		// https://github.com/rust-lang/rust/issues/19680
		// https://github.com/rust-lang/rust/issues/34909
		flags.RustFlags = append(flags.RustFlags, "-C prefer-dynamic")
	}

	// Call the appropriate builder for this library type
	if library.rlib() {
		ret.kytheFile = TransformSrctoRlib(ctx, crateRootPath, deps, flags, outputFile).kytheFile
	} else if library.dylib() {
		ret.kytheFile = TransformSrctoDylib(ctx, crateRootPath, deps, flags, outputFile).kytheFile
	} else if library.static() {
		ret.kytheFile = TransformSrctoStatic(ctx, crateRootPath, deps, flags, outputFile).kytheFile
	} else if library.shared() {
		ret.kytheFile = TransformSrctoShared(ctx, crateRootPath, deps, flags, outputFile).kytheFile
	}

	if library.rlib() || library.dylib() {
		library.flagExporter.exportLinkDirs(deps.linkDirs...)
		library.flagExporter.exportLinkObjects(deps.linkObjects...)
	}

	if library.static() || library.shared() {
		ctx.SetProvider(cc.FlagExporterInfoProvider, cc.FlagExporterInfo{
			IncludeDirs: library.includeDirs,
		})
	}

	if library.shared() {
		// Optimize out relinking against shared libraries whose interface hasn't changed by
		// depending on a table of contents file instead of the library itself.
		tocFile := outputFile.ReplaceExtension(ctx, flags.Toolchain.SharedLibSuffix()[1:]+".toc")
		library.tocFile = android.OptionalPathForPath(tocFile)
		cc.TransformSharedObjectToToc(ctx, outputFile, tocFile)

		ctx.SetProvider(cc.SharedLibraryInfoProvider, cc.SharedLibraryInfo{
			TableOfContents: android.OptionalPathForPath(tocFile),
			SharedLibrary:   outputFile,
			Target:          ctx.Target(),
		})
	}

	if library.static() {
		depSet := android.NewDepSetBuilder[android.Path](android.TOPOLOGICAL).Direct(outputFile).Build()
		ctx.SetProvider(cc.StaticLibraryInfoProvider, cc.StaticLibraryInfo{
			StaticLibrary: outputFile,

			TransitiveStaticLibrariesForOrdering: depSet,
		})
	}

	library.flagExporter.setProvider(ctx)

	return ret
}

func (library *libraryDecorator) crateRootPath(ctx ModuleContext, _ PathDeps) android.Path {
	if library.sourceProvider != nil {
		// Assume the first source from the source provider is the library entry point.
		return library.sourceProvider.Srcs()[0]
	} else if library.baseCompiler.Properties.Crate_root == nil {
		path, _ := srcPathFromModuleSrcs(ctx, library.baseCompiler.Properties.Srcs)
		return path
	} else {
		return android.PathForModuleSrc(ctx, *library.baseCompiler.Properties.Crate_root)
	}
}

func (library *libraryDecorator) rustdoc(ctx ModuleContext, flags Flags,
	deps PathDeps) android.OptionalPath {
	// rustdoc has builtin support for documenting config specific information
	// regardless of the actual config it was given
	// (https://doc.rust-lang.org/rustdoc/advanced-features.html#cfgdoc-documenting-platform-specific-or-feature-specific-information),
	// so we generate the rustdoc for only the primary module so that we have a
	// single set of docs to refer to.
	if ctx.Module() != ctx.PrimaryModule() {
		return android.OptionalPath{}
	}

	return android.OptionalPathForPath(Rustdoc(ctx, library.crateRootPath(ctx, deps),
		deps, flags))
}

func (library *libraryDecorator) getStem(ctx ModuleContext) string {
	stem := library.baseCompiler.getStemWithoutSuffix(ctx)
	validateLibraryStem(ctx, stem, library.crateName())

	return stem + String(library.baseCompiler.Properties.Suffix)
}

func (library *libraryDecorator) install(ctx ModuleContext) {
	// Only shared and dylib variants make sense to install.
	if library.shared() || library.dylib() {
		library.baseCompiler.install(ctx)
	}
}

func (library *libraryDecorator) Disabled() bool {
	return library.MutatedProperties.VariantIsDisabled
}

func (library *libraryDecorator) SetDisabled() {
	library.MutatedProperties.VariantIsDisabled = true
}

var validCrateName = regexp.MustCompile("[^a-zA-Z0-9_]+")

func validateLibraryStem(ctx BaseModuleContext, filename string, crate_name string) {
	if crate_name == "" {
		ctx.PropertyErrorf("crate_name", "crate_name must be defined.")
	}

	// crate_names are used for the library output file, and rustc expects these
	// to be alphanumeric with underscores allowed.
	if validCrateName.MatchString(crate_name) {
		ctx.PropertyErrorf("crate_name",
			"library crate_names must be alphanumeric with underscores allowed")
	}

	// Libraries are expected to begin with "lib" followed by the crate_name
	if !strings.HasPrefix(filename, "lib"+crate_name) {
		ctx.ModuleErrorf("Invalid name or stem property; library filenames must start with lib<crate_name>")
	}
}

// LibraryMutator mutates the libraries into variants according to the
// build{Rlib,Dylib} attributes.
func LibraryMutator(mctx android.BottomUpMutatorContext) {
	// Only mutate on Rust libraries.
	m, ok := mctx.Module().(*Module)
	if !ok || m.compiler == nil {
		return
	}
	library, ok := m.compiler.(libraryInterface)
	if !ok {
		return
	}

	var variants []string
	// The source variant is used for SourceProvider modules. The other variants (i.e. rlib and dylib)
	// depend on this variant. It must be the first variant to be declared.
	sourceVariant := false
	if m.sourceProvider != nil {
		variants = append(variants, "source")
		sourceVariant = true
	}
	if library.buildRlib() {
		variants = append(variants, rlibVariation)
	}
	if library.buildDylib() {
		variants = append(variants, dylibVariation)
	}

	if len(variants) == 0 {
		return
	}
	modules := mctx.CreateLocalVariations(variants...)

	// The order of the variations (modules) matches the variant names provided. Iterate
	// through the new variation modules and set their mutated properties.
	for i, v := range modules {
		switch variants[i] {
		case rlibVariation:
			v.(*Module).compiler.(libraryInterface).setRlib()
		case dylibVariation:
			v.(*Module).compiler.(libraryInterface).setDylib()
			if v.(*Module).ModuleBase.ImageVariation().Variation == android.VendorRamdiskVariation {
				// TODO(b/165791368)
				// Disable dylib Vendor Ramdisk variations until we support these.
				v.(*Module).Disable()
			}

		case "source":
			v.(*Module).compiler.(libraryInterface).setSource()
			// The source variant does not produce any library.
			// Disable the compilation steps.
			v.(*Module).compiler.SetDisabled()
		}
	}

	// If a source variant is created, add an inter-variant dependency
	// between the other variants and the source variant.
	if sourceVariant {
		sv := modules[0]
		for _, v := range modules[1:] {
			if !v.Enabled() {
				continue
			}
			mctx.AddInterVariantDependency(sourceDepTag, v, sv)
		}
		// Alias the source variation so it can be named directly in "srcs" properties.
		mctx.AliasVariation("source")
	}
}

func LibstdMutator(mctx android.BottomUpMutatorContext) {
	if m, ok := mctx.Module().(*Module); ok && m.compiler != nil && !m.compiler.Disabled() {
		switch library := m.compiler.(type) {
		case libraryInterface:
			// Only create a variant if a library is actually being built.
			if library.rlib() && !library.sysroot() {
				variants := []string{"rlib-std", "dylib-std"}
				modules := mctx.CreateLocalVariations(variants...)

				rlib := modules[0].(*Module)
				dylib := modules[1].(*Module)
				rlib.compiler.(libraryInterface).setRlibStd()
				dylib.compiler.(libraryInterface).setDylibStd()
				if dylib.ModuleBase.ImageVariation().Variation == android.VendorRamdiskVariation {
					// TODO(b/165791368)
					// Disable rlibs that link against dylib-std on vendor ramdisk variations until those dylib
					// variants are properly supported.
					dylib.Disable()
				}
				rlib.Properties.RustSubName += RlibStdlibSuffix
			}
		}
	}
}

func (l *libraryDecorator) snapshotHeaders() android.Paths {
	if l.collectedSnapshotHeaders == nil {
		panic("snapshotHeaders() must be called after collectHeadersForSnapshot()")
	}
	return l.collectedSnapshotHeaders
}

// collectHeadersForSnapshot collects all exported headers from library.
// It globs header files in the source tree for exported include directories,
// and tracks generated header files separately.
//
// This is to be called from GenerateAndroidBuildActions, and then collected
// header files can be retrieved by snapshotHeaders().
func (l *libraryDecorator) collectHeadersForSnapshot(ctx android.ModuleContext, deps PathDeps) {
	ret := android.Paths{}

	// Glob together the headers from the modules include_dirs property
	for _, path := range android.CopyOfPaths(l.includeDirs) {
		dir := path.String()
		globDir := dir + "/**/*"
		glob, err := ctx.GlobWithDeps(globDir, nil)
		if err != nil {
			ctx.ModuleErrorf("glob of %q failed: %s", globDir, err)
			return
		}

		for _, header := range glob {
			// Filter out only the files with extensions that are headers.
			found := false
			for _, ext := range cc.HeaderExts {
				if strings.HasSuffix(header, ext) {
					found = true
					break
				}
			}
			if !found {
				continue
			}
			ret = append(ret, android.PathForSource(ctx, header))
		}
	}

	// Glob together the headers from C dependencies as well, starting with non-generated headers.
	ret = append(ret, cc.GlobHeadersForSnapshot(ctx, append(android.CopyOfPaths(deps.depIncludePaths), deps.depSystemIncludePaths...))...)

	// Collect generated headers from C dependencies.
	ret = append(ret, cc.GlobGeneratedHeadersForSnapshot(ctx, deps.depGeneratedHeaders)...)

	// TODO(185577950): If support for generated headers is added, they need to be collected here as well.
	l.collectedSnapshotHeaders = ret
}

type rustLibraryAttributes struct {
	commonLibraryAttrs
}

type commonLibraryAttrs struct {
	Srcs            bazel.LabelListAttribute
	Compile_data    bazel.LabelListAttribute
	Crate_name      bazel.StringAttribute
	Edition         bazel.StringAttribute
	Crate_features  bazel.StringListAttribute
	Deps            bazel.LabelListAttribute
	Rustc_flags     bazel.StringListAttribute
	Proc_macro_deps bazel.LabelListAttribute
}

func commonLibraryAttrsBp2build(ctx android.Bp2buildMutatorContext, m *Module) *commonLibraryAttrs {
	lib := m.compiler.(*libraryDecorator)

	srcs, compileData := srcsAndCompileDataAttrs(ctx, *lib.baseCompiler)

	deps := android.BazelLabelForModuleDeps(ctx, append(
		lib.baseCompiler.Properties.Rustlibs,
		lib.baseCompiler.Properties.Rlibs...,
	))

	cargoBuildScript := cargoBuildScriptBp2build(ctx, m)
	if cargoBuildScript != nil {
		deps.Add(&bazel.Label{
			Label: ":" + *cargoBuildScript,
		})
	}

	procMacroDeps := android.BazelLabelForModuleDeps(ctx, lib.baseCompiler.Properties.Proc_macros)

	var rustcFLags []string
	for _, cfg := range lib.baseCompiler.Properties.Cfgs {
		rustcFLags = append(rustcFLags, fmt.Sprintf("--cfg=%s", cfg))
	}

	return &commonLibraryAttrs{
		Srcs: bazel.MakeLabelListAttribute(
			srcs,
		),
		Compile_data: bazel.MakeLabelListAttribute(
			compileData,
		),
		Crate_name: bazel.StringAttribute{
			Value: &lib.baseCompiler.Properties.Crate_name,
		},
		Edition: bazel.StringAttribute{
			Value: lib.baseCompiler.Properties.Edition,
		},
		Crate_features: bazel.StringListAttribute{
			Value: lib.baseCompiler.Properties.Features,
		},
		Deps: bazel.MakeLabelListAttribute(
			deps,
		),
		Proc_macro_deps: bazel.MakeLabelListAttribute(
			procMacroDeps,
		),
		Rustc_flags: bazel.StringListAttribute{
			Value: append(
				rustcFLags,
				lib.baseCompiler.Properties.Flags...,
			),
		},
	}

}

func libraryBp2build(ctx android.Bp2buildMutatorContext, m *Module) {
	ctx.CreateBazelTargetModule(
		bazel.BazelTargetModuleProperties{
			Rule_class:        "rust_library",
			Bzl_load_location: "@rules_rust//rust:defs.bzl",
		},
		android.CommonAttributes{
			Name: m.Name(),
		},
		commonLibraryAttrsBp2build(ctx, m),
	)
}

type cargoBuildScriptAttributes struct {
	Srcs    bazel.LabelListAttribute
	Edition bazel.StringAttribute
	Version bazel.StringAttribute
}

func cargoBuildScriptBp2build(ctx android.Bp2buildMutatorContext, m *Module) *string {
	// Soong treats some crates like libprotobuf as special in that they have
	// cargo build script ran to produce an out folder and check it into AOSP
	// For example, https://cs.android.com/android/platform/superproject/main/+/main:external/rust/crates/protobuf/out/
	// is produced by cargo build script https://cs.android.com/android/platform/superproject/main/+/main:external/rust/crates/protobuf/build.rs
	// The out folder is then fed into `rust_library` by a genrule
	// https://cs.android.com/android/platform/superproject/main/+/main:external/rust/crates/protobuf/Android.bp;l=22
	// This allows Soong to decouple from cargo completely.

	// Soong decouples from cargo so that it has control over cc compilation.
	// https://cs.android.com/android/platform/superproject/main/+/main:development/scripts/cargo2android.py;l=1033-1041;drc=8449944a50a0445a5ecaf9b7aed12608c81bf3f1
	// generates a `cc_library_static` module to have custom cc flags.
	// Since bp2build will convert the cc modules to cc targets which include the cflags,
	// Bazel does not need to have this optimization.

	// Performance-wise: rust_library -> cargo_build_script vs rust_library -> genrule (like Soong)
	// don't have any major difference in build time in Bazel. So using cargo_build_script does not slow
	// down the build.

	// The benefit of using `cargo_build_script` here is that it would take care of setting correct
	// `OUT_DIR` for us - similar to what Soong does here
	// https://cs.android.com/android/platform/superproject/main/+/main:build/soong/rust/builder.go;l=202-218;drc=f29ca58e88c5846bbe8955e5192135e5ab4f14a1

	// TODO(b/297364081): cargo2android.py has logic for when generate/not cc_library_static and out directory
	// bp2build might be able use the same logic for when to use `cargo_build_script`.
	// For now, we're building libprotobuf_build_script as a one-off until we have a more principled solution
	if m.Name() != "libprotobuf" {
		return nil
	}

	lib := m.compiler.(*libraryDecorator)

	name := m.Name() + "_build_script"
	attrs := &cargoBuildScriptAttributes{
		Srcs: bazel.MakeLabelListAttribute(
			android.BazelLabelForModuleSrc(ctx, []string{"build.rs"}),
		),
		Edition: bazel.StringAttribute{
			Value: lib.baseCompiler.Properties.Edition,
		},
		Version: bazel.StringAttribute{
			Value: lib.baseCompiler.Properties.Cargo_pkg_version,
		},
	}

	// TODO(b/290790800): Remove the restriction when rust toolchain for android is implemented
	var restriction bazel.BoolAttribute
	restriction.SetSelectValue(bazel.OsConfigurationAxis, "android", proptools.BoolPtr(false))

	ctx.CreateBazelTargetModuleWithRestrictions(
		bazel.BazelTargetModuleProperties{
			Rule_class:        "cargo_build_script",
			Bzl_load_location: "@rules_rust//cargo:cargo_build_script.bzl",
		},
		android.CommonAttributes{
			Name: name,
		},
		attrs,
		restriction,
	)

	return &name
}

type ffiStaticAttributes struct {
	commonLibraryAttrs
	Export_includes bazel.StringListAttribute
}

func ffiStaticBp2build(ctx android.Bp2buildMutatorContext, m *Module) {
	lib := m.compiler.(*libraryDecorator)

	attrs := &ffiStaticAttributes{
		Export_includes: bazel.StringListAttribute{
			Value: lib.Properties.Include_dirs,
		},
		commonLibraryAttrs: *commonLibraryAttrsBp2build(ctx, m),
	}

	ctx.CreateBazelTargetModule(
		bazel.BazelTargetModuleProperties{
			Rule_class:        "rust_ffi_static",
			Bzl_load_location: "//build/bazel/rules/rust:rust_ffi_static.bzl",
		},
		android.CommonAttributes{
			Name: m.Name(),
		},
		attrs,
	)
}
