// Copyright 2021 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 bp2build

/*
For shareable/common bp2build testing functionality and dumping ground for
specific-but-shared functionality among tests in package
*/

import (
	"fmt"
	"path/filepath"
	"regexp"
	"sort"
	"strings"
	"testing"

	"android/soong/ui/metrics/bp2build_metrics_proto"
	"github.com/google/blueprint/proptools"

	"android/soong/android"
	"android/soong/android/allowlists"
	"android/soong/bazel"
)

var (
	buildDir string
)

var labelRegex = regexp.MustCompile(`^//([^: ]+):([^ ]+)$`)
var simpleModuleNameRegex = regexp.MustCompile(`^[^: /]+$`)

func checkError(t *testing.T, errs []error, expectedErr error) bool {
	t.Helper()

	if len(errs) != 1 {
		return false
	}
	if strings.Contains(errs[0].Error(), expectedErr.Error()) {
		return true
	}

	return false
}

func errored(t *testing.T, tc Bp2buildTestCase, errs []error) bool {
	t.Helper()
	if tc.ExpectedErr != nil {
		// Rely on checkErrors, as this test case is expected to have an error.
		return false
	}

	if len(errs) > 0 {
		for _, err := range errs {
			t.Errorf("%s: %s", tc.Description, err)
		}
		return true
	}

	// All good, continue execution.
	return false
}

func RunBp2BuildTestCaseSimple(t *testing.T, tc Bp2buildTestCase) {
	t.Helper()
	RunBp2BuildTestCase(t, func(ctx android.RegistrationContext) {}, tc)
}

type Bp2buildTestCase struct {
	Description                string
	ModuleTypeUnderTest        string
	ModuleTypeUnderTestFactory android.ModuleFactory
	// Text to add to the toplevel, root Android.bp file. If Dir is not set, all
	// ExpectedBazelTargets are assumed to be generated by this file.
	Blueprint string
	// ExpectedBazelTargets compares the BazelTargets generated in `Dir` (if not empty).
	// Otherwise, it checks the BazelTargets generated by `Blueprint` in the root directory.
	ExpectedBazelTargets []string
	// ExpectedConvertedModules asserts that modules in this list are labeled as "converted
	// by bp2build" in the metrics reported by bp2build.
	ExpectedConvertedModules []string
	// ExpectedHandcraftedModules asserts that modules in this list are labeled as "handcrafted
	// in build files" in the metrics reported by bp2build. Such modules are either explicitly
	// defined in a BUILD file (by name), or registered as "otherwise implicitly handled"
	// by bp2build (for example, by macros owned by other modules).
	ExpectedHandcraftedModules []string

	// AlreadyExistingBuildContents, if non-empty, simulates an already-present source BUILD file
	// in the directory under test. The BUILD file has the given contents. This BUILD file
	// will also be treated as "BUILD file to keep" by the simulated bp2build environment.
	AlreadyExistingBuildContents string

	// StubbedBuildDefinitions, if non-empty, adds stub definitions to already-present source
	// BUILD files for each bazel label given. The BUILD files with these stub definitions
	// are added to the BUILD file given in AlreadyExistingBuildContents.
	// Labels may be of the form //pkg/to:target_name (which would be defined in pkg/to/BUILD.bazel)
	// or `target_name` (which would be defined in ./BUILD.bazel).
	StubbedBuildDefinitions []string

	Filesystem map[string]string
	// Dir sets the directory which will be compared against the targets in ExpectedBazelTargets.
	// This should used in conjunction with the Filesystem property to check for targets
	// generated from a directory that is not the root.
	// If not set, all ExpectedBazelTargets are assumed to be generated by the text in the
	// Blueprint property.
	Dir string
	// An error with a string contained within the string of the expected error
	ExpectedErr         error
	UnconvertedDepsMode unconvertedDepsMode

	// For every directory listed here, the BUILD file for that directory will
	// be merged with the generated BUILD file. This allows custom BUILD targets
	// to be used in tests, or use BUILD files to draw package boundaries.
	KeepBuildFileForDirs []string
}

