// 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"
	"strings"

	"github.com/google/blueprint"

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

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

	android.RegisterModuleType("java_library", LibraryFactory)
	android.RegisterModuleType("java_library_static", LibraryFactory)
	android.RegisterModuleType("java_library_host", LibraryHostFactory)
	android.RegisterModuleType("java_binary", BinaryFactory)
	android.RegisterModuleType("java_binary_host", BinaryHostFactory)
	android.RegisterModuleType("java_prebuilt_library", PrebuiltFactory)
	android.RegisterModuleType("android_prebuilt_sdk", SdkPrebuiltFactory)
	android.RegisterModuleType("android_app", AndroidAppFactory)

	android.RegisterSingletonType("logtags", LogtagsSingleton)
}

// TODO:
// Autogenerated files:
//  Proto
//  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
	Resource_dirs []string `android:"arch_variant"`

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

	// don't build against the default libraries (legacy-test, core-junit,
	// ext, and framework for device targets)
	No_standard_libraries 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
}

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
	deviceProperties CompilerDeviceProperties

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

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

	// jarSpecs suitable for inserting classes from a static library into another jar
	classJarSpecs []jarSpec

	// jarSpecs suitable for inserting resources from a static library into another jar
	resourceJarSpecs []jarSpec

	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 {
	ClasspathFile() android.Path
	ClassJarSpecs() []jarSpec
	ResourceJarSpecs() []jarSpec
	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"}
	sdkDependencyTag = dependencyTag{name: "sdk"}
)

func (j *Module) deps(ctx android.BottomUpMutatorContext) {
	if !j.properties.No_standard_libraries {
		if ctx.Device() {
			switch j.deviceProperties.Sdk_version {
			case "":
				ctx.AddDependency(ctx.Module(), bootClasspathTag, "core-libart")
			case "current":
				// TODO: !TARGET_BUILD_APPS
				// TODO: export preprocessed framework.aidl from android_stubs_current
				ctx.AddDependency(ctx.Module(), bootClasspathTag, "android_stubs_current")
			case "system_current":
				ctx.AddDependency(ctx.Module(), bootClasspathTag, "android_system_stubs_current")
			default:
				ctx.AddDependency(ctx.Module(), sdkDependencyTag, "sdk_v"+j.deviceProperties.Sdk_version)
			}
		} else {
			if j.deviceProperties.Dex {
				ctx.AddDependency(ctx.Module(), bootClasspathTag, "core-libart")
			}
		}

		if ctx.Device() && j.deviceProperties.Sdk_version == "" {
			ctx.AddDependency(ctx.Module(), libTag, config.DefaultLibraries...)
		}
	}
	ctx.AddDependency(ctx.Module(), libTag, j.properties.Libs...)
	ctx.AddDependency(ctx.Module(), staticLibTag, j.properties.Static_libs...)
}

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
}

func (j *Module) collectDeps(ctx android.ModuleContext) (classpath android.Paths,
	bootClasspath android.OptionalPath, classJarSpecs, resourceJarSpecs []jarSpec, aidlPreprocess android.OptionalPath,
	aidlIncludeDirs android.Paths, srcFileLists android.Paths) {

	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:
			default:
				ctx.ModuleErrorf("depends on non-java module %q", otherName)
			}
			return
		}

		switch tag {
		case bootClasspathTag:
			bootClasspath = android.OptionalPathForPath(dep.ClasspathFile())
		case libTag:
			classpath = append(classpath, dep.ClasspathFile())
		case staticLibTag:
			classpath = append(classpath, dep.ClasspathFile())
			classJarSpecs = append(classJarSpecs, dep.ClassJarSpecs()...)
			resourceJarSpecs = append(resourceJarSpecs, dep.ResourceJarSpecs()...)
		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
				srcFileLists = append(srcFileLists, module.(*AndroidApp).aaptJavaFileList)
			}
		case sdkDependencyTag:
			sdkDep := module.(sdkDependency)
			if sdkDep.AidlPreprocessed().Valid() {
				if aidlPreprocess.Valid() {
					ctx.ModuleErrorf("multiple dependencies with preprocessed aidls:\n %q\n %q",
						aidlPreprocess, sdkDep.AidlPreprocessed())
				} else {
					aidlPreprocess = sdkDep.AidlPreprocessed()
				}
			}
		default:
			panic(fmt.Errorf("unknown dependency %q for %q", otherName, ctx.ModuleName()))
		}

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

	return classpath, bootClasspath, classJarSpecs, resourceJarSpecs, aidlPreprocess,
		aidlIncludeDirs, srcFileLists
}

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

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

	classpath, bootClasspath, classJarSpecs, resourceJarSpecs, aidlPreprocess,
		aidlIncludeDirs, srcFileLists := j.collectDeps(ctx)

	var flags javaBuilderFlags

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

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

	var deps android.Paths

	if bootClasspath.Valid() {
		flags.bootClasspath = "-bootclasspath " + bootClasspath.String()
		deps = append(deps, bootClasspath.Path())
	}

	if len(classpath) > 0 {
		flags.classpath = "-classpath " + strings.Join(classpath.Strings(), ":")
		deps = append(deps, classpath...)
	}

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

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

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

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

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

		classJarSpecs = append([]jarSpec{classes}, classJarSpecs...)
	}

	resourceJarSpecs = append(ResourceDirsToJarSpecs(ctx, j.properties.Resource_dirs, j.properties.Exclude_resource_dirs),
		resourceJarSpecs...)

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

	allJarSpecs := append([]jarSpec(nil), classJarSpecs...)
	allJarSpecs = append(allJarSpecs, resourceJarSpecs...)

	// Combine classes + resources into classes-full-debug.jar
	outputFile := TransformClassesToJar(ctx, allJarSpecs, manifest)
	if ctx.Failed() {
		return
	}

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

		classes, _ := TransformPrebuiltJarToClasses(ctx, outputFile)
		classJarSpecs = []jarSpec{classes}
	}

	j.resourceJarSpecs = resourceJarSpecs
	j.classJarSpecs = classJarSpecs
	j.classpathFile = outputFile

	if j.deviceProperties.Dex && len(srcFiles) > 0 {
		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")
		}

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

		// Compile classes.jar into classes.dex
		dexJarSpec := TransformClassesJarToDex(ctx, outputFile, flags)
		if ctx.Failed() {
			return
		}

		// Combine classes.dex + resources into javalib.jar
		outputFile = TransformDexToJavaLib(ctx, resourceJarSpecs, dexJarSpec)
	}
	ctx.CheckbuildFile(outputFile)
	j.outputFile = outputFile
}

