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

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

var (
	pctx = android.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>)
	javac = pctx.AndroidStaticRule("javac",
		blueprint.RuleParams{
			Command: `rm -rf "$outDir" && mkdir -p "$outDir" && ` +
				`$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.AndroidStaticRule("jar",
		blueprint.RuleParams{
			Command:     `$jarCmd -o $out $jarArgs`,
			CommandDeps: []string{"$jarCmd"},
			Description: "jar $out",
		},
		"jarCmd", "jarArgs")

	dx = pctx.AndroidStaticRule("dx",
		blueprint.RuleParams{
			Command: `rm -rf "$outDir" && mkdir -p "$outDir" && ` +
				`$dxCmd --dex --output=$outDir $dxFlags $in || ( rm -rf "$outDir"; exit 41 ) && ` +
				`find "$outDir" -name "classes*.dex" > $out`,
			CommandDeps: []string{"$dxCmd"},
			Description: "dex $out",
		},
		"outDir", "dxFlags")

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

	extractPrebuilt = pctx.AndroidStaticRule("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.Import("github.com/google/blueprint/bootstrap")
	pctx.StaticVariable("commonJdkFlags", "-source 1.7 -target 1.7 -Xmaxerrs 9999999")
	pctx.StaticVariable("javacCmd", "javac -J-Xmx1024M $commonJdkFlags")
	pctx.StaticVariable("jarCmd", filepath.Join("${bootstrap.ToolDir}", "soong_zip"))
	pctx.HostBinToolVariable("dxCmd", "dx")
	pctx.HostJavaToolVariable("jarjarCmd", "jarjar.jar")
}

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

type jarSpec struct {
	fileList, dir android.Path
}

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

func TransformJavaToClasses(ctx android.ModuleContext, srcFiles android.Paths, srcFileLists android.Paths,
	flags javaBuilderFlags, deps android.Paths) jarSpec {

	classDir := android.PathForModuleOut(ctx, "classes")
	classFileList := android.PathForModuleOut(ctx, "classes.list")

	javacFlags := flags.javacFlags + android.JoinWithPrefix(srcFileLists.Strings(), "@")

	deps = append(deps, srcFileLists...)

	ctx.ModuleBuild(pctx, android.ModuleBuildParams{
		Rule:      javac,
		Output:    classFileList,
		Inputs:    srcFiles,
		Implicits: deps,
		Args: map[string]string{
			"javacFlags":    javacFlags,
			"bootClasspath": flags.bootClasspath,
			"classpath":     flags.classpath,
			"outDir":        classDir.String(),
		},
	})

	return jarSpec{classFileList, classDir}
}

func TransformClassesToJar(ctx android.ModuleContext, classes []jarSpec,
	manifest android.OptionalPath) android.Path {

	outputFile := android.PathForModuleOut(ctx, "classes-full-debug.jar")

	deps := android.Paths{}
	jarArgs := []string{}

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

	if manifest.Valid() {
		deps = append(deps, manifest.Path())
		jarArgs = append(jarArgs, "-m "+manifest.String())
	}

	ctx.ModuleBuild(pctx, android.ModuleBuildParams{
		Rule:      jar,
		Output:    outputFile,
		Implicits: deps,
		Args: map[string]string{
			"jarArgs": strings.Join(jarArgs, " "),
		},
	})

	return outputFile
}

func TransformClassesJarToDex(ctx android.ModuleContext, classesJar android.Path,
	flags javaBuilderFlags) jarSpec {

	outDir := android.PathForModuleOut(ctx, "dex")
	outputFile := android.PathForModuleOut(ctx, "dex.filelist")

	ctx.ModuleBuild(pctx, android.ModuleBuildParams{
		Rule:   dx,
		Output: outputFile,
		Input:  classesJar,
		Args: map[string]string{
			"dxFlags": flags.dxFlags,
			"outDir":  outDir.String(),
		},
	})

	return jarSpec{outputFile, outDir}
}

func TransformDexToJavaLib(ctx android.ModuleContext, resources []jarSpec,
	dexJarSpec jarSpec) android.Path {

	outputFile := android.PathForModuleOut(ctx, "javalib.jar")
	var deps android.Paths
	var jarArgs []string

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

	deps = append(deps, dexJarSpec.fileList)
	jarArgs = append(jarArgs, dexJarSpec.soongJarArgs())

	ctx.ModuleBuild(pctx, android.ModuleBuildParams{
		Rule:      jar,
		Output:    outputFile,
		Implicits: deps,
		Args: map[string]string{
			"jarArgs": strings.Join(jarArgs, " "),
		},
	})

	return outputFile
}

func TransformJarJar(ctx android.ModuleContext, classesJar android.Path, rulesFile android.Path) android.Path {
	outputFile := android.PathForModuleOut(ctx, "classes-jarjar.jar")
	ctx.ModuleBuild(pctx, android.ModuleBuildParams{
		Rule:     jarjar,
		Output:   outputFile,
		Input:    classesJar,
		Implicit: rulesFile,
		Args: map[string]string{
			"rulesFile": rulesFile.String(),
		},
	})

	return outputFile
}

func TransformPrebuiltJarToClasses(ctx android.ModuleContext,
	prebuilt android.Path) (classJarSpec, resourceJarSpec jarSpec) {

	classDir := android.PathForModuleOut(ctx, "extracted/classes")
	classFileList := android.PathForModuleOut(ctx, "extracted/classes.list")
	resourceFileList := android.PathForModuleOut(ctx, "extracted/resources.list")

	ctx.ModuleBuild(pctx, android.ModuleBuildParams{
		Rule:    extractPrebuilt,
		Outputs: android.WritablePaths{classFileList, resourceFileList},
		Input:   prebuilt,
		Args: map[string]string{
			"outDir":       classDir.String(),
			"classFile":    classFileList.String(),
			"resourceFile": resourceFileList.String(),
		},
	})

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