func RunBp2BuildTestCaseExtraContext(t *testing.T, registerModuleTypes func(ctx android.RegistrationContext), modifyContext func(ctx *android.TestContext), tc Bp2buildTestCase) {
	t.Helper()
	preparers := []android.FixturePreparer{
		android.FixtureRegisterWithContext(registerModuleTypes),
	}
	if modifyContext != nil {
		preparers = append(preparers, android.FixtureModifyContext(modifyContext))
	}
	preparers = append(preparers, SetBp2BuildTestRunner)
	bp2buildSetup := android.GroupFixturePreparers(
		preparers...,
	)
	runBp2BuildTestCaseWithSetup(t, bp2buildSetup, tc)
}

func RunBp2BuildTestCase(t *testing.T, registerModuleTypes func(ctx android.RegistrationContext), tc Bp2buildTestCase) {
	t.Helper()
	RunBp2BuildTestCaseExtraContext(t, registerModuleTypes, nil, tc)
}

func runBp2BuildTestCaseWithSetup(t *testing.T, extraPreparer android.FixturePreparer, tc Bp2buildTestCase) {
	t.Helper()
	if tc.Filesystem == nil {
		tc.Filesystem = map[string]string{}
	}
	checkDir := "."
	if tc.Dir != "" {
		checkDir = tc.Dir
	}
	keepExistingBuildDirs := tc.KeepBuildFileForDirs
	buildFilesToParse := []string{}

	if len(tc.StubbedBuildDefinitions) > 0 {
		for _, buildDef := range tc.StubbedBuildDefinitions {
			globalLabelMatch := labelRegex.FindStringSubmatch(buildDef)
			var dir, targetName string
			if len(globalLabelMatch) > 0 {
				dir = globalLabelMatch[1]
				targetName = globalLabelMatch[2]
			} else {
				if !simpleModuleNameRegex.MatchString(buildDef) {
					t.Errorf("Stubbed build definition '%s' must be either a simple module name or of global target syntax (//foo/bar:baz).", buildDef)
					return
				}
				dir = "."
				targetName = buildDef
			}
			buildFilePath := filepath.Join(dir, "BUILD")
			tc.Filesystem[buildFilePath] +=
				MakeBazelTarget(
					"bp2build_test_stub",
					targetName,
					AttrNameToString{})
			keepExistingBuildDirs = append(keepExistingBuildDirs, dir)
			buildFilesToParse = append(buildFilesToParse, buildFilePath)
		}
	}
	if len(tc.AlreadyExistingBuildContents) > 0 {
		buildFilePath := filepath.Join(checkDir, "BUILD")
		tc.Filesystem[buildFilePath] += tc.AlreadyExistingBuildContents
		keepExistingBuildDirs = append(keepExistingBuildDirs, checkDir)
		buildFilesToParse = append(buildFilesToParse, buildFilePath)
	}
	filesystem := make(map[string][]byte)
	for f, content := range tc.Filesystem {
		filesystem[f] = []byte(content)
	}
	preparers := []android.FixturePreparer{
		extraPreparer,
		android.FixtureMergeMockFs(filesystem),
		android.FixtureWithRootAndroidBp(tc.Blueprint),
		android.FixtureRegisterWithContext(func(ctx android.RegistrationContext) {
			ctx.RegisterModuleType(tc.ModuleTypeUnderTest, tc.ModuleTypeUnderTestFactory)
		}),
		android.FixtureModifyContextWithMockFs(func(ctx *android.TestContext) {
			// A default configuration for tests to not have to specify bp2build_available on top level
			// targets.
			bp2buildConfig := android.NewBp2BuildAllowlist().SetDefaultConfig(
				allowlists.Bp2BuildConfig{
					android.Bp2BuildTopLevel: allowlists.Bp2BuildDefaultTrueRecursively,
				},
			)
			for _, f := range keepExistingBuildDirs {
				bp2buildConfig.SetKeepExistingBuildFile(map[string]bool{
					f: /*recursive=*/ false,
				})
			}
			ctx.RegisterBp2BuildConfig(bp2buildConfig)
			// This setting is added to bp2build invocations. It prevents bp2build
			// from cloning modules to their original state after mutators run. This
			// would lose some data intentionally set by these mutators.
			ctx.SkipCloneModulesAfterMutators = true
			err := ctx.RegisterExistingBazelTargets(".", buildFilesToParse)
			if err != nil {
				t.Errorf("error parsing build files in test setup: %s", err)
			}
		}),
		android.FixtureModifyEnv(func(env map[string]string) {
			if tc.UnconvertedDepsMode == errorModulesUnconvertedDeps {
				env["BP2BUILD_ERROR_UNCONVERTED"] = "true"
			}
		}),
	}

	preparer := android.GroupFixturePreparers(preparers...)
	if tc.ExpectedErr != nil {
		pattern := "\\Q" + tc.ExpectedErr.Error() + "\\E"
		preparer = preparer.ExtendWithErrorHandler(android.FixtureExpectsOneErrorPattern(pattern))
	}
	result := preparer.RunTestWithCustomResult(t).(*BazelTestResult)
	if len(result.Errs) > 0 {
		return
	}

	expectedTargets := map[string][]string{
		checkDir: tc.ExpectedBazelTargets,
	}

	result.CompareAllBazelTargets(t, tc, expectedTargets, true)
}

