// 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.Device() {
		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")

			if ctx.Device() {
				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")
			}

			if ctx.Device() {
				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() && !ctx.Os().Linux() {
		// 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 IsNativeCoverageNeededContext interface {
	Config() android.Config
	DeviceConfig() android.DeviceConfig
	Device() bool
}

var _ IsNativeCoverageNeededContext = android.IncomingTransitionContext(nil)
var _ IsNativeCoverageNeededContext = android.BaseModuleContext(nil)
var _ IsNativeCoverageNeededContext = android.BottomUpMutatorContext(nil)

type UseCoverage interface {
	android.Module
	IsNativeCoverageNeeded(ctx IsNativeCoverageNeededContext) 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
}
