// Copyright 2015 Google Inc. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package java

// This file contains the module types for compiling Java for Android, and converts the properties
// into the flags and filenames necessary to pass to the Module.  The final creation of the rules
// is handled in builder.go

import (
	"fmt"
	"path/filepath"
	"strconv"
	"strings"

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

	"android/soong/android"
	"android/soong/genrule"
	"android/soong/java/config"
)

func init() {
	android.RegisterModuleType("java_defaults", defaultsFactory)

	android.RegisterModuleType("java_library", LibraryFactory(true))
	android.RegisterModuleType("java_library_static", LibraryFactory(false))
	android.RegisterModuleType("java_library_host", LibraryHostFactory)
	android.RegisterModuleType("java_binary", BinaryFactory)
	android.RegisterModuleType("java_binary_host", BinaryHostFactory)
	android.RegisterModuleType("java_import", ImportFactory)
	android.RegisterModuleType("java_import_host", ImportFactoryHost)
	android.RegisterModuleType("android_app", AndroidAppFactory)

	android.RegisterSingletonType("logtags", LogtagsSingleton)
}

// TODO:
// Autogenerated files:
//  Renderscript
// Post-jar passes:
//  Proguard
//  Jacoco
//  Jarjar
//  Dex
// Rmtypedefs
// DroidDoc
// Findbugs

type CompilerProperties struct {
	// list of source files used to compile the Java module.  May be .java, .logtags, .proto,
	// or .aidl files.
	Srcs []string `android:"arch_variant"`

	// list of source files that should not be used to build the Java module.
	// This is most useful in the arch/multilib variants to remove non-common files
	Exclude_srcs []string `android:"arch_variant"`

	// list of directories containing Java resources
	Java_resource_dirs []string `android:"arch_variant"`

	// list of directories that should be excluded from java_resource_dirs
	Exclude_java_resource_dirs []string `android:"arch_variant"`

	// list of files to use as Java resources
	Java_resources []string `android:"arch_variant"`

	// list of files that should be excluded from java_resources
	Exclude_java_resources []string `android:"arch_variant"`

	// don't build against the default libraries (bootclasspath, legacy-test, core-junit,
	// ext, and framework for device targets)
	No_standard_libs *bool

	// don't build against the framework libraries (legacy-test, core-junit,
	// ext, and framework for device targets)
	No_framework_libs *bool

	// list of module-specific flags that will be used for javac compiles
	Javacflags []string `android:"arch_variant"`

	// list of of java libraries that will be in the classpath
	Libs []string `android:"arch_variant"`

	// list of java libraries that will be compiled into the resulting jar
	Static_libs []string `android:"arch_variant"`

	// manifest file to be included in resulting jar
	Manifest *string

	// if not blank, run jarjar using the specified rules file
	Jarjar_rules *string

	// If not blank, set the java version passed to javac as -source and -target
	Java_version *string

	// If set to false, don't allow this module to be installed.  Defaults to true.
	Installable *bool

	// If set to true, include sources used to compile the module in to the final jar
	Include_srcs *bool

	// List of modules to use as annotation processors
	Annotation_processors []string

	// List of classes to pass to javac to use as annotation processors
	Annotation_processor_classes []string
}

type CompilerDeviceProperties struct {
	// list of module-specific flags that will be used for dex compiles
	Dxflags []string `android:"arch_variant"`

	// if not blank, set to the version of the sdk to compile against
	Sdk_version string

	// Set for device java libraries, and for host versions of device java libraries
	// built for testing
	Dex bool `blueprint:"mutated"`

	// directories to pass to aidl tool
	Aidl_includes []string

	// directories that should be added as include directories
	// for any aidl sources of modules that depend on this module
	Export_aidl_include_dirs []string
}

// Module contains the properties and members used by all java module types
type Module struct {
	android.ModuleBase
	android.DefaultableModuleBase

	properties       CompilerProperties
	protoProperties  android.ProtoProperties
	deviceProperties CompilerDeviceProperties

	// output file suitable for inserting into the classpath of another compile
	classpathFile android.Path

	// output file containing classes.dex
	dexJarFile android.Path

	// output files containing resources
	resourceJarFiles android.Paths

	// output file suitable for installing or running
	outputFile android.Path

	exportAidlIncludeDirs android.Paths

	logtagsSrcs android.Paths

	// filelists of extra source files that should be included in the javac command line,
	// for example R.java generated by aapt for android apps
	ExtraSrcLists android.Paths

	// installed file for binary dependency
	installFile android.Path
}