// SetBp2BuildTestRunner customizes the test fixture mechanism to run tests in Bp2Build mode.
var SetBp2BuildTestRunner = android.FixtureSetTestRunner(&bazelTestRunner{})

// bazelTestRunner customizes the test fixture mechanism to run tests of the bp2build build mode.
type bazelTestRunner struct{}

func (b *bazelTestRunner) FinalPreparer(result *android.TestResult) android.CustomTestResult {
	ctx := result.TestContext
	ctx.RegisterForBazelConversion()

	return &BazelTestResult{TestResult: result}
}

func (b *bazelTestRunner) PostParseProcessor(result android.CustomTestResult) {
	bazelResult := result.(*BazelTestResult)
	ctx := bazelResult.TestContext
	config := bazelResult.Config
	_, errs := ctx.ResolveDependencies(config)
	if bazelResult.CollateErrs(errs) {
		return
	}

	codegenCtx := NewCodegenContext(config, ctx.Context, Bp2Build, "")
	res, errs := GenerateBazelTargets(codegenCtx, false)
	if bazelResult.CollateErrs(errs) {
		return
	}

	// Store additional data for access by tests.
	bazelResult.conversionResults = res
}

// BazelTestResult is a wrapper around android.TestResult to provide type safe access to the bazel
// specific data stored by the bazelTestRunner.
type BazelTestResult struct {
	*android.TestResult

	// The result returned by the GenerateBazelTargets function.
	conversionResults
}

// CompareAllBazelTargets compares the BazelTargets produced by the test for all the directories
// with the supplied set of expected targets.
//
// If ignoreUnexpected=false then this enforces an exact match where every BazelTarget produced must
// have a corresponding expected BazelTarget.
//
// If ignoreUnexpected=true then it will ignore directories for which there are no expected targets.
func (b BazelTestResult) CompareAllBazelTargets(t *testing.T, tc Bp2buildTestCase, expectedTargets map[string][]string, ignoreUnexpected bool) {
	t.Helper()
	actualTargets := b.buildFileToTargets

	// Generate the sorted set of directories to check.
	dirsToCheck := android.SortedKeys(expectedTargets)
	if !ignoreUnexpected {
		// This needs to perform an exact match so add the directories in which targets were
		// produced to the list of directories to check.
		dirsToCheck = append(dirsToCheck, android.SortedKeys(actualTargets)...)
		dirsToCheck = android.SortedUniqueStrings(dirsToCheck)
	}

	for _, dir := range dirsToCheck {
		expected := expectedTargets[dir]
		actual := actualTargets[dir]

		if expected == nil {
			if actual != nil {
				t.Errorf("did not expect any bazel modules in %q but found %d", dir, len(actual))
			}
		} else if actual == nil {
			expectedCount := len(expected)
			if expectedCount > 0 {
				t.Errorf("expected %d bazel modules in %q but did not find any", expectedCount, dir)
			}
		} else {
			b.CompareBazelTargets(t, tc.Description, expected, actual)
		}
	}

	for _, module := range tc.ExpectedConvertedModules {
		if _, found := b.metrics.convertedModulePathMap[module]; !found {
			t.Errorf("expected %s to be generated by bp2build, but was not. Map of converted modules: %s", module, b.metrics.convertedModulePathMap)
		}
	}

	for _, module := range tc.ExpectedHandcraftedModules {
		if reason, found := b.metrics.serialized.UnconvertedModules[module]; !found {
			t.Errorf("expected %s to be marked 'unconverted' by bp2build, but was not found. Full list: %s",
				module, b.metrics.serialized.UnconvertedModules)
		} else {
			if reason.Type != bp2build_metrics_proto.UnconvertedReasonType_DEFINED_IN_BUILD_FILE {
				t.Errorf("expected %s to be marked 'handcrafted' by bp2build, but was disabled for another reason: %s", module, reason)
			}
		}
	}
}

