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

// Rules for instrumenting classes using jacoco

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

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

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

var (
	jacoco = pctx.AndroidStaticRule("jacoco", blueprint.RuleParams{
		Command: `rm -rf $tmpDir && mkdir -p $tmpDir && ` +
			`${config.Zip2ZipCmd} -i $in -o $strippedJar $stripSpec && ` +
			`${config.JavaCmd} ${config.JavaVmFlags} -jar ${config.JacocoCLIJar} ` +
			`  instrument --quiet --dest $tmpDir $strippedJar && ` +
			`${config.Ziptime} $tmpJar && ` +
			`${config.MergeZipsCmd} --ignore-duplicates -j $out $tmpJar $in`,
		CommandDeps: []string{
			"${config.Zip2ZipCmd}",
			"${config.JavaCmd}",
			"${config.JacocoCLIJar}",
			"${config.Ziptime}",
			"${config.MergeZipsCmd}",
		},
	},
		"strippedJar", "stripSpec", "tmpDir", "tmpJar")
)

// Instruments a jar using the Jacoco command line interface.  Uses stripSpec to extract a subset
// of the classes in inputJar into strippedJar, instruments strippedJar into tmpJar, and then
// combines the classes in tmpJar with inputJar (preferring the instrumented classes in tmpJar)
// to produce instrumentedJar.
func jacocoInstrumentJar(ctx android.ModuleContext, instrumentedJar, strippedJar android.WritablePath,
	inputJar android.Path, stripSpec string) {

	// The basename of tmpJar has to be the same as the basename of strippedJar
	tmpJar := android.PathForModuleOut(ctx, "jacoco", "tmp", strippedJar.Base())

	ctx.Build(pctx, android.BuildParams{
		Rule:           jacoco,
		Description:    "jacoco",
		Output:         instrumentedJar,
		ImplicitOutput: strippedJar,
		Input:          inputJar,
		Args: map[string]string{
			"strippedJar": strippedJar.String(),
			"stripSpec":   stripSpec,
			"tmpDir":      filepath.Dir(tmpJar.String()),
			"tmpJar":      tmpJar.String(),
		},
	})
}

func (j *Module) jacocoModuleToZipCommand(ctx android.ModuleContext) string {
	includes, err := jacocoFiltersToSpecs(j.properties.Jacoco.Include_filter)
	if err != nil {
		ctx.PropertyErrorf("jacoco.include_filter", "%s", err.Error())
	}
	// Also include the default list of classes to exclude from instrumentation.
	excludes, err := jacocoFiltersToSpecs(append(j.properties.Jacoco.Exclude_filter, config.DefaultJacocoExcludeFilter...))
	if err != nil {
		ctx.PropertyErrorf("jacoco.exclude_filter", "%s", err.Error())
	}

	return jacocoFiltersToZipCommand(includes, excludes)
}

func jacocoFiltersToZipCommand(includes, excludes []string) string {
	specs := ""
	if len(excludes) > 0 {
		specs += android.JoinWithPrefix(excludes, "-x ") + " "
	}
	if len(includes) > 0 {
		specs += strings.Join(includes, " ")
	} else {
		specs += "'**/*.class'"
	}
	return specs
}

func jacocoFiltersToSpecs(filters []string) ([]string, error) {
	specs := make([]string, len(filters))
	var err error
	for i, f := range filters {
		specs[i], err = jacocoFilterToSpec(f)
		if err != nil {
			return nil, err
		}
	}
	return proptools.NinjaAndShellEscapeList(specs), nil
}

func jacocoFilterToSpec(filter string) (string, error) {
	recursiveWildcard := strings.HasSuffix(filter, "**")
	nonRecursiveWildcard := false
	if !recursiveWildcard {
		nonRecursiveWildcard = strings.HasSuffix(filter, "*")
		filter = strings.TrimSuffix(filter, "*")
	} else {
		filter = strings.TrimSuffix(filter, "**")
	}

	if recursiveWildcard && !(strings.HasSuffix(filter, ".") || filter == "") {
		return "", fmt.Errorf("only '**' or '.**' is supported as recursive wildcard in a filter")
	}

	if strings.ContainsRune(filter, '*') {
		return "", fmt.Errorf("'*' is only supported as the last character in a filter")
	}

	spec := strings.Replace(filter, ".", "/", -1)

	if recursiveWildcard {
		spec += "**/*.class"
	} else if nonRecursiveWildcard {
		spec += "*.class"
	} else {
		spec += ".class"
	}

	return spec, nil
}
