// 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 generates the final rules for compiling all Java.  All properties related to
// compiling should have been translated into javaBuilderFlags or another argument to the Transform*
// functions.

import (
	"path/filepath"
	"strings"

	"android/soong/common"

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

var (
	pctx = blueprint.NewPackageContext("android/soong/java")

	// Compiling java is not conducive to proper dependency tracking.  The path-matches-class-name
	// requirement leads to unpredictable generated source file names, and a single .java file
	// will get compiled into multiple .class files if it contains inner classes.  To work around
	// this, all java rules write into separate directories and then a post-processing step lists
	// the files in the the directory into a list file that later rules depend on (and sometimes
	// read from directly using @<listfile>)
	cc = pctx.StaticRule("javac",
		blueprint.RuleParams{
			Command: `$javacCmd -encoding UTF-8 $javacFlags $bootClasspath $classpath ` +
				`-extdirs "" -d $outDir @$out.rsp || ( rm -rf $outDir; exit 41 ) && ` +
				`find $outDir -name "*.class" > $out`,
			Rspfile:        "$out.rsp",
			RspfileContent: "$in",
			Description:    "javac $outDir",
		},
		"javacCmd", "javacFlags", "bootClasspath", "classpath", "outDir")

	jar = pctx.StaticRule("jar",
		blueprint.RuleParams{
			Command:     `$jarCmd -o $out $jarArgs`,
			Description: "jar $out",
		},
		"jarCmd", "jarArgs")

	dx = pctx.StaticRule("dx",
		blueprint.RuleParams{
			Command:     "$dxCmd --dex --output=$out $dxFlags $in",
			Description: "dex $out",
		},
		"outDir", "dxFlags")

	jarjar = pctx.StaticRule("jarjar",
		blueprint.RuleParams{
			Command:     "java -jar $jarjarCmd process $rulesFile $in $out",
			Description: "jarjar $out",
		},
		"rulesFile")

	extractPrebuilt = pctx.StaticRule("extractPrebuilt",
		blueprint.RuleParams{
			Command: `rm -rf $outDir && unzip -qo $in -d $outDir && ` +
				`find $outDir -name "*.class" > $classFile && ` +
				`find $outDir -type f -a \! -name "*.class" -a \! -name "MANIFEST.MF" > $resourceFile || ` +
				`(rm -rf $outDir; exit 42)`,
			Description: "extract java prebuilt $outDir",
		},
		"outDir", "classFile", "resourceFile")
)

func init() {
	pctx.StaticVariable("commonJdkFlags", "-source 1.7 -target 1.7 -Xmaxerrs 9999999")
	pctx.StaticVariable("javacCmd", "javac -J-Xmx1024M $commonJdkFlags")
	pctx.StaticVariable("jarCmd", filepath.Join(bootstrap.BinDir, "soong_jar"))
	pctx.VariableFunc("dxCmd", func(c interface{}) (string, error) {
		return c.(common.Config).HostBinTool("dx")
	})
	pctx.VariableFunc("jarjarCmd", func(c interface{}) (string, error) {
		return c.(common.Config).HostJavaTool("jarjar.jar")
	})
}

type javaBuilderFlags struct {
	javacFlags    string
	dxFlags       string
	bootClasspath string
	classpath     string
	aidlFlags     string
}

type jarSpec struct {
	fileList, dir string
}

func (j jarSpec) soongJarArgs() string {
	return "-C " + j.dir + " -l " + j.fileList
}

func TransformJavaToClasses(ctx common.AndroidModuleContext, srcFiles []string,
	flags javaBuilderFlags, deps []string) jarSpec {

	classDir := filepath.Join(common.ModuleOutDir(ctx), "classes")
	classFileList := filepath.Join(classDir, "classes.list")

	ctx.Build(pctx, blueprint.BuildParams{
		Rule:      cc,
		Outputs:   []string{classFileList},
		Inputs:    srcFiles,
		Implicits: deps,
		Args: map[string]string{
			"javacFlags":    flags.javacFlags,
			"bootClasspath": flags.bootClasspath,
			"classpath":     flags.classpath,
			"outDir":        classDir,
		},
	})

	return jarSpec{classFileList, classDir}
}

func TransformClassesToJar(ctx common.AndroidModuleContext, classes []jarSpec,
	manifest string) string {

	outputFile := filepath.Join(common.ModuleOutDir(ctx), "classes-full-debug.jar")

	deps := []string{}
	jarArgs := []string{}

	for _, j := range classes {
		deps = append(deps, j.fileList)
		jarArgs = append(jarArgs, j.soongJarArgs())
	}

	if manifest != "" {
		deps = append(deps, manifest)
		jarArgs = append(jarArgs, "-m "+manifest)
	}

	deps = append(deps, "$jarCmd")

	ctx.Build(pctx, blueprint.BuildParams{
		Rule:      jar,
		Outputs:   []string{outputFile},
		Implicits: deps,
		Args: map[string]string{
			"jarArgs": strings.Join(jarArgs, " "),
		},
	})

	return outputFile
}

func TransformClassesJarToDex(ctx common.AndroidModuleContext, classesJar string,
	flags javaBuilderFlags) string {

	outputFile := filepath.Join(common.ModuleOutDir(ctx), "classes.dex")

	ctx.Build(pctx, blueprint.BuildParams{
		Rule:      dx,
		Outputs:   []string{outputFile},
		Inputs:    []string{classesJar},
		Implicits: []string{"$dxCmd"},
		Args: map[string]string{
			"dxFlags": flags.dxFlags,
		},
	})

	return outputFile
}

func TransformDexToJavaLib(ctx common.AndroidModuleContext, resources []jarSpec,
	dexFile string) string {

	outputFile := filepath.Join(common.ModuleOutDir(ctx), "javalib.jar")
	var deps []string
	var jarArgs []string

	for _, j := range resources {
		deps = append(deps, j.fileList)
		jarArgs = append(jarArgs, j.soongJarArgs())
	}

	dexDir, _ := filepath.Split(dexFile)
	jarArgs = append(jarArgs, "-C "+dexDir+" -f "+dexFile)

	deps = append(deps, "$jarCmd", dexFile)

	ctx.Build(pctx, blueprint.BuildParams{
		Rule:      jar,
		Outputs:   []string{outputFile},
		Implicits: deps,
		Args: map[string]string{
			"jarArgs": strings.Join(jarArgs, " "),
		},
	})

	return outputFile
}

func TransformJarJar(ctx common.AndroidModuleContext, classesJar string, rulesFile string) string {
	outputFile := filepath.Join(common.ModuleOutDir(ctx), "classes-jarjar.jar")
	ctx.Build(pctx, blueprint.BuildParams{
		Rule:      jarjar,
		Outputs:   []string{outputFile},
		Inputs:    []string{classesJar},
		Implicits: []string{"$jarjarCmd"},
		Args: map[string]string{
			"rulesFile": rulesFile,
		},
	})

	return outputFile
}

func TransformPrebuiltJarToClasses(ctx common.AndroidModuleContext,
	prebuilt string) (classJarSpec, resourceJarSpec jarSpec) {

	classDir := filepath.Join(common.ModuleOutDir(ctx), "classes")
	classFileList := filepath.Join(classDir, "classes.list")
	resourceFileList := filepath.Join(classDir, "resources.list")

	ctx.Build(pctx, blueprint.BuildParams{
		Rule:    extractPrebuilt,
		Outputs: []string{classFileList, resourceFileList},
		Inputs:  []string{prebuilt},
		Args: map[string]string{
			"outDir":       classDir,
			"classFile":    classFileList,
			"resourceFile": resourceFileList,
		},
	})

	return jarSpec{classFileList, classDir}, jarSpec{resourceFileList, classDir}
}