func (b BazelTestResult) CompareBazelTargets(t *testing.T, description string, expectedContents []string, actualTargets BazelTargets) {
	t.Helper()
	if actualCount, expectedCount := len(actualTargets), len(expectedContents); actualCount != expectedCount {
		t.Errorf("%s: Expected %d bazel target (%s), got %d (%s)",
			description, expectedCount, expectedContents, actualCount, actualTargets)
	} else {
		sort.SliceStable(actualTargets, func(i, j int) bool {
			return actualTargets[i].name < actualTargets[j].name
		})
		sort.SliceStable(expectedContents, func(i, j int) bool {
			return getTargetName(expectedContents[i]) < getTargetName(expectedContents[j])
		})
		for i, actualTarget := range actualTargets {
			if w, g := expectedContents[i], actualTarget.content; w != g {
				t.Errorf(
					"%s[%d]: Expected generated Bazel target to be `%s`, got `%s`",
					description, i, w, g)
			}
		}
	}
}

type nestedProps struct {
	Nested_prop *string
}

type EmbeddedProps struct {
	Embedded_prop *string
}

type OtherEmbeddedProps struct {
	Other_embedded_prop *string
}

type customProps struct {
	EmbeddedProps
	*OtherEmbeddedProps

	Bool_prop     bool
	Bool_ptr_prop *bool
	// Ensure that properties tagged `blueprint:mutated` are omitted
	Int_prop            int `blueprint:"mutated"`
	Int64_ptr_prop      *int64
	String_prop         string
	String_literal_prop *string `android:"arch_variant"`
	String_ptr_prop     *string
	String_list_prop    []string

	Nested_props     nestedProps
	Nested_props_ptr *nestedProps

	Arch_paths         []string `android:"path,arch_variant"`
	Arch_paths_exclude []string `android:"path,arch_variant"`

	// Prop used to indicate this conversion should be 1 module -> multiple targets
	One_to_many_prop *bool

	// Prop used to simulate an unsupported property in bp2build conversion. If this
	// is true, this module should be treated as "unconvertible" via bp2build.
	Does_not_convert_to_bazel *bool

	Api *string // File describing the APIs of this module

	Test_config_setting *bool // Used to test generation of config_setting targets

	Dir *string // Dir in which the Bazel Target will be created
}

type customModule struct {
	android.ModuleBase
	android.BazelModuleBase

	props customProps
}

// OutputFiles is needed because some instances of this module use dist with a
// tag property which requires the module implements OutputFileProducer.
func (m *customModule) OutputFiles(tag string) (android.Paths, error) {
	return android.PathsForTesting("path" + tag), nil
}

func (m *customModule) GenerateAndroidBuildActions(ctx android.ModuleContext) {
	// nothing for now.
}

func customModuleFactoryBase() android.Module {
	module := &customModule{}
	module.AddProperties(&module.props)
	android.InitBazelModule(module)
	return module
}

