// Copyright (C) 2018 The Android Open Source Project
//
// 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 aidl

import (
	"android/soong/android"
	"android/soong/cc"
	"android/soong/java"
	"android/soong/phony"
	"android/soong/rust"

	"fmt"
	"path/filepath"
	"regexp"
	"sort"
	"strconv"
	"strings"

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

const (
	aidlInterfaceSuffix       = "_interface"
	aidlMetadataSingletonName = "aidl_metadata_json"
	aidlApiDir                = "aidl_api"
	aidlApiSuffix             = "-api"
	langCpp                   = "cpp"
	langJava                  = "java"
	langNdk                   = "ndk"
	langRust                  = "rust"
	// TODO(b/161456198) remove the NDK platform backend as the 'platform' variant of the NDK
	// backend serves the same purpose.
	langNdkPlatform = "ndk_platform"

	currentVersion = "current"
)

var (
	pctx = android.NewPackageContext("android/aidl")
)

func init() {
	pctx.Import("android/soong/android")
	pctx.HostBinToolVariable("aidlCmd", "aidl")
	pctx.HostBinToolVariable("aidlHashGen", "aidl_hash_gen")
	pctx.SourcePathVariable("aidlToJniCmd", "system/tools/aidl/build/aidl_to_jni.py")
	pctx.SourcePathVariable("aidlRustGlueCmd", "system/tools/aidl/build/aidl_rust_glue.py")
	android.RegisterModuleType("aidl_interface", aidlInterfaceFactory)
	android.PreArchMutators(registerPreArchMutators)
	android.PreArchBp2BuildMutators(registerPreArchMutators)
	android.PostDepsMutators(registerPostDepsMutators)
}

func registerPreArchMutators(ctx android.RegisterMutatorsContext) {
	ctx.BottomUp("addInterfaceDeps", addInterfaceDeps).Parallel()
	ctx.BottomUp("checkImports", checkImports).Parallel()
	ctx.TopDown("createAidlInterface", createAidlInterfaceMutator).Parallel()
}

func registerPostDepsMutators(ctx android.RegisterMutatorsContext) {
	ctx.BottomUp("checkAidlGeneratedModules", checkAidlGeneratedModules).Parallel()
}

func createAidlInterfaceMutator(mctx android.TopDownMutatorContext) {
	if g, ok := mctx.Module().(*aidlImplementationGenerator); ok {
		g.GenerateImplementation(mctx)
	}
}

// A marker struct for AIDL-generated library modules
type AidlGeneratedModuleProperties struct{}

func wrapLibraryFactory(factory func() android.Module) func() android.Module {
	return func() android.Module {
		m := factory()
		// put a marker struct for AIDL-generated modules
		m.AddProperties(&AidlGeneratedModuleProperties{})
		return m
	}
}

func isAidlGeneratedModule(module android.Module) bool {
	for _, props := range module.GetProperties() {
		// check if there's a marker struct
		if _, ok := props.(*AidlGeneratedModuleProperties); ok {
			return true
		}
	}
	return false
}

// AildVersionInfo keeps the *-source module for each (aidl_interface & lang) and the list of
// not-frozen versions (which shouldn't be used by other modules)
type AildVersionInfo struct {
	notFrozen []string
	sourceMap map[string]string
}

var AidlVersionInfoProvider = blueprint.NewMutatorProvider(AildVersionInfo{}, "checkAidlGeneratedModules")

// Merges `other` version info into this one.
// Returns the pair of mismatching versions when there's conflict. Otherwise returns nil.
// For example, when a module depends on 'foo-V2-ndk', the map contains an entry of (foo, foo-V2-ndk-source).
// Merging (foo, foo-V1-ndk-source) and (foo, foo-V2-ndk-source) will fail and returns
// {foo-V1-ndk-source, foo-V2-ndk-source}.
func (info *AildVersionInfo) merge(other AildVersionInfo) []string {
	info.notFrozen = append(info.notFrozen, other.notFrozen...)

	if other.sourceMap == nil {
		return nil
	}
	if info.sourceMap == nil {
		info.sourceMap = make(map[string]string)
	}
	for ifaceName, otherSourceName := range other.sourceMap {
		if sourceName, ok := info.sourceMap[ifaceName]; ok {
			if sourceName != otherSourceName {
				return []string{sourceName, otherSourceName}
			}
		} else {
			info.sourceMap[ifaceName] = otherSourceName
		}
	}
	return nil
}

func reportUsingNotFrozenError(ctx android.BaseModuleContext, notFrozen []string) {
	// TODO(b/154066686): Replace it with a common method instead of listing up module types.
	// Test libraries are exempted.
	if android.InList(ctx.ModuleType(), []string{"cc_test_library", "android_test", "cc_benchmark", "cc_test"}) {
		return
	}
	for _, name := range notFrozen {
		ctx.ModuleErrorf("%v is disallowed in release version because it is unstable, and its \"owner\" property is missing.",
			name)
	}
}

func reportMultipleVersionError(ctx android.BaseModuleContext, violators []string) {
	sort.Strings(violators)
	ctx.ModuleErrorf("depends on multiple versions of the same aidl_interface: %s", strings.Join(violators, ", "))
	ctx.WalkDeps(func(child android.Module, parent android.Module) bool {
		if android.InList(child.Name(), violators) {
			ctx.ModuleErrorf("Dependency path: %s", ctx.GetPathString(true))
			return false
		}
		return true
	})
}

func checkAidlGeneratedModules(mctx android.BottomUpMutatorContext) {
	switch mctx.Module().(type) {
	case *java.Library:
	case *cc.Module:
	case *rust.Module:
	case *aidlGenRule:
	default:
		return
	}
	if gen, ok := mctx.Module().(*aidlGenRule); ok {
		var notFrozen []string
		if gen.properties.NotFrozen {
			notFrozen = []string{strings.TrimSuffix(mctx.ModuleName(), "-source")}
		}
		mctx.SetProvider(AidlVersionInfoProvider, AildVersionInfo{
			notFrozen: notFrozen,
			sourceMap: map[string]string{
				gen.properties.BaseName + "-" + gen.properties.Lang: gen.Name(),
			},
		})
		return
	}
	// Collect/merge AildVersionInfos from direct dependencies
	var info AildVersionInfo
	mctx.VisitDirectDeps(func(dep android.Module) {
		if mctx.OtherModuleHasProvider(dep, AidlVersionInfoProvider) {
			otherInfo := mctx.OtherModuleProvider(dep, AidlVersionInfoProvider).(AildVersionInfo)
			if violators := info.merge(otherInfo); violators != nil {
				reportMultipleVersionError(mctx, violators)
			}
		}
	})
	if !isAidlGeneratedModule(mctx.Module()) && len(info.notFrozen) > 0 {
		reportUsingNotFrozenError(mctx, info.notFrozen)
	}
	if mctx.Failed() {
		return
	}
	if info.sourceMap != nil || len(info.notFrozen) > 0 {
		mctx.SetProvider(AidlVersionInfoProvider, info)
	}
}

func getPaths(ctx android.ModuleContext, rawSrcs []string, root string) (srcs android.Paths, imports []string) {
	// TODO(b/189288369): move this to android.PathsForModuleSrcSubDir(ctx, srcs, subdir)
	for _, src := range rawSrcs {
		if m, _ := android.SrcIsModuleWithTag(src); m != "" {
			srcs = append(srcs, android.PathsForModuleSrc(ctx, []string{src})...)
		} else {
			srcs = append(srcs, android.PathsWithModuleSrcSubDir(ctx, android.PathsForModuleSrc(ctx, []string{src}), root)...)
		}
	}

	if len(srcs) == 0 {
		ctx.PropertyErrorf("srcs", "No sources provided in %v", root)
	}

	// gather base directories from input .aidl files
	for _, src := range srcs {
		if src.Ext() != ".aidl" {
			// Silently ignore non-aidl files as some filegroups have both java and aidl files together
			continue
		}
		baseDir := strings.TrimSuffix(src.String(), src.Rel())
		baseDir = strings.TrimSuffix(baseDir, "/")
		if baseDir != "" && !android.InList(baseDir, imports) {
			imports = append(imports, baseDir)
		}
	}

	return srcs, imports
}

func isRelativePath(path string) bool {
	if path == "" {
		return true
	}
	return filepath.Clean(path) == path && path != ".." &&
		!strings.HasPrefix(path, "../") && !strings.HasPrefix(path, "/")
}

type CommonBackendProperties struct {
	// Whether to generate code in the corresponding backend.
	// Default: true
	Enabled        *bool
	Apex_available []string

	// The minimum version of the sdk that the compiled artifacts will run against
	// For native modules, the property needs to be set when a module is a part of mainline modules(APEX).
	// Forwarded to generated java/native module.
	Min_sdk_version *string
}

type CommonNativeBackendProperties struct {
	CommonBackendProperties
	// Whether to generate additional code for gathering information
	// about the transactions.
	// Default: false
	Gen_log *bool

	// VNDK properties for correspdoning backend.
	cc.VndkProperties
}

type DumpApiProperties struct {
	// Dumps without license header (assuming it is the first comment in .aidl file). Default: false
	No_license *bool
}

type aidlInterfaceProperties struct {
	// Vndk properties for C++/NDK libraries only (preferred to use backend-specific settings)
	cc.VndkProperties

	// How to interpret VNDK options. We only want one library in the VNDK (not multiple
	// versions, since this would be a waste of space/unclear, and ultimately we want all
	// code in a given release to be updated to use a specific version). By default, this
	// puts either the latest stable version of the library or, if there is no stable
	// version, the unstable version of the library in the VNDK. When using this field,
	// explicitly set it to one of the values in the 'versions' field to put that version
	// in the VNDK or set it to the next version (1 higher than this) to mean the version
	// that will be frozen in the next update.
	Vndk_use_version *string

	// Whether the library can be installed on the vendor image.
	Vendor_available *bool

	// Whether the library can be installed on the odm image.
	Odm_available *bool

	// Whether the library can be installed on the product image.
	Product_available *bool

	// Whether the library can be installed on the recovery image.
	Recovery_available *bool

	// Whether the library can be loaded multiple times into the same process
	Double_loadable *bool

	// Whether the library can be used on host
	Host_supported *bool

	// Whether tracing should be added to the interface.
	Gen_trace *bool

	// Top level directories for includes.
	// TODO(b/128940869): remove it if aidl_interface can depend on framework.aidl
	Include_dirs []string
	// Relative path for includes. By default assumes AIDL path is relative to current directory.
	Local_include_dir string

	// List of .aidl files which compose this interface.
	Srcs []string `android:"path"`

	// List of aidl_interface modules that this uses. If one of your AIDL interfaces uses an
	// interface or parcelable from another aidl_interface, you should put its name here.
	// It could be an aidl_interface solely or with version(such as -V1)
	Imports []string

	// Stability promise. Currently only supports "vintf".
	// If this is unset, this corresponds to an interface with stability within
	// this compilation context (so an interface loaded here can only be used
	// with things compiled together, e.g. on the system.img).
	// If this is set to "vintf", this corresponds to a stability promise: the
	// interface must be kept stable as long as it is used.
	Stability *string

	// Previous API versions that are now frozen. The version that is last in
	// the list is considered as the most recent version.
	Versions []string

	// The minimum version of the sdk that the compiled artifacts will run against
	// For native modules, the property needs to be set when a module is a part of mainline modules(APEX).
	// Forwarded to generated java/native module. This can be overridden by
	// backend.<name>.min_sdk_version.
	Min_sdk_version *string

	Backend struct {
		// Backend of the compiler generating code for Java clients.
		// When enabled, this creates a target called "<name>-java".
		Java struct {
			CommonBackendProperties
			// Set to the version of the sdk to compile against
			// Default: system_current
			Sdk_version *string
			// Whether to compile against platform APIs instead of
			// an SDK.
			Platform_apis *bool
			// Whether RPC features are enabled (requires API level 32)
			// TODO(b/175819535): enable this automatically?
			Gen_rpc *bool
			// Lint properties for generated java module
			java.LintProperties
		}
		// Backend of the compiler generating code for C++ clients using
		// libbinder (unstable C++ interface)
		// When enabled, this creates a target called "<name>-cpp".
		Cpp struct {
			CommonNativeBackendProperties
		}
		// Backend of the compiler generating code for C++ clients using libbinder_ndk
		// (stable C interface to system's libbinder) When enabled, this creates a target
		// called "<name>-V<ver>-ndk" (for both apps and platform) and
		// "<name>-V<ver>-ndk_platform" (for platform only).
		// TODO(b/161456198): remove the ndk_platform backend as the ndk backend can serve
		// the same purpose.
		Ndk struct {
			CommonNativeBackendProperties

			// If set to false, the ndk backend is exclusive to platform and is not
			// available to applications. Default is true (i.e. available to both
			// applications and platform).
			Apps_enabled *bool
		}
		// Backend of the compiler generating code for Rust clients.
		// When enabled, this creates a target called "<name>-rust".
		Rust struct {
			CommonBackendProperties
		}
	}

	// Marks that this interface does not need to be stable. When set to true, the build system
	// doesn't create the API dump and require it to be updated. Default is false.
	Unstable *bool

	// Optional flags to be passed to the AIDL compiler. e.g. "-Weverything"
	Flags []string

	// --dumpapi options
	Dumpapi DumpApiProperties
}

type aidlInterface struct {
	android.ModuleBase

	properties aidlInterfaceProperties

	computedTypes []string

	// list of module names that are created for this interface
	internalModuleNames []string

	// map for version to preprocessed.aidl file.
	// There's two additional alias for versions:
	// - ""(empty) is for ToT
	// - "latest" is for i.latestVersion()
	preprocessed map[string]android.WritablePath
}

func (i *aidlInterface) shouldGenerateJavaBackend() bool {
	// explicitly true if not specified to give early warning to devs
	return proptools.BoolDefault(i.properties.Backend.Java.Enabled, true)
}

func (i *aidlInterface) shouldGenerateCppBackend() bool {
	// explicitly true if not specified to give early warning to devs
	return proptools.BoolDefault(i.properties.Backend.Cpp.Enabled, true)
}

func (i *aidlInterface) shouldGenerateNdkBackend() bool {
	// explicitly true if not specified to give early warning to devs
	return proptools.BoolDefault(i.properties.Backend.Ndk.Enabled, true)
}

// Returns whether the ndk backend supports applications or not. Default is `true`. `false` is
// returned when `apps_enabled` is explicitly set to false or the interface is exclusive to vendor
// (i.e. `vendor: true`). Note that the ndk_platform backend (which will be removed in the future)
// is not affected by this. In other words, it is always exclusive for the platform, as its name
// clearly shows.
func (i *aidlInterface) shouldGenerateAppNdkBackend() bool {
	return i.shouldGenerateNdkBackend() &&
		proptools.BoolDefault(i.properties.Backend.Ndk.Apps_enabled, true) &&
		!i.SocSpecific()
}

func (i *aidlInterface) shouldGenerateRustBackend() bool {
	return i.properties.Backend.Rust.Enabled != nil && *i.properties.Backend.Rust.Enabled
}

func (i *aidlInterface) minSdkVersion(lang string) *string {
	var ver *string
	switch lang {
	case langCpp:
		ver = i.properties.Backend.Cpp.Min_sdk_version
	case langJava:
		ver = i.properties.Backend.Java.Min_sdk_version
	case langNdk, langNdkPlatform:
		ver = i.properties.Backend.Ndk.Min_sdk_version
	case langRust:
		ver = i.properties.Backend.Rust.Min_sdk_version
	default:
		panic(fmt.Errorf("unsupported language backend %q\n", lang))
	}
	if ver == nil {
		return i.properties.Min_sdk_version
	}
	return ver
}

// Dep to *-api module(aidlApi)
type apiDepTag struct {
	blueprint.BaseDependencyTag
	name string
}

type importInterfaceDepTag struct {
	blueprint.BaseDependencyTag
	anImport string
}

type interfaceDepTag struct {
	blueprint.BaseDependencyTag
}

var (
	// Dep from *-source (aidlGenRule) to *-api (aidlApi)
	apiDep = apiDepTag{name: "api"}
	// Dep from *-api (aidlApi) to *-api (aidlApi), representing imported interfaces
	importApiDep = apiDepTag{name: "imported-api"}
	// Dep to original *-interface (aidlInterface)
	interfaceDep = interfaceDepTag{}
)

func addImportedInterfaceDeps(ctx android.BottomUpMutatorContext, imports []string) {
	for _, anImport := range imports {
		name, _ := parseModuleWithVersion(anImport)
		ctx.AddDependency(ctx.Module(), importInterfaceDepTag{anImport: anImport}, name+aidlInterfaceSuffix)
	}
}

// Run custom "Deps" mutator between AIDL modules created at LoadHook stage.
// We can't use the "DepsMutator" for these dependencies because
// - We need to create library modules (cc/java/...) before "arch" mutator. Note that cc_library
//   should be mutated by os/image/arch mutators as well.
// - When creating library modules, we need to access the original interface and its imported
//   interfaces to determine which version to use. See aidlInterface.getImportWithVersion.
func addInterfaceDeps(mctx android.BottomUpMutatorContext) {
	switch i := mctx.Module().(type) {
	case *aidlInterface:
		// In fact this isn't necessary because soong checks dependencies on undefined modules.
		// But since aidl_interface overrides its name internally, this provides better error message.
		for _, anImportWithVersion := range i.properties.Imports {
			anImport, _ := parseModuleWithVersion(anImportWithVersion)
			if !mctx.OtherModuleExists(anImport + aidlInterfaceSuffix) {
				if !mctx.Config().AllowMissingDependencies() {
					mctx.PropertyErrorf("imports", "Import does not exist: "+anImport)
				}
			}
		}
		if mctx.Failed() {
			return
		}
		addImportedInterfaceDeps(mctx, i.properties.Imports)
	case *aidlImplementationGenerator:
		mctx.AddDependency(i, interfaceDep, i.properties.AidlInterfaceName+aidlInterfaceSuffix)
		addImportedInterfaceDeps(mctx, i.properties.Imports)
	case *rust.Module:
		for _, props := range i.GetProperties() {
			if sp, ok := props.(*aidlRustSourceProviderProperties); ok {
				mctx.AddDependency(i, interfaceDep, sp.AidlInterfaceName+aidlInterfaceSuffix)
				addImportedInterfaceDeps(mctx, sp.Imports)
				break
			}
		}
	case *aidlApi:
		mctx.AddDependency(i, interfaceDep, i.properties.BaseName+aidlInterfaceSuffix)
		addImportedInterfaceDeps(mctx, i.properties.Imports)
		for _, anImport := range i.properties.Imports {
			name, _ := parseModuleWithVersion(anImport)
			mctx.AddDependency(i, importApiDep, name+aidlApiSuffix)
		}
	case *aidlGenRule:
		mctx.AddDependency(i, interfaceDep, i.properties.BaseName+aidlInterfaceSuffix)
		addImportedInterfaceDeps(mctx, i.properties.Imports)
		if !proptools.Bool(i.properties.Unstable) {
			// for checkapi timestamps
			mctx.AddDependency(i, apiDep, i.properties.BaseName+aidlApiSuffix)
		}
	}
}

// checkImports checks if "import:" property is valid.
// In fact, this isn't necessary because Soong can check/report when we add a dependency to
// undefined/unknown module. But module names are very implementation specific and may not be easy
// to understand. For example, when foo (with java enabled) depends on bar (with java disabled), the
// error message would look like "foo-V2-java depends on unknown module `bar-V3-java`", which isn't
// clear that backend.java.enabled should be turned on.
func checkImports(mctx android.BottomUpMutatorContext) {
	if i, ok := mctx.Module().(*aidlInterface); ok {
		mctx.VisitDirectDeps(func(dep android.Module) {
			tag, ok := mctx.OtherModuleDependencyTag(dep).(importInterfaceDepTag)
			if !ok {
				return
			}
			other := dep.(*aidlInterface)
			anImport := other.ModuleBase.Name()
			anImportWithVersion := tag.anImport
			_, version := parseModuleWithVersion(tag.anImport)
			if version != "" {
				candidateVersions := concat(other.properties.Versions, []string{other.nextVersion()})
				if !android.InList(version, candidateVersions) {
					mctx.PropertyErrorf("imports", "%q depends on %q version %q(%q), which doesn't exist. The version must be one of %q", i.ModuleBase.Name(), anImport, version, anImportWithVersion, candidateVersions)
				}
			}
			if i.shouldGenerateJavaBackend() && !other.shouldGenerateJavaBackend() {
				mctx.PropertyErrorf("backend.java.enabled",
					"Java backend not enabled in the imported AIDL interface %q", anImport)
			}

			if i.shouldGenerateCppBackend() && !other.shouldGenerateCppBackend() {
				mctx.PropertyErrorf("backend.cpp.enabled",
					"C++ backend not enabled in the imported AIDL interface %q", anImport)
			}

			if i.shouldGenerateNdkBackend() && !other.shouldGenerateNdkBackend() {
				mctx.PropertyErrorf("backend.ndk.enabled",
					"NDK backend not enabled in the imported AIDL interface %q", anImport)
			}

			if i.shouldGenerateRustBackend() && !other.shouldGenerateRustBackend() {
				mctx.PropertyErrorf("backend.rust.enabled",
					"Rust backend not enabled in the imported AIDL interface %q", anImport)
			}
		})
	}
}

func (i *aidlInterface) checkGenTrace(mctx android.LoadHookContext) {
	if !proptools.Bool(i.properties.Gen_trace) {
		return
	}
	if i.shouldGenerateJavaBackend() && !proptools.Bool(i.properties.Backend.Java.Platform_apis) {
		mctx.PropertyErrorf("gen_trace", "must be false when Java backend is enabled and platform_apis is false")
	}
}

func (i *aidlInterface) checkStability(mctx android.LoadHookContext) {
	if i.properties.Stability == nil {
		return
	}

	if proptools.Bool(i.properties.Unstable) {
		mctx.PropertyErrorf("stability", "must be empty when \"unstable\" is true")
	}

	// TODO(b/136027762): should we allow more types of stability (e.g. for APEX) or
	// should we switch this flag to be something like "vintf { enabled: true }"
	isVintf := "vintf" == proptools.String(i.properties.Stability)
	if !isVintf {
		mctx.PropertyErrorf("stability", "must be empty or \"vintf\"")
	}
}
func (i *aidlInterface) checkVersions(mctx android.LoadHookContext) {
	versions := make(map[string]bool)
	intVersions := make([]int, 0, len(i.properties.Versions))
	for _, ver := range i.properties.Versions {
		if _, dup := versions[ver]; dup {
			mctx.PropertyErrorf("versions", "duplicate found", ver)
			continue
		}
		versions[ver] = true
		n, err := strconv.Atoi(ver)
		if err != nil {
			mctx.PropertyErrorf("versions", "%q is not an integer", ver)
			continue
		}
		if n <= 0 {
			mctx.PropertyErrorf("versions", "should be > 0, but is %v", ver)
			continue
		}
		intVersions = append(intVersions, n)

	}
	if !mctx.Failed() && !sort.IntsAreSorted(intVersions) {
		mctx.PropertyErrorf("versions", "should be sorted, but is %v", i.properties.Versions)
	}
}
func (i *aidlInterface) checkVndkUseVersion(mctx android.LoadHookContext) {
	if i.properties.Vndk_use_version == nil {
		return
	}
	if !i.hasVersion() {
		mctx.PropertyErrorf("vndk_use_version", "This does not make sense when no 'versions' are specified.")

	}
	if *i.properties.Vndk_use_version == i.nextVersion() {
		return
	}
	for _, ver := range i.properties.Versions {
		if *i.properties.Vndk_use_version == ver {
			return
		}
	}
	mctx.PropertyErrorf("vndk_use_version", "Specified version %q does not exist", *i.properties.Vndk_use_version)
}

func (i *aidlInterface) nextVersion() string {
	if proptools.Bool(i.properties.Unstable) {
		return ""
	}
	return nextVersion(i.properties.Versions)
}

func nextVersion(versions []string) string {
	if len(versions) == 0 {
		return "1"
	}
	ver := versions[len(versions)-1]
	i, err := strconv.Atoi(ver)
	if err != nil {
		panic(err)
	}
	return strconv.Itoa(i + 1)
}

func (i *aidlInterface) latestVersion() string {
	if !i.hasVersion() {
		return "0"
	}
	return i.properties.Versions[len(i.properties.Versions)-1]
}

func (i *aidlInterface) hasVersion() bool {
	return len(i.properties.Versions) > 0
}

func hasVersionSuffix(moduleName string) bool {
	hasVersionSuffix, _ := regexp.MatchString("-V\\d+$", moduleName)
	return hasVersionSuffix
}

func parseModuleWithVersion(moduleName string) (string, string) {
	if hasVersionSuffix(moduleName) {
		versionIdx := strings.LastIndex(moduleName, "-V")
		if versionIdx == -1 {
			panic("-V must exist in this context")
		}
		return moduleName[:versionIdx], moduleName[versionIdx+len("-V"):]
	}
	return moduleName, ""
}

func trimVersionSuffixInList(moduleNames []string) []string {
	return wrapFunc("", moduleNames, "", func(moduleName string) string {
		moduleNameWithoutVersion, _ := parseModuleWithVersion(moduleName)
		return moduleNameWithoutVersion
	})
}

func aidlInterfaceHook(mctx android.LoadHookContext, i *aidlInterface) {
	if hasVersionSuffix(i.ModuleBase.Name()) {
		mctx.PropertyErrorf("name", "aidl_interface should not have '-V<number> suffix")
	}
	if !isRelativePath(i.properties.Local_include_dir) {
		mctx.PropertyErrorf("local_include_dir", "must be relative path: "+i.properties.Local_include_dir)
	}

	i.checkStability(mctx)
	i.checkVersions(mctx)
	i.checkVndkUseVersion(mctx)
	i.checkGenTrace(mctx)

	if mctx.Failed() {
		return
	}

	var libs []string

	unstable := proptools.Bool(i.properties.Unstable)

	if unstable {
		if i.hasVersion() {
			mctx.PropertyErrorf("versions", "cannot have versions for an unstable interface")
			return
		}
		if i.properties.Stability != nil {
			mctx.ModuleErrorf("unstable:true and stability:%q cannot happen at the same time", i.properties.Stability)
			return
		}
	}

	sdkIsFinal := !mctx.Config().DefaultAppTargetSdk(mctx).IsPreview()
	requireFrozenNoOwner := i.Owner() == "" && (sdkIsFinal || mctx.Config().IsEnvTrue("AIDL_FROZEN_REL"))
	requireFrozenWithOwner := i.Owner() != "" && android.InList(i.Owner(), strings.Fields(mctx.Config().Getenv("AIDL_FROZEN_OWNERS")))
	requireFrozenByOwner := requireFrozenNoOwner || requireFrozenWithOwner

	// Two different types of 'unstable' here
	// - 'unstable: true' meaning the module is never stable
	// - current unfrozen ToT version
	//
	// OEM branches may remove 'i.Owner()' here to apply the check to all interfaces, in
	// addition to core platform interfaces. Otherwise, we rely on vts_treble_vintf_vendor_test.
	requireFrozenVersion := !unstable && requireFrozenByOwner

	// surface error early, main check is via checkUnstableModuleMutator
	if requireFrozenVersion && !i.hasVersion() {
		mctx.PropertyErrorf("versions", "must be set (need to be frozen) when \"unstable\" is false, PLATFORM_VERSION_CODENAME is REL, and \"owner\" property is missing.")
	}

	versions := i.properties.Versions
	nextVersion := i.nextVersion()
	shouldGenerateLangBackendMap := map[string]bool{
		langCpp:  i.shouldGenerateCppBackend(),
		langNdk:  i.shouldGenerateNdkBackend(),
		langJava: i.shouldGenerateJavaBackend(),
		langRust: i.shouldGenerateRustBackend()}

	// The ndk_platform backend is generated only when explicitly requested. This will
	// eventually be completely removed the devices in the long tail are gone.
	if mctx.DeviceConfig().GenerateAidlNdkPlatformBackend() {
		shouldGenerateLangBackendMap[langNdkPlatform] = i.shouldGenerateNdkBackend()
	}

	for lang, shouldGenerate := range shouldGenerateLangBackendMap {
		if !shouldGenerate {
			continue
		}
		libs = append(libs, addLibrary(mctx, i, nextVersion, lang, requireFrozenVersion))
		for _, version := range versions {
			libs = append(libs, addLibrary(mctx, i, version, lang, false))
		}
	}

	if unstable {
		apiDirRoot := filepath.Join(aidlApiDir, i.ModuleBase.Name())
		aidlDumps, _ := mctx.GlobWithDeps(filepath.Join(mctx.ModuleDir(), apiDirRoot, "**/*.aidl"), nil)
		if len(aidlDumps) != 0 {
			mctx.PropertyErrorf("unstable", "The interface is configured as unstable, "+
				"but API dumps exist under %q. Unstable interface cannot have dumps.", apiDirRoot)
		}
	} else {
		addApiModule(mctx, i)
	}

	if proptools.Bool(i.properties.VndkProperties.Vndk.Enabled) {
		if "vintf" != proptools.String(i.properties.Stability) {
			mctx.PropertyErrorf("stability", "must be \"vintf\" if the module is for VNDK.")
		}
	}

	// Reserve this module name for future use
	mctx.CreateModule(phony.PhonyFactory, &phonyProperties{
		Name: proptools.StringPtr(i.ModuleBase.Name()),
	})

	i.internalModuleNames = libs
}

func (i *aidlInterface) commonBackendProperties(lang string) CommonBackendProperties {
	switch lang {
	case langCpp:
		return i.properties.Backend.Cpp.CommonBackendProperties
	case langJava:
		return i.properties.Backend.Java.CommonBackendProperties
	case langNdk, langNdkPlatform:
		return i.properties.Backend.Ndk.CommonBackendProperties
	case langRust:
		return i.properties.Backend.Rust.CommonBackendProperties
	default:
		panic(fmt.Errorf("unsupported language backend %q\n", lang))
	}
}

func (i *aidlInterface) Name() string {
	return i.ModuleBase.Name() + aidlInterfaceSuffix
}

func (i *aidlInterface) GenerateAndroidBuildActions(ctx android.ModuleContext) {
	srcs, _ := getPaths(ctx, i.properties.Srcs, i.properties.Local_include_dir)
	for _, src := range srcs {
		computedType := strings.TrimSuffix(strings.ReplaceAll(src.Rel(), "/", "."), ".aidl")
		i.computedTypes = append(i.computedTypes, computedType)
	}

	i.preprocessed = make(map[string]android.WritablePath)
	// generate (len(versions) + 1) preprocessed.aidl files
	for _, version := range concat(i.properties.Versions, []string{i.nextVersion()}) {
		i.preprocessed[version] = i.buildPreprocessed(ctx, version)
	}
	// helpful aliases
	if !proptools.Bool(i.properties.Unstable) {
		if i.hasVersion() {
			i.preprocessed["latest"] = i.preprocessed[i.latestVersion()]
		} else {
			// when we have no frozen versions yet, use "next version" as latest
			i.preprocessed["latest"] = i.preprocessed[i.nextVersion()]
		}
		i.preprocessed[""] = i.preprocessed[i.nextVersion()]
	}
}

// imported interfaces
// TODO(b/146436251) use imports in versions_with_info
// For example, foo-V1 should use bar-V1 while foo-V2 should use bar-V2
//   name: "foo",
//   versions_with_info: [
//     { version: "1", imports: ["bar-V1"]},
//     { version: "2", imports: ["bar-V2"]},
//   ]
func (i *aidlInterface) getImports(version string) map[string]string {
	imports := make(map[string]string)
	useLatestStable := !proptools.Bool(i.properties.Unstable) && version != "" && version != i.nextVersion()
	for _, importString := range i.properties.Imports {
		name, targetVersion := parseModuleWithVersion(importString)
		if targetVersion == "" && useLatestStable {
			targetVersion = "latest"
		}
		imports[name] = targetVersion
	}
	return imports
}

// generate preprocessed.aidl which contains only types with evaluated constants.
// "imports" will use preprocessed.aidl with -p flag to avoid parsing the entire transitive list
// of dependencies.
func (i *aidlInterface) buildPreprocessed(ctx android.ModuleContext, version string) android.WritablePath {
	deps := getDeps(ctx, i.getImports(version))

	preprocessed := android.PathForModuleOut(ctx, version, "preprocessed.aidl")
	rb := android.NewRuleBuilder(pctx, ctx)
	srcs, root_dir := i.srcsForVersion(ctx, version)

	if len(srcs) == 0 {
		ctx.PropertyErrorf("srcs", "No sources for a previous version in %v. Was a version manually added to .bp file? This is added automatically by <module>-freeze-api.", root_dir)
	}

	paths, imports := getPaths(ctx, srcs, root_dir)

	preprocessCommand := rb.Command().BuiltTool("aidl").
		FlagWithOutput("--preprocess ", preprocessed).
		Flag("--structured")
	if i.properties.Stability != nil {
		preprocessCommand.FlagWithArg("--stability ", *i.properties.Stability)
	}
	preprocessCommand.FlagForEachInput("-p", deps.preprocessed)
	preprocessCommand.FlagForEachArg("-I", concat(imports, i.properties.Include_dirs))
	preprocessCommand.Inputs(paths)
	name := i.BaseModuleName()
	if version != "" {
		name += "/" + version
	}
	rb.Build("export_"+name, "export types for "+name)
	return preprocessed
}

func (i *aidlInterface) DepsMutator(ctx android.BottomUpMutatorContext) {
	ctx.AddReverseDependency(ctx.Module(), nil, aidlMetadataSingletonName)
}

func aidlInterfaceFactory() android.Module {
	i := &aidlInterface{}
	i.AddProperties(&i.properties)
	android.InitAndroidModule(i)
	android.AddLoadHook(i, func(ctx android.LoadHookContext) { aidlInterfaceHook(ctx, i) })
	return i
}