type Dependency interface {
	ClasspathFiles() android.Paths
	ResourceJarFiles() android.Paths
	AidlIncludeDirs() android.Paths
}

func InitJavaModule(module android.DefaultableModule, hod android.HostOrDeviceSupported) {
	android.InitAndroidArchModule(module, hod, android.MultilibCommon)
	android.InitDefaultableModule(module)
}

type dependencyTag struct {
	blueprint.BaseDependencyTag
	name string
}

var (
	staticLibTag     = dependencyTag{name: "staticlib"}
	libTag           = dependencyTag{name: "javalib"}
	bootClasspathTag = dependencyTag{name: "bootclasspath"}
	frameworkResTag  = dependencyTag{name: "framework-res"}
)

type sdkDep struct {
	useModule, useFiles, useDefaultLibs, invalidVersion bool

	module string
	jar    android.Path
	aidl   android.Path
}

func decodeSdkDep(ctx android.BaseContext, v string) sdkDep {
	switch v {
	case "", "current", "system_current", "test_current":
		// OK
	default:
		if _, err := strconv.Atoi(v); err != nil {
			ctx.PropertyErrorf("sdk_version", "invalid sdk version")
			return sdkDep{}
		}
	}

	toFile := func(v string) sdkDep {
		dir := filepath.Join("prebuilts/sdk", v)
		jar := filepath.Join(dir, "android.jar")
		aidl := filepath.Join(dir, "framework.aidl")
		jarPath := android.ExistentPathForSource(ctx, "sdkdir", jar)
		aidlPath := android.ExistentPathForSource(ctx, "sdkdir", aidl)

		if (!jarPath.Valid() || !aidlPath.Valid()) && ctx.AConfig().AllowMissingDependencies() {
			return sdkDep{
				invalidVersion: true,
				module:         "sdk_v" + v,
			}
		}

		if !jarPath.Valid() {
			ctx.PropertyErrorf("sdk_version", "invalid sdk version %q, %q does not exist", v, jar)
			return sdkDep{}
		}

		if !aidlPath.Valid() {
			ctx.PropertyErrorf("sdk_version", "invalid sdk version %q, %q does not exist", v, aidl)
			return sdkDep{}
		}

		return sdkDep{
			useFiles: true,
			jar:      jarPath.Path(),
			aidl:     aidlPath.Path(),
		}
	}

	toModule := func(m string) sdkDep {
		return sdkDep{
			useModule: true,
			module:    m,
		}
	}

	if ctx.AConfig().UnbundledBuild() && v != "" {
		return toFile(v)
	}

	switch v {
	case "":
		return sdkDep{
			useDefaultLibs: true,
		}
	case "current":
		return toModule("android_stubs_current")
	case "system_current":
		return toModule("android_system_stubs_current")
	case "test_current":
		return toModule("android_test_stubs_current")
	default:
		return toFile(v)
	}
}

func (j *Module) deps(ctx android.BottomUpMutatorContext) {
	if !proptools.Bool(j.properties.No_standard_libs) {
		if ctx.Device() {
			sdkDep := decodeSdkDep(ctx, j.deviceProperties.Sdk_version)
			if sdkDep.useDefaultLibs {
				ctx.AddDependency(ctx.Module(), bootClasspathTag, config.DefaultBootclasspathLibraries...)
				if !proptools.Bool(j.properties.No_framework_libs) {
					ctx.AddDependency(ctx.Module(), libTag, config.DefaultLibraries...)
				}
			}
			if sdkDep.useModule {
				ctx.AddDependency(ctx.Module(), bootClasspathTag, sdkDep.module)
			}
		} else {
			if j.deviceProperties.Dex {
				ctx.AddDependency(ctx.Module(), bootClasspathTag, config.DefaultBootclasspathLibraries...)
			}
		}
	}
	ctx.AddDependency(ctx.Module(), libTag, j.properties.Libs...)
	ctx.AddDependency(ctx.Module(), staticLibTag, j.properties.Static_libs...)
	ctx.AddDependency(ctx.Module(), libTag, j.properties.Annotation_processors...)

	android.ExtractSourcesDeps(ctx, j.properties.Srcs)
	android.ExtractSourcesDeps(ctx, j.properties.Java_resources)

	if j.hasSrcExt(".proto") {
		protoDeps(ctx, &j.protoProperties)
	}
}