func customModuleFactoryHostAndDevice() android.Module {
	m := customModuleFactoryBase()
	android.InitAndroidArchModule(m, android.HostAndDeviceSupported, android.MultilibBoth)
	return m
}

func customModuleFactoryDeviceSupported() android.Module {
	m := customModuleFactoryBase()
	android.InitAndroidArchModule(m, android.DeviceSupported, android.MultilibBoth)
	return m
}

func customModuleFactoryHostSupported() android.Module {
	m := customModuleFactoryBase()
	android.InitAndroidArchModule(m, android.HostSupported, android.MultilibBoth)
	return m
}

func customModuleFactoryHostAndDeviceDefault() android.Module {
	m := customModuleFactoryBase()
	android.InitAndroidArchModule(m, android.HostAndDeviceDefault, android.MultilibBoth)
	return m
}

func customModuleFactoryNeitherHostNorDeviceSupported() android.Module {
	m := customModuleFactoryBase()
	android.InitAndroidArchModule(m, android.NeitherHostNorDeviceSupported, android.MultilibBoth)
	return m
}

type testProps struct {
	Test_prop struct {
		Test_string_prop string
	}
}

type customTestModule struct {
	android.ModuleBase

	props      customProps
	test_props testProps
}

func (m *customTestModule) GenerateAndroidBuildActions(ctx android.ModuleContext) {
	// nothing for now.
}

func customTestModuleFactoryBase() android.Module {
	m := &customTestModule{}
	m.AddProperties(&m.props)
	m.AddProperties(&m.test_props)
	return m
}

func customTestModuleFactory() android.Module {
	m := customTestModuleFactoryBase()
	android.InitAndroidModule(m)
	return m
}

type customDefaultsModule struct {
	android.ModuleBase
	android.DefaultsModuleBase
}

func customDefaultsModuleFactoryBase() android.DefaultsModule {
	module := &customDefaultsModule{}
	module.AddProperties(&customProps{})
	return module
}

func customDefaultsModuleFactoryBasic() android.Module {
	return customDefaultsModuleFactoryBase()
}

func customDefaultsModuleFactory() android.Module {
	m := customDefaultsModuleFactoryBase()
	android.InitDefaultsModule(m)
	return m
}

type EmbeddedAttr struct {
	Embedded_attr *string
}

type OtherEmbeddedAttr struct {
	Other_embedded_attr *string
}

type customBazelModuleAttributes struct {
	EmbeddedAttr
	*OtherEmbeddedAttr
	String_literal_prop bazel.StringAttribute
	String_ptr_prop     *string
	String_list_prop    []string
	Arch_paths          bazel.LabelListAttribute
	Api                 bazel.LabelAttribute
}

func (m *customModule) dir() *string {
	return m.props.Dir
}

