// 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 cc

import (
	"strconv"

	"github.com/google/blueprint"

	"android/soong/android"
)

var (
 	clangCoverageHostLdFlags = []string{
 		"-Wl,--no-as-needed",
 		"-Wl,--wrap,open",
 	}
 	clangContinuousCoverageFlags = []string{
 		"-mllvm",
 		"-runtime-counter-relocation",
 	}
 	clangCoverageCFlags = []string{
 		"-Wno-frame-larger-than=",
 	}
 	clangCoverageCommonFlags = []string{
 		"-fcoverage-mapping",
 		"-Wno-pass-failed",
 		"-D__ANDROID_CLANG_COVERAGE__",
 	}
 	clangCoverageHWASanFlags = []string{
 		"-mllvm",
 		"-hwasan-globals=0",
 	}
)

const profileInstrFlag = "-fprofile-instr-generate=/data/misc/trace/clang-%p-%m.profraw"

type CoverageProperties struct {
	Native_coverage *bool

	NeedCoverageVariant bool `blueprint:"mutated"`
	NeedCoverageBuild   bool `blueprint:"mutated"`

	CoverageEnabled   bool `blueprint:"mutated"`
	IsCoverageVariant bool `blueprint:"mutated"`
}

type coverage struct {
	Properties CoverageProperties

	// Whether binaries containing this module need --coverage added to their ldflags
	linkCoverage bool
}

func (cov *coverage) props() []interface{} {
	return []interface{}{&cov.Properties}
}

func getGcovProfileLibraryName(ctx ModuleContextIntf) string {
	// This function should only ever be called for a cc.Module, so the
	// following statement should always succeed.
	// LINT.IfChange
	if ctx.useSdk() {
		return "libprofile-extras_ndk"
	} else {
		return "libprofile-extras"
	}
}

func getClangProfileLibraryName(ctx ModuleContextIntf) string {
	if ctx.useSdk() {
		return "libprofile-clang-extras_ndk"
	} else if ctx.isCfiAssemblySupportEnabled() {
		return "libprofile-clang-extras_cfi_support"
	} else {
		return "libprofile-clang-extras"
	}
	// LINT.ThenChange(library.go)
}

func (cov *coverage) deps(ctx DepsContext, deps Deps) Deps {
	if cov.Properties.NeedCoverageVariant {
		ctx.AddVariationDependencies([]blueprint.Variation{
			{Mutator: "link", Variation: "static"},
		}, CoverageDepTag, getGcovProfileLibraryName(ctx))
		ctx.AddVariationDependencies([]blueprint.Variation{
			{Mutator: "link", Variation: "static"},
		}, CoverageDepTag, getClangProfileLibraryName(ctx))
	}
	return deps
}

func EnableContinuousCoverage(ctx android.BaseModuleContext) bool {
	return ctx.DeviceConfig().ClangCoverageContinuousMode()
}