func hasSrcExt(srcs []string, ext string) bool {
	for _, src := range srcs {
		if filepath.Ext(src) == ext {
			return true
		}
	}

	return false
}

func (j *Module) hasSrcExt(ext string) bool {
	return hasSrcExt(j.properties.Srcs, ext)
}

func (j *Module) aidlFlags(ctx android.ModuleContext, aidlPreprocess android.OptionalPath,
	aidlIncludeDirs android.Paths) []string {

	localAidlIncludes := android.PathsForModuleSrc(ctx, j.deviceProperties.Aidl_includes)

	var flags []string
	if aidlPreprocess.Valid() {
		flags = append(flags, "-p"+aidlPreprocess.String())
	} else {
		flags = append(flags, android.JoinWithPrefix(aidlIncludeDirs.Strings(), "-I"))
	}

	flags = append(flags, android.JoinWithPrefix(j.exportAidlIncludeDirs.Strings(), "-I"))
	flags = append(flags, android.JoinWithPrefix(localAidlIncludes.Strings(), "-I"))
	flags = append(flags, "-I"+android.PathForModuleSrc(ctx).String())
	if src := android.ExistentPathForSource(ctx, "", "src"); src.Valid() {
		flags = append(flags, "-I"+src.String())
	}

	return flags
}

type deps struct {
	classpath          android.Paths
	bootClasspath      android.Paths
	staticJars         android.Paths
	staticJarResources android.Paths
	aidlIncludeDirs    android.Paths
	srcFileLists       android.Paths
	aidlPreprocess     android.OptionalPath
}

func (j *Module) collectDeps(ctx android.ModuleContext) deps {
	var deps deps

	sdkDep := decodeSdkDep(ctx, j.deviceProperties.Sdk_version)
	if sdkDep.invalidVersion {
		ctx.AddMissingDependencies([]string{sdkDep.module})
	} else if sdkDep.useFiles {
		deps.classpath = append(deps.classpath, sdkDep.jar)
		deps.aidlIncludeDirs = append(deps.aidlIncludeDirs, sdkDep.aidl)
	}

	ctx.VisitDirectDeps(func(module blueprint.Module) {
		otherName := ctx.OtherModuleName(module)
		tag := ctx.OtherModuleDependencyTag(module)

		dep, _ := module.(Dependency)
		if dep == nil {
			switch tag {
			case android.DefaultsDepTag, android.SourceDepTag:
				// Nothing to do
			default:
				ctx.ModuleErrorf("depends on non-java module %q", otherName)
			}
			return
		}

		switch tag {
		case bootClasspathTag:
			deps.bootClasspath = append(deps.bootClasspath, dep.ClasspathFiles()...)
		case libTag:
			deps.classpath = append(deps.classpath, dep.ClasspathFiles()...)
		case staticLibTag:
			deps.classpath = append(deps.classpath, dep.ClasspathFiles()...)
			deps.staticJars = append(deps.staticJars, dep.ClasspathFiles()...)
			deps.staticJarResources = append(deps.staticJarResources, dep.ResourceJarFiles()...)
		case frameworkResTag:
			if ctx.ModuleName() == "framework" {
				// framework.jar has a one-off dependency on the R.java and Manifest.java files
				// generated by framework-res.apk
				deps.srcFileLists = append(deps.srcFileLists, module.(*AndroidApp).aaptJavaFileList)
			}
		default:
			panic(fmt.Errorf("unknown dependency %q for %q", otherName, ctx.ModuleName()))
		}

		deps.aidlIncludeDirs = append(deps.aidlIncludeDirs, dep.AidlIncludeDirs()...)
	})

	return deps
}