func (m *customModule) ConvertWithBp2build(ctx android.Bp2buildMutatorContext) {
	if p := m.props.Does_not_convert_to_bazel; p != nil && *p {
		ctx.MarkBp2buildUnconvertible(bp2build_metrics_proto.UnconvertedReasonType_PROPERTY_UNSUPPORTED, "")
		return
	}
	if p := m.props.One_to_many_prop; p != nil && *p {
		customBp2buildOneToMany(ctx, m)
		return
	}

	paths := bazel.LabelListAttribute{}
	strAttr := bazel.StringAttribute{}
	for axis, configToProps := range m.GetArchVariantProperties(ctx, &customProps{}) {
		for config, props := range configToProps {
			if custProps, ok := props.(*customProps); ok {
				if custProps.Arch_paths != nil {
					paths.SetSelectValue(axis, config, android.BazelLabelForModuleSrcExcludes(ctx, custProps.Arch_paths, custProps.Arch_paths_exclude))
				}
				if custProps.String_literal_prop != nil {
					strAttr.SetSelectValue(axis, config, custProps.String_literal_prop)
				}
			}
		}
	}
	productVariableProps, errs := android.ProductVariableProperties(ctx, ctx.Module())
	for _, err := range errs {
		ctx.ModuleErrorf("ProductVariableProperties error: %s", err)
	}
	if props, ok := productVariableProps["String_literal_prop"]; ok {
		for c, p := range props {
			if val, ok := p.(*string); ok {
				strAttr.SetSelectValue(c.ConfigurationAxis(), c.SelectKey(), val)
			}
		}
	}

	paths.ResolveExcludes()

	attrs := &customBazelModuleAttributes{
		String_literal_prop: strAttr,
		String_ptr_prop:     m.props.String_ptr_prop,
		String_list_prop:    m.props.String_list_prop,
		Arch_paths:          paths,
	}

	attrs.Embedded_attr = m.props.Embedded_prop
	if m.props.OtherEmbeddedProps != nil {
		attrs.OtherEmbeddedAttr = &OtherEmbeddedAttr{Other_embedded_attr: m.props.OtherEmbeddedProps.Other_embedded_prop}
	}

	props := bazel.BazelTargetModuleProperties{
		Rule_class: "custom",
	}

	ctx.CreateBazelTargetModule(props, android.CommonAttributes{Name: m.Name(), Dir: m.dir()}, attrs)

	if proptools.Bool(m.props.Test_config_setting) {
		m.createConfigSetting(ctx)
	}

}

func (m *customModule) createConfigSetting(ctx android.Bp2buildMutatorContext) {
	csa := bazel.ConfigSettingAttributes{
		Flag_values: bazel.StringMapAttribute{
			"//build/bazel/rules/my_string_setting": m.Name(),
		},
	}
	ca := android.CommonAttributes{
		Name: m.Name() + "_config_setting",
	}
	ctx.CreateBazelConfigSetting(
		csa,
		ca,
		ctx.ModuleDir(),
	)
}

// A bp2build mutator that uses load statements and creates a 1:M mapping from
// module to target.
func customBp2buildOneToMany(ctx android.Bp2buildMutatorContext, m *customModule) {

	baseName := m.Name()
	attrs := &customBazelModuleAttributes{}

	myLibraryProps := bazel.BazelTargetModuleProperties{
		Rule_class:        "my_library",
		Bzl_load_location: "//build/bazel/rules:rules.bzl",
	}
	ctx.CreateBazelTargetModule(myLibraryProps, android.CommonAttributes{Name: baseName}, attrs)

	protoLibraryProps := bazel.BazelTargetModuleProperties{
		Rule_class:        "proto_library",
		Bzl_load_location: "//build/bazel/rules:proto.bzl",
	}
	ctx.CreateBazelTargetModule(protoLibraryProps, android.CommonAttributes{Name: baseName + "_proto_library_deps"}, attrs)

	myProtoLibraryProps := bazel.BazelTargetModuleProperties{
		Rule_class:        "my_proto_library",
		Bzl_load_location: "//build/bazel/rules:proto.bzl",
	}
	ctx.CreateBazelTargetModule(myProtoLibraryProps, android.CommonAttributes{Name: baseName + "_my_proto_library_deps"}, attrs)
}

// Helper method for tests to easily access the targets in a dir.
func generateBazelTargetsForDir(codegenCtx *CodegenContext, dir string) (BazelTargets, []error) {
	// TODO: Set generateFilegroups to true and/or remove the generateFilegroups argument completely
	res, err := GenerateBazelTargets(codegenCtx, false)
	if err != nil {
		return BazelTargets{}, err
	}
	return res.buildFileToTargets[dir], err
}

func registerCustomModuleForBp2buildConversion(ctx *android.TestContext) {
	ctx.RegisterModuleType("custom", customModuleFactoryHostAndDevice)
	ctx.RegisterForBazelConversion()
}

func simpleModule(typ, name string) string {
	return fmt.Sprintf(`
%s {
		name: "%s",
}`, typ, name)
}

type AttrNameToString map[string]string

func (a AttrNameToString) clone() AttrNameToString {
	newAttrs := make(AttrNameToString, len(a))
	for k, v := range a {
		newAttrs[k] = v
	}
	return newAttrs
}