func (cov *coverage) flags(ctx ModuleContext, flags Flags, deps PathDeps) (Flags, PathDeps) {
	clangCoverage := ctx.DeviceConfig().ClangCoverageEnabled()
	gcovCoverage := ctx.DeviceConfig().GcovCoverageEnabled()

	if !gcovCoverage && !clangCoverage {
		return flags, deps
	}

	if cov.Properties.CoverageEnabled {
		cov.linkCoverage = true

		if gcovCoverage {
			flags.GcovCoverage = true
			flags.Local.CommonFlags = append(flags.Local.CommonFlags, "--coverage", "-O0")

			// Override -Wframe-larger-than and non-default optimization
			// flags that the module may use.
			flags.Local.CFlags = append(flags.Local.CFlags, "-Wno-frame-larger-than=", "-O0")
		} else if clangCoverage {
			flags.Local.CommonFlags = append(flags.Local.CommonFlags, profileInstrFlag)
			flags.Local.CommonFlags = append(flags.Local.CommonFlags, clangCoverageCommonFlags...)
			// Override -Wframe-larger-than.  We can expect frame size increase after
			// coverage instrumentation.
			flags.Local.CFlags = append(flags.Local.CFlags, clangCoverageCFlags...)
			if EnableContinuousCoverage(ctx) {
				flags.Local.CommonFlags = append(flags.Local.CommonFlags, clangContinuousCoverageFlags...)
			}

			// http://b/248022906, http://b/247941801  enabling coverage and hwasan-globals
			// instrumentation together causes duplicate-symbol errors for __llvm_profile_filename.
			if c, ok := ctx.Module().(*Module); ok && c.sanitize.isSanitizerEnabled(Hwasan) {
				flags.Local.CommonFlags = append(flags.Local.CommonFlags, clangCoverageHWASanFlags...)
			}
		}
	}

	// Even if we don't have coverage enabled, if any of our object files were compiled
	// with coverage, then we need to add --coverage to our ldflags.
	if !cov.linkCoverage {
		if ctx.static() && !ctx.staticBinary() {
			// For static libraries, the only thing that changes our object files
			// are included whole static libraries, so check to see if any of
			// those have coverage enabled.
			ctx.VisitDirectDeps(func(m android.Module) {
				if depTag, ok := ctx.OtherModuleDependencyTag(m).(libraryDependencyTag); ok {
					if depTag.static() && depTag.wholeStatic {
						if cc, ok := m.(*Module); ok && cc.coverage != nil {
							if cc.coverage.linkCoverage {
								cov.linkCoverage = true
							}
						}
					}
				}
			})
		} else {
			// For executables and shared libraries, we need to check all of
			// our static dependencies.
			ctx.VisitDirectDeps(func(m android.Module) {
				cc, ok := m.(*Module)
				if !ok || cc.coverage == nil {
					return
				}

				if static, ok := cc.linker.(libraryInterface); !ok || !static.static() {
					return
				}

				if cc.coverage.linkCoverage {
					cov.linkCoverage = true
				}
			})
		}
	}

	if cov.linkCoverage {
		if gcovCoverage {
			flags.Local.LdFlags = append(flags.Local.LdFlags, "--coverage")

			coverage := ctx.GetDirectDepWithTag(getGcovProfileLibraryName(ctx), CoverageDepTag).(*Module)
			deps.WholeStaticLibs = append(deps.WholeStaticLibs, coverage.OutputFile().Path())

			flags.Local.LdFlags = append(flags.Local.LdFlags, "-Wl,--wrap,getenv")
		} else if clangCoverage {
			flags.Local.LdFlags = append(flags.Local.LdFlags, profileInstrFlag)
			if EnableContinuousCoverage(ctx) {
				flags.Local.LdFlags = append(flags.Local.LdFlags, "-Wl,-mllvm=-runtime-counter-relocation")
			}

			coverage := ctx.GetDirectDepWithTag(getClangProfileLibraryName(ctx), CoverageDepTag).(*Module)
			deps.WholeStaticLibs = append(deps.WholeStaticLibs, coverage.OutputFile().Path())
			flags.Local.LdFlags = append(flags.Local.LdFlags, "-Wl,--wrap,open")
		}
	}

	return flags, deps
}

func (cov *coverage) begin(ctx BaseModuleContext) {
	if ctx.Host() {
		// TODO(dwillemsen): because of -nodefaultlibs, we must depend on libclang_rt.profile-*.a
		// Just turn off for now.
	} else {
		cov.Properties = SetCoverageProperties(ctx, cov.Properties, ctx.nativeCoverage(), ctx.useSdk(), ctx.sdkVersion())
	}
}

func SetCoverageProperties(ctx android.BaseModuleContext, properties CoverageProperties, moduleTypeHasCoverage bool,
	useSdk bool, sdkVersion string) CoverageProperties {
	// Coverage is disabled globally
	if !ctx.DeviceConfig().NativeCoverageEnabled() {
		return properties
	}

	var needCoverageVariant bool
	var needCoverageBuild bool

	if moduleTypeHasCoverage {
		// Check if Native_coverage is set to false.  This property defaults to true.
		needCoverageVariant = BoolDefault(properties.Native_coverage, true)
		if useSdk && sdkVersion != "current" {
			// Native coverage is not supported for SDK versions < 23
			if fromApi, err := strconv.Atoi(sdkVersion); err == nil && fromApi < 23 {
				needCoverageVariant = false
			}
		}

		if needCoverageVariant {
			// Coverage variant is actually built with coverage if enabled for its module path
			needCoverageBuild = ctx.DeviceConfig().NativeCoverageEnabledForPath(ctx.ModuleDir())
		}
	}

	properties.NeedCoverageBuild = needCoverageBuild
	properties.NeedCoverageVariant = needCoverageVariant

	return properties
}

type UseCoverage interface {
	android.Module
	IsNativeCoverageNeeded(ctx android.IncomingTransitionContext) bool
}

// Coverage is an interface for non-CC modules to implement to be mutated for coverage
type Coverage interface {
	UseCoverage
	SetPreventInstall()
	HideFromMake()
	MarkAsCoverageVariant(bool)
	EnableCoverageIfNeeded()
}