func (j *Module) compile(ctx android.ModuleContext) {

	j.exportAidlIncludeDirs = android.PathsForModuleSrc(ctx, j.deviceProperties.Export_aidl_include_dirs)

	deps := j.collectDeps(ctx)

	var flags javaBuilderFlags

	javacFlags := j.properties.Javacflags
	if ctx.AConfig().Getenv("EXPERIMENTAL_USE_OPENJDK9") == "" {
		javacFlags = config.StripJavac9Flags(javacFlags)
	}

	if j.properties.Java_version != nil {
		flags.javaVersion = *j.properties.Java_version
	} else {
		flags.javaVersion = "${config.DefaultJavaVersion}"
	}

	flags.bootClasspath.AddPaths(deps.bootClasspath)
	flags.classpath.AddPaths(deps.classpath)

	if len(javacFlags) > 0 {
		ctx.Variable(pctx, "javacFlags", strings.Join(javacFlags, " "))
		flags.javacFlags = "$javacFlags"
	}

	aidlFlags := j.aidlFlags(ctx, deps.aidlPreprocess, deps.aidlIncludeDirs)
	if len(aidlFlags) > 0 {
		ctx.Variable(pctx, "aidlFlags", strings.Join(aidlFlags, " "))
		flags.aidlFlags = "$aidlFlags"
	}

	srcFiles := ctx.ExpandSources(j.properties.Srcs, j.properties.Exclude_srcs)

	if hasSrcExt(srcFiles.Strings(), ".proto") {
		flags = protoFlags(ctx, &j.protoProperties, flags)
	}

	var srcFileLists android.Paths

	srcFiles, srcFileLists = j.genSources(ctx, srcFiles, flags)

	srcFileLists = append(srcFileLists, deps.srcFileLists...)

	ctx.VisitDirectDeps(func(module blueprint.Module) {
		if gen, ok := module.(genrule.SourceFileGenerator); ok {
			srcFiles = append(srcFiles, gen.GeneratedSourceFiles()...)
		}
	})

	srcFileLists = append(srcFileLists, j.ExtraSrcLists...)

	var jars android.Paths

	if len(srcFiles) > 0 {
		var extraJarDeps android.Paths
		if ctx.AConfig().IsEnvTrue("RUN_ERROR_PRONE") {
			// If error-prone is enabled, add an additional rule to compile the java files into
			// a separate set of classes (so that they don't overwrite the normal ones and require
			// a rebuild when error-prone is turned off).
			// TODO(ccross): Once we always compile with javac9 we may be able to conditionally
			//    enable error-prone without affecting the output class files.
			errorprone := RunErrorProne(ctx, srcFiles, srcFileLists, flags)
			extraJarDeps = append(extraJarDeps, errorprone)
		}

		// Compile java sources into .class files
		classes := TransformJavaToClasses(ctx, srcFiles, srcFileLists, flags, extraJarDeps)
		if ctx.Failed() {
			return
		}

		jars = append(jars, classes)
	}

	dirArgs, dirDeps := ResourceDirsToJarArgs(ctx, j.properties.Java_resource_dirs, j.properties.Exclude_java_resource_dirs)
	fileArgs, fileDeps := ResourceFilesToJarArgs(ctx, j.properties.Java_resources, j.properties.Exclude_java_resources)

	var resArgs []string
	var resDeps android.Paths

	resArgs = append(resArgs, dirArgs...)
	resDeps = append(resDeps, dirDeps...)

	resArgs = append(resArgs, fileArgs...)
	resDeps = append(resDeps, fileDeps...)

	if proptools.Bool(j.properties.Include_srcs) {
		srcArgs, srcDeps := ResourceFilesToJarArgs(ctx, j.properties.Srcs, j.properties.Exclude_srcs)
		resArgs = append(resArgs, srcArgs...)
		resDeps = append(resDeps, srcDeps...)
	}

	if len(resArgs) > 0 {
		// Combine classes + resources into classes-full-debug.jar
		resourceJar := TransformResourcesToJar(ctx, resArgs, resDeps)
		if ctx.Failed() {
			return
		}

		j.resourceJarFiles = append(j.resourceJarFiles, resourceJar)
		jars = append(jars, resourceJar)
	}

	// Propagate the resources from the transitive closure of static dependencies for copying
	// into dex jars
	j.resourceJarFiles = append(j.resourceJarFiles, deps.staticJarResources...)

	// static classpath jars have the resources in them, so the resource jars aren't necessary here
	jars = append(jars, deps.staticJars...)

	manifest := android.OptionalPathForModuleSrc(ctx, j.properties.Manifest)

	// Combine the classes built from sources, any manifests, and any static libraries into
	// classes.jar.  If there is only one input jar this step will be skipped.
	outputFile := TransformJarsToJar(ctx, "classes.jar", jars, manifest, false)

	if j.properties.Jarjar_rules != nil {
		jarjar_rules := android.PathForModuleSrc(ctx, *j.properties.Jarjar_rules)
		// Transform classes.jar into classes-jarjar.jar
		outputFile = TransformJarJar(ctx, outputFile, jarjar_rules)
		if ctx.Failed() {
			return
		}
	}

	j.classpathFile = outputFile

	// TODO(ccross): handle hostdex
	if ctx.Device() && len(srcFiles) > 0 && j.installable() {
		dxFlags := j.deviceProperties.Dxflags
		if false /* emma enabled */ {
			// If you instrument class files that have local variable debug information in
			// them emma does not correctly maintain the local variable table.
			// This will cause an error when you try to convert the class files for Android.
			// The workaround here is to build different dex file here based on emma switch
			// then later copy into classes.dex. When emma is on, dx is run with --no-locals
			// option to remove local variable information
			dxFlags = append(dxFlags, "--no-locals")
		}

		if ctx.AConfig().Getenv("NO_OPTIMIZE_DX") != "" {
			dxFlags = append(dxFlags, "--no-optimize")
		}

		if ctx.AConfig().Getenv("GENERATE_DEX_DEBUG") != "" {
			dxFlags = append(dxFlags,
				"--debug",
				"--verbose",
				"--dump-to="+android.PathForModuleOut(ctx, "classes.lst").String(),
				"--dump-width=1000")
		}

		var minSdkVersion string
		switch j.deviceProperties.Sdk_version {
		case "", "current", "test_current", "system_current":
			minSdkVersion = strconv.Itoa(ctx.AConfig().DefaultAppTargetSdkInt())
		default:
			minSdkVersion = j.deviceProperties.Sdk_version
		}

		dxFlags = append(dxFlags, "--min-sdk-version="+minSdkVersion)

		flags.dxFlags = strings.Join(dxFlags, " ")

		desugarFlags := []string{
			"--min_sdk_version " + minSdkVersion,
			"--desugar_try_with_resources_if_needed=false",
			"--allow_empty_bootclasspath",
		}

		if inList("--core-library", dxFlags) {
			desugarFlags = append(desugarFlags, "--core_library")
		}

		flags.desugarFlags = strings.Join(desugarFlags, " ")

		desugarJar := TransformDesugar(ctx, outputFile, flags)
		if ctx.Failed() {
			return
		}

		// Compile classes.jar into classes.dex
		dexJarFile := TransformClassesJarToDexJar(ctx, desugarJar, flags)
		if ctx.Failed() {
			return
		}

		jars := android.Paths{dexJarFile}
		jars = append(jars, j.resourceJarFiles...)

		outputFile = TransformJarsToJar(ctx, "javalib.jar", jars, android.OptionalPath{}, true)

		j.dexJarFile = outputFile
	}
	ctx.CheckbuildFile(outputFile)
	j.outputFile = outputFile
}