// makeBazelTargetNoRestrictions returns bazel target build file definition that can be host or
// device specific, or independent of host/device.
func makeBazelTargetHostOrDevice(typ, name string, attrs AttrNameToString, hod android.HostOrDeviceSupported) string {
	if _, ok := attrs["target_compatible_with"]; !ok {
		switch hod {
		case android.HostSupported:
			attrs["target_compatible_with"] = `select({
        "//build/bazel_common_rules/platforms/os:android": ["@platforms//:incompatible"],
        "//conditions:default": [],
    })`
		case android.DeviceSupported:
			attrs["target_compatible_with"] = `["//build/bazel_common_rules/platforms/os:android"]`
		}
	}

	attrStrings := make([]string, 0, len(attrs)+1)
	if name != "" {
		attrStrings = append(attrStrings, fmt.Sprintf(`    name = "%s",`, name))
	}
	for _, k := range android.SortedKeys(attrs) {
		attrStrings = append(attrStrings, fmt.Sprintf("    %s = %s,", k, attrs[k]))
	}
	return fmt.Sprintf(`%s(
%s
)`, typ, strings.Join(attrStrings, "\n"))
}

// MakeBazelTargetNoRestrictions returns bazel target build file definition that does not add a
// target_compatible_with.  This is useful for module types like filegroup and genrule that arch not
// arch variant
func MakeBazelTargetNoRestrictions(typ, name string, attrs AttrNameToString) string {
	return makeBazelTargetHostOrDevice(typ, name, attrs, android.HostAndDeviceDefault)
}

// makeBazelTargetNoRestrictions returns bazel target build file definition that is device specific
// as this is the most common default in Soong.
func MakeBazelTarget(typ, name string, attrs AttrNameToString) string {
	return makeBazelTargetHostOrDevice(typ, name, attrs, android.DeviceSupported)
}

type ExpectedRuleTarget struct {
	Rule  string
	Name  string
	Attrs AttrNameToString
	Hod   android.HostOrDeviceSupported
}

func (ebr ExpectedRuleTarget) String() string {
	return makeBazelTargetHostOrDevice(ebr.Rule, ebr.Name, ebr.Attrs, ebr.Hod)
}

func makeCcStubSuiteTargets(name string, attrs AttrNameToString) string {
	if _, hasStubs := attrs["stubs_symbol_file"]; !hasStubs {
		return ""
	}
	STUB_SUITE_ATTRS := map[string]string{
		"api_surface":          "api_surface",
		"stubs_symbol_file":    "symbol_file",
		"stubs_versions":       "versions",
		"soname":               "soname",
		"source_library_label": "source_library_label",
	}

	stubSuiteAttrs := AttrNameToString{}
	for key, _ := range attrs {
		if _, stubSuiteAttr := STUB_SUITE_ATTRS[key]; stubSuiteAttr {
			stubSuiteAttrs[STUB_SUITE_ATTRS[key]] = attrs[key]
		} else {
			panic(fmt.Sprintf("unused cc_stub_suite attr %q\n", key))
		}
	}
	return MakeBazelTarget("cc_stub_suite", name+"_stub_libs", stubSuiteAttrs)
}

func MakeNeverlinkDuplicateTarget(moduleType string, name string) string {
	return MakeNeverlinkDuplicateTargetWithAttrs(moduleType, name, AttrNameToString{
		"sdk_version": `"current"`, // use as default
	})
}

func MakeNeverlinkDuplicateTargetWithAttrs(moduleType string, name string, extraAttrs AttrNameToString) string {
	attrs := extraAttrs
	attrs["neverlink"] = `True`
	attrs["exports"] = `[":` + name + `"]`
	return MakeBazelTarget(moduleType, name+"-neverlink", attrs)
}

func getTargetName(targetContent string) string {
	data := strings.Split(targetContent, "name = \"")
	if len(data) < 2 {
		return ""
	} else {
		endIndex := strings.Index(data[1], "\"")
		return data[1][:endIndex]
	}
}