var _ Dependency = (*Library)(nil)

func (j *Module) ClasspathFile() android.Path {
	return j.classpathFile
}

func (j *Module) ClassJarSpecs() []jarSpec {
	return j.classJarSpecs
}

func (j *Module) ResourceJarSpecs() []jarSpec {
	return j.resourceJarSpecs
}

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)

	j.installFile = ctx.InstallFileName(android.PathForModuleInstall(ctx, "framework"), ctx.ModuleName()+".jar", j.outputFile)
}

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

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

	module.deviceProperties.Dex = true

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

	InitJavaModule(module, android.HostAndDeviceSupported)
	return module
}

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

	module.AddProperties(&module.Module.properties)

	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
}

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.
	ctx.InstallFile(android.PathForModuleInstall(ctx, "bin"), android.PathForModuleSrc(ctx, j.binaryProperties.Wrapper),
		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.binaryProperties)

	InitJavaModule(module, android.HostAndDeviceSupported)
	return module
}

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

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

	InitJavaModule(module, android.HostSupported)
	return module
}

//
// Java prebuilts
//

type Prebuilt struct {
	android.ModuleBase
	prebuilt android.Prebuilt

	classpathFile                   android.Path
	classJarSpecs, resourceJarSpecs []jarSpec
}

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

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

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

func (j *Prebuilt) GenerateAndroidBuildActions(ctx android.ModuleContext) {
	prebuilt := j.prebuilt.Path(ctx)

	classJarSpec, resourceJarSpec := TransformPrebuiltJarToClasses(ctx, prebuilt)

	j.classpathFile = prebuilt
	j.classJarSpecs = []jarSpec{classJarSpec}
	j.resourceJarSpecs = []jarSpec{resourceJarSpec}
	ctx.InstallFileName(android.PathForModuleInstall(ctx, "framework"), ctx.ModuleName()+".jar", j.classpathFile)
}

var _ Dependency = (*Prebuilt)(nil)

func (j *Prebuilt) ClasspathFile() android.Path {
	return j.classpathFile
}

func (j *Prebuilt) ClassJarSpecs() []jarSpec {
	return j.classJarSpecs
}

func (j *Prebuilt) ResourceJarSpecs() []jarSpec {
	return j.resourceJarSpecs
}

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

func PrebuiltFactory() android.Module {
	module := &Prebuilt{}

	module.AddProperties(&module.prebuilt.Properties)

	android.InitAndroidArchModule(module, android.HostAndDeviceSupported, android.MultilibCommon)
	return module
}

//
// SDK java prebuilts (.jar containing resources plus framework.aidl)
//

type sdkDependency interface {
	Dependency
	AidlPreprocessed() android.OptionalPath
}

var _ sdkDependency = (*sdkPrebuilt)(nil)

type sdkPrebuiltProperties struct {
	Aidl_preprocessed *string
}

type sdkPrebuilt struct {
	Prebuilt

	sdkProperties sdkPrebuiltProperties

	aidlPreprocessed android.OptionalPath
}

func (j *sdkPrebuilt) GenerateAndroidBuildActions(ctx android.ModuleContext) {
	j.Prebuilt.GenerateAndroidBuildActions(ctx)

	j.aidlPreprocessed = android.OptionalPathForModuleSrc(ctx, j.sdkProperties.Aidl_preprocessed)
}

func (j *sdkPrebuilt) AidlPreprocessed() android.OptionalPath {
	return j.aidlPreprocessed
}

func SdkPrebuiltFactory() android.Module {
	module := &sdkPrebuilt{}

	module.AddProperties(
		&module.prebuilt.Properties,
		&module.sdkProperties)

	android.InitAndroidArchModule(module, android.HostAndDeviceSupported, 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
}