func (j *Module) installable() bool {
	return j.properties.Installable == nil || *j.properties.Installable
}

var _ Dependency = (*Library)(nil)

func (j *Module) ClasspathFiles() android.Paths {
	return android.Paths{j.classpathFile}
}

func (j *Module) ResourceJarFiles() android.Paths {
	return j.resourceJarFiles
}

func (j *Module) AidlIncludeDirs() android.Paths {
	return j.exportAidlIncludeDirs
}

var _ logtagsProducer = (*Module)(nil)

func (j *Module) logtags() android.Paths {
	return j.logtagsSrcs
}

//
// Java libraries (.jar file)
//

type Library struct {
	Module
}

func (j *Library) GenerateAndroidBuildActions(ctx android.ModuleContext) {
	j.compile(ctx)

	if j.installable() {
		j.installFile = ctx.InstallFile(android.PathForModuleInstall(ctx, "framework"),
			ctx.ModuleName()+".jar", j.outputFile)
	}
}

func (j *Library) DepsMutator(ctx android.BottomUpMutatorContext) {
	j.deps(ctx)
}

func LibraryFactory(installable bool) func() android.Module {
	return func() android.Module {
		module := &Library{}

		if !installable {
			module.properties.Installable = proptools.BoolPtr(false)
		}
		module.deviceProperties.Dex = true

		module.AddProperties(
			&module.Module.properties,
			&module.Module.deviceProperties,
			&module.Module.protoProperties)

		InitJavaModule(module, android.HostAndDeviceSupported)
		return module
	}
}

func LibraryHostFactory() android.Module {
	module := &Library{}

	module.AddProperties(
		&module.Module.properties,
		&module.Module.protoProperties)

	InitJavaModule(module, android.HostSupported)
	return module
}