type coverageTransitionMutator struct{}

var _ android.TransitionMutator = (*coverageTransitionMutator)(nil)

func (c coverageTransitionMutator) Split(ctx android.BaseModuleContext) []string {
	if c, ok := ctx.Module().(*Module); ok && c.coverage != nil {
		if c.coverage.Properties.NeedCoverageVariant {
			return []string{"", "cov"}
		}
	} else if cov, ok := ctx.Module().(Coverage); ok && cov.IsNativeCoverageNeeded(ctx) {
		// APEX and Rust modules fall here

		// Note: variant "" is also created because an APEX can be depended on by another
		// module which are split into "" and "cov" variants. e.g. when cc_test refers
		// to an APEX via 'data' property.
		return []string{"", "cov"}
	} else if cov, ok := ctx.Module().(UseCoverage); ok && cov.IsNativeCoverageNeeded(ctx) {
		// Module itself doesn't have to have "cov" variant, but it should use "cov" variants of
		// deps.
		return []string{"cov"}
	}

	return []string{""}
}

func (c coverageTransitionMutator) OutgoingTransition(ctx android.OutgoingTransitionContext, sourceVariation string) string {
	return sourceVariation
}

func (c coverageTransitionMutator) IncomingTransition(ctx android.IncomingTransitionContext, incomingVariation string) string {
	if c, ok := ctx.Module().(*Module); ok && c.coverage != nil {
		if !c.coverage.Properties.NeedCoverageVariant {
			return ""
		}
	} else if cov, ok := ctx.Module().(Coverage); ok {
		if !cov.IsNativeCoverageNeeded(ctx) {
			return ""
		}
	} else if cov, ok := ctx.Module().(UseCoverage); ok && cov.IsNativeCoverageNeeded(ctx) {
		// Module only has a "cov" variation, so all incoming variations should use "cov".
		return "cov"
	} else {
		return ""
	}

	return incomingVariation
}

func (c coverageTransitionMutator) Mutate(ctx android.BottomUpMutatorContext, variation string) {
	if c, ok := ctx.Module().(*Module); ok && c.coverage != nil {
		if variation == "" && c.coverage.Properties.NeedCoverageVariant {
			// Setup the non-coverage version and set HideFromMake and
			// PreventInstall to true.
			c.coverage.Properties.CoverageEnabled = false
			c.coverage.Properties.IsCoverageVariant = false
			c.Properties.HideFromMake = true
			c.Properties.PreventInstall = true
		} else if variation == "cov" {
			// The coverage-enabled version inherits HideFromMake,
			// PreventInstall from the original module.
			c.coverage.Properties.CoverageEnabled = c.coverage.Properties.NeedCoverageBuild
			c.coverage.Properties.IsCoverageVariant = true
		}
	} else if cov, ok := ctx.Module().(Coverage); ok && cov.IsNativeCoverageNeeded(ctx) {
		// APEX and Rust modules fall here

		// Note: variant "" is also created because an APEX can be depended on by another
		// module which are split into "" and "cov" variants. e.g. when cc_test refers
		// to an APEX via 'data' property.
		if variation == "" {
			cov.MarkAsCoverageVariant(false)
			cov.SetPreventInstall()
			cov.HideFromMake()
		} else if variation == "cov" {
			cov.MarkAsCoverageVariant(true)
			cov.EnableCoverageIfNeeded()
		}
	} else if cov, ok := ctx.Module().(UseCoverage); ok && cov.IsNativeCoverageNeeded(ctx) {
		// Module itself doesn't have to have "cov" variant, but it should use "cov" variants of
		// deps.
	}
}

func parseSymbolFileForAPICoverage(ctx ModuleContext, symbolFile string) android.ModuleOutPath {
	apiLevelsJson := android.GetApiLevelsJson(ctx)
	symbolFilePath := android.PathForModuleSrc(ctx, symbolFile)
	outputFile := ctx.baseModuleName() + ".xml"
	parsedApiCoveragePath := android.PathForModuleOut(ctx, outputFile)
	rule := android.NewRuleBuilder(pctx, ctx)
	rule.Command().
		BuiltTool("ndk_api_coverage_parser").
		Input(symbolFilePath).
		Output(parsedApiCoveragePath).
		Implicit(apiLevelsJson).
		FlagWithArg("--api-map ", apiLevelsJson.String())
	rule.Build("native_library_api_list", "Generate native API list based on symbol files for coverage measurement")
	return parsedApiCoveragePath
}