//
// Java Binaries (.jar file plus wrapper script)
//

type binaryProperties struct {
	// installable script to execute the resulting jar
	Wrapper string
}

type Binary struct {
	Library

	binaryProperties binaryProperties

	wrapperFile android.ModuleSrcPath
	binaryFile  android.OutputPath
}

func (j *Binary) GenerateAndroidBuildActions(ctx android.ModuleContext) {
	j.Library.GenerateAndroidBuildActions(ctx)

	// Depend on the installed jar (j.installFile) so that the wrapper doesn't get executed by
	// another build rule before the jar has been installed.
	j.wrapperFile = android.PathForModuleSrc(ctx, j.binaryProperties.Wrapper)
	j.binaryFile = ctx.InstallExecutable(android.PathForModuleInstall(ctx, "bin"),
		ctx.ModuleName(), j.wrapperFile, j.installFile)
}

func (j *Binary) DepsMutator(ctx android.BottomUpMutatorContext) {
	j.deps(ctx)
}

func BinaryFactory() android.Module {
	module := &Binary{}

	module.deviceProperties.Dex = true

	module.AddProperties(
		&module.Module.properties,
		&module.Module.deviceProperties,
		&module.Module.protoProperties,
		&module.binaryProperties)

	InitJavaModule(module, android.HostAndDeviceSupported)
	return module
}

func BinaryHostFactory() android.Module {
	module := &Binary{}

	module.AddProperties(
		&module.Module.properties,
		&module.Module.deviceProperties,
		&module.Module.protoProperties,
		&module.binaryProperties)

	InitJavaModule(module, android.HostSupported)
	return module
}

//
// Java prebuilts
//

type ImportProperties struct {
	Jars []string
}

type Import struct {
	android.ModuleBase
	prebuilt android.Prebuilt

	properties ImportProperties

	classpathFiles        android.Paths
	combinedClasspathFile android.Path
}

func (j *Import) Prebuilt() *android.Prebuilt {
	return &j.prebuilt
}

func (j *Import) PrebuiltSrcs() []string {
	return j.properties.Jars
}

func (j *Import) Name() string {
	return j.prebuilt.Name(j.ModuleBase.Name())
}

func (j *Import) DepsMutator(ctx android.BottomUpMutatorContext) {
}

func (j *Import) GenerateAndroidBuildActions(ctx android.ModuleContext) {
	j.classpathFiles = android.PathsForModuleSrc(ctx, j.properties.Jars)

	j.combinedClasspathFile = TransformJarsToJar(ctx, "classes.jar", j.classpathFiles, android.OptionalPath{}, false)
}

var _ Dependency = (*Import)(nil)

func (j *Import) ClasspathFiles() android.Paths {
	return j.classpathFiles
}

func (j *Import) ResourceJarFiles() android.Paths {
	// resources are in the ClasspathFiles
	return nil
}

func (j *Import) AidlIncludeDirs() android.Paths {
	return nil
}

var _ android.PrebuiltInterface = (*Import)(nil)

func ImportFactory() android.Module {
	module := &Import{}

	module.AddProperties(&module.properties)

	android.InitPrebuiltModule(module, &module.properties.Jars)
	android.InitAndroidArchModule(module, android.HostAndDeviceSupported, android.MultilibCommon)
	return module
}

func ImportFactoryHost() android.Module {
	module := &Import{}

	module.AddProperties(&module.properties)

	android.InitPrebuiltModule(module, &module.properties.Jars)
	android.InitAndroidArchModule(module, android.HostSupported, android.MultilibCommon)
	return module
}

func inList(s string, l []string) bool {
	for _, e := range l {
		if e == s {
			return true
		}
	}
	return false
}

//
// Defaults
//
type Defaults struct {
	android.ModuleBase
	android.DefaultsModuleBase
}

func (*Defaults) GenerateAndroidBuildActions(ctx android.ModuleContext) {
}

func (d *Defaults) DepsMutator(ctx android.BottomUpMutatorContext) {
}

func defaultsFactory() android.Module {
	return DefaultsFactory()
}

func DefaultsFactory(props ...interface{}) android.Module {
	module := &Defaults{}

	module.AddProperties(props...)
	module.AddProperties(
		&CompilerProperties{},
		&CompilerDeviceProperties{},
	)

	android.InitDefaultsModule(module)

	return module
}
