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

import (
	"android/soong/android"
	"android/soong/etc"
	"fmt"
	"path"
	"strings"

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

// ---------------------------------------------------------------------------------------------
// Naming scheme of the submodules generated by java_sdk_library and java_sdk_library_import
// ---------------------------------------------------------------------------------------------

const (
	sdkXmlFileSuffix = ".xml"
	implLibSuffix    = ".impl"
)

// Module name of the runtime implementation library
func (c *commonToSdkLibraryAndImport) implLibraryModuleName() string {
	return c.module.RootLibraryName() + implLibSuffix
}

// Module name of the XML file for the lib
func (c *commonToSdkLibraryAndImport) xmlPermissionsModuleName() string {
	return c.module.RootLibraryName() + sdkXmlFileSuffix
}

// Name of the java_library module that compiles the stubs source.
func (c *commonToSdkLibraryAndImport) stubsLibraryModuleName(apiScope *apiScope) string {
	baseName := c.module.RootLibraryName()
	return apiScope.stubsLibraryModuleName(baseName)
}

// Name of the java_library module that compiles the exportable stubs source.
func (c *commonToSdkLibraryAndImport) exportableStubsLibraryModuleName(apiScope *apiScope) string {
	baseName := c.module.RootLibraryName()
	return apiScope.exportableStubsLibraryModuleName(baseName)
}

// Name of the droidstubs module that generates the stubs source and may also
// generate/check the API.
func (c *commonToSdkLibraryAndImport) droidstubsModuleName(apiScope *apiScope) string {
	baseName := c.module.RootLibraryName()
	return apiScope.stubsSourceModuleName(baseName)
}

// Name of the java_api_library module that generates the from-text stubs source
// and compiles to a jar file.
func (c *commonToSdkLibraryAndImport) fromTextStubsLibraryModuleName(apiScope *apiScope) string {
	baseName := c.module.RootLibraryName()
	return apiScope.apiLibraryModuleName(baseName)
}

// Name of the java_library module that compiles the stubs
// generated from source Java files.
func (c *commonToSdkLibraryAndImport) fromSourceStubsLibraryModuleName(apiScope *apiScope) string {
	baseName := c.module.RootLibraryName()
	return apiScope.sourceStubsLibraryModuleName(baseName)
}

// Name of the java_library module that compiles the exportable stubs
// generated from source Java files.
func (c *commonToSdkLibraryAndImport) exportableFromSourceStubsLibraryModuleName(apiScope *apiScope) string {
	baseName := c.module.RootLibraryName()
	return apiScope.exportableSourceStubsLibraryModuleName(baseName)
}

// ---------------------------------------------------------------------------------------------
// Build rules of the submodules generated by java_sdk_library.
// java_sdk_library "framework-foo" generates the following submodules:
//
// - "framework-foo.impl" (type: [Library]): the implementation library, which generates the
//		compilation outputs that include the implementation details and the private apis
//		(i.e. class/methods that are annotated @hide).
//
// - "framework-foo.stubs.source.<[apiScope.name]>" (type: [Droidstubs]): droidstubs module that
//		generates the stubs and the api files for the given api scope.
//
// - "framework-foo.stubs.<[apiScope.name]>" (type: [Library]): stub library module that
//		provides the compilation output of the stubs to the reverse dependencies. The module
//		itself does not perform any compilation actions; the module statically depends on one of
//		the from-source stub module or the from-text stub configuration based on the build
// 		configuration.
//
// - "framework-foo.stubs.<[apiScope.name]>.from-source" (type: [Library]): stub library module
//		that compiles the stubs generated by the droidstubs submodule. This module is a static
//		dependency of the stub library module when
//		[android/soong/android/config.BuildFromTextStub()] is false.
//
// - "framework-foo.stubs.<[apiScope.name]>.from-text" (type: [ApiLibrary]): api library module
//		that generates and compiles the stubs from the api files checked in the tree instead of
//		the source Java files (e.g. *-current.txt files). This module is a static dependency of
//		the stub library module when [android/soong/android/config.BuildFromTextStub()] is true.
//
// - "framework-foo.stubs.exportable.<[apiScope.name]>" (type: [Library]): stub library module
//		that provides the "exportable" stubs. "exportable" stubs are the stubs that do not
//		include in-development flagged apis. This module is only used for SDK builds to generate
//		the SDK artifacts, and not purposed for consumption for other modules.
//
// - "framework-foo.stubs.exportable.<[apiScope.name]>.from-source" (type: [Library]): stub
//		library module that compiles the "exportable" stubs generated by the droidstubs
//		submodule. This module is always a static dependency of the "exportable" stub library
//		module given that from-text stubs cannot be used for SDK builds as it does not contain
//		documentations.
//
// - "framework-foo.xml" (type: [sdkLibraryXml]): xml library that generates the permission xml
//		file, which allows [SdkLibrary] to be used with <uses-permission> tag in the
//		AndroidManifest.xml files.
// ---------------------------------------------------------------------------------------------

// Creates the implementation [Library] with ".impl" suffix.
func (module *SdkLibrary) createImplLibrary(mctx android.DefaultableHookContext) {
	visibility := childModuleVisibility(module.sdkLibraryProperties.Impl_library_visibility)

	staticLibs := module.properties.Static_libs.Clone()
	staticLibs.AppendSimpleValue(module.sdkLibraryProperties.Impl_only_static_libs)
	props := struct {
		Name           *string
		Enabled        proptools.Configurable[bool]
		Visibility     []string
		Libs           []string
		Static_libs    proptools.Configurable[[]string]
		Apex_available []string
		Stem           *string
	}{
		Name:       proptools.StringPtr(module.implLibraryModuleName()),
		Enabled:    module.EnabledProperty(),
		Visibility: visibility,

		Libs: append(module.properties.Libs, module.sdkLibraryProperties.Impl_only_libs...),

		Static_libs: staticLibs,
		// Pass the apex_available settings down so that the impl library can be statically
		// embedded within a library that is added to an APEX. Needed for updatable-media.
		Apex_available: module.ApexAvailable(),

		Stem: proptools.StringPtr(module.Name()),
	}

	properties := []interface{}{
		&module.properties,
		&module.protoProperties,
		&module.deviceProperties,
		&module.dexProperties,
		&module.dexpreoptProperties,
		&module.linter.properties,
		&module.overridableProperties,
		&props,
		module.sdkComponentPropertiesForChildLibrary(),
	}
	mctx.CreateModule(LibraryFactory, properties...)
}

// Creates the [Droidstubs] module with ".stubs.source.<[apiScope.name]>" that creates stubs
// source files from the given full source files and also updates and checks the API
// specification files (i.e. "*-current.txt", "*-removed.txt" files).
func (module *SdkLibrary) createDroidstubs(mctx android.DefaultableHookContext, apiScope *apiScope, name string, scopeSpecificDroidstubsArgs []string) {
	props := struct {
		Name                             *string
		Enabled                          proptools.Configurable[bool]
		Visibility                       []string
		Srcs                             []string
		Installable                      *bool
		Sdk_version                      *string
		Api_surface                      *string
		System_modules                   *string
		Libs                             proptools.Configurable[[]string]
		Output_javadoc_comments          *bool
		Arg_files                        []string
		Args                             *string
		Java_version                     *string
		Annotations_enabled              *bool
		Merge_annotations_dirs           []string
		Merge_inclusion_annotations_dirs []string
		Generate_stubs                   *bool
		Previous_api                     *string
		Aconfig_declarations             []string
		Check_api                        struct {
			Current       ApiToCheck
			Last_released ApiToCheck

			Api_lint struct {
				Enabled       *bool
				New_since     *string
				Baseline_file *string
			}
		}
		Aidl struct {
			Include_dirs       []string
			Local_include_dirs []string
		}
		Dists []android.Dist
	}{}

	// The stubs source processing uses the same compile time classpath when extracting the
	// API from the implementation library as it does when compiling it. i.e. the same
	// * sdk version
	// * system_modules
	// * libs (static_libs/libs)

	props.Name = proptools.StringPtr(name)
	props.Enabled = module.EnabledProperty()
	props.Visibility = childModuleVisibility(module.sdkLibraryProperties.Stubs_source_visibility)
	props.Srcs = append(props.Srcs, module.properties.Srcs...)
	props.Srcs = append(props.Srcs, module.sdkLibraryProperties.Api_srcs...)
	props.Sdk_version = module.deviceProperties.Sdk_version
	props.Api_surface = &apiScope.name
	props.System_modules = module.deviceProperties.System_modules
	props.Installable = proptools.BoolPtr(false)
	// A droiddoc module has only one Libs property and doesn't distinguish between
	// shared libs and static libs. So we need to add both of these libs to Libs property.
	props.Libs = proptools.NewConfigurable[[]string](nil, nil)
	props.Libs.AppendSimpleValue(module.properties.Libs)
	props.Libs.Append(module.properties.Static_libs)
	props.Libs.AppendSimpleValue(module.sdkLibraryProperties.Stub_only_libs)
	props.Libs.AppendSimpleValue(module.scopeToProperties[apiScope].Libs)
	props.Aidl.Include_dirs = module.deviceProperties.Aidl.Include_dirs
	props.Aidl.Local_include_dirs = module.deviceProperties.Aidl.Local_include_dirs
	props.Java_version = module.properties.Java_version

	props.Annotations_enabled = module.sdkLibraryProperties.Annotations_enabled
	props.Merge_annotations_dirs = module.sdkLibraryProperties.Merge_annotations_dirs
	props.Merge_inclusion_annotations_dirs = module.sdkLibraryProperties.Merge_inclusion_annotations_dirs
	props.Aconfig_declarations = module.sdkLibraryProperties.Aconfig_declarations

	droidstubsArgs := []string{}
	if len(module.sdkLibraryProperties.Api_packages) != 0 {
		droidstubsArgs = append(droidstubsArgs, "--stub-packages "+strings.Join(module.sdkLibraryProperties.Api_packages, ":"))
	}
	droidstubsArgs = append(droidstubsArgs, module.sdkLibraryProperties.Droiddoc_options...)
	disabledWarnings := []string{"HiddenSuperclass"}
	if proptools.BoolDefault(module.sdkLibraryProperties.Api_lint.Legacy_errors_allowed, true) {
		disabledWarnings = append(disabledWarnings,
			"BroadcastBehavior",
			"DeprecationMismatch",
			"MissingPermission",
			"SdkConstant",
			"Todo",
		)
	}
	droidstubsArgs = append(droidstubsArgs, android.JoinWithPrefix(disabledWarnings, "--hide "))

	// Output Javadoc comments for public scope.
	if apiScope == apiScopePublic {
		props.Output_javadoc_comments = proptools.BoolPtr(true)
	}

	// Add in scope specific arguments.
	droidstubsArgs = append(droidstubsArgs, scopeSpecificDroidstubsArgs...)
	props.Arg_files = module.sdkLibraryProperties.Droiddoc_option_files
	props.Args = proptools.StringPtr(strings.Join(droidstubsArgs, " "))

	// List of APIs identified from the provided source files are created. They are later
	// compared against to the not-yet-released (a.k.a current) list of APIs and to the
	// last-released (a.k.a numbered) list of API.
	currentApiFileName := apiScope.apiFilePrefix + "current.txt"
	removedApiFileName := apiScope.apiFilePrefix + "removed.txt"
	apiDir := module.getApiDir()
	currentApiFileName = path.Join(apiDir, currentApiFileName)
	removedApiFileName = path.Join(apiDir, removedApiFileName)

	// check against the not-yet-release API
	props.Check_api.Current.Api_file = proptools.StringPtr(currentApiFileName)
	props.Check_api.Current.Removed_api_file = proptools.StringPtr(removedApiFileName)

	if module.compareAgainstLatestApi(apiScope) {
		// check against the latest released API
		latestApiFilegroupName := proptools.StringPtr(module.latestApiFilegroupName(apiScope))
		props.Previous_api = latestApiFilegroupName
		props.Check_api.Last_released.Api_file = latestApiFilegroupName
		props.Check_api.Last_released.Removed_api_file = proptools.StringPtr(
			module.latestRemovedApiFilegroupName(apiScope))
		props.Check_api.Last_released.Baseline_file = proptools.StringPtr(
			module.latestIncompatibilitiesFilegroupName(apiScope))

		if proptools.Bool(module.sdkLibraryProperties.Api_lint.Enabled) {
			// Enable api lint.
			props.Check_api.Api_lint.Enabled = proptools.BoolPtr(true)
			props.Check_api.Api_lint.New_since = latestApiFilegroupName

			// If it exists then pass a lint-baseline.txt through to droidstubs.
			baselinePath := path.Join(apiDir, apiScope.apiFilePrefix+"lint-baseline.txt")
			baselinePathRelativeToRoot := path.Join(mctx.ModuleDir(), baselinePath)
			paths, err := mctx.GlobWithDeps(baselinePathRelativeToRoot, nil)
			if err != nil {
				mctx.ModuleErrorf("error checking for presence of %s: %s", baselinePathRelativeToRoot, err)
			}
			if len(paths) == 1 {
				props.Check_api.Api_lint.Baseline_file = proptools.StringPtr(baselinePath)
			} else if len(paths) != 0 {
				mctx.ModuleErrorf("error checking for presence of %s: expected one path, found: %v", baselinePathRelativeToRoot, paths)
			}
		}
	}

	if !Bool(module.sdkLibraryProperties.No_dist) {
		// Dist the api txt and removed api txt artifacts for sdk builds.
		distDir := proptools.StringPtr(path.Join(module.apiDistPath(apiScope), "api"))
		stubsTypeTagPrefix := ""
		if mctx.Config().ReleaseHiddenApiExportableStubs() {
			stubsTypeTagPrefix = ".exportable"
		}
		for _, p := range []struct {
			tag     string
			pattern string
		}{
			// "exportable" api files are copied to the dist directory instead of the
			// "everything" api files when "RELEASE_HIDDEN_API_EXPORTABLE_STUBS" build flag
			// is set. Otherwise, the "everything" api files are copied to the dist directory.
			{tag: "%s.api.txt", pattern: "%s.txt"},
			{tag: "%s.removed-api.txt", pattern: "%s-removed.txt"},
		} {
			props.Dists = append(props.Dists, android.Dist{
				Targets: []string{"sdk", "win_sdk"},
				Dir:     distDir,
				Dest:    proptools.StringPtr(fmt.Sprintf(p.pattern, module.distStem())),
				Tag:     proptools.StringPtr(fmt.Sprintf(p.tag, stubsTypeTagPrefix)),
			})
		}
	}

	mctx.CreateModule(DroidstubsFactory, &props, module.sdkComponentPropertiesForChildLibrary()).(*Droidstubs).CallHookIfAvailable(mctx)
}

type libraryProperties struct {
	Name           *string
	Enabled        proptools.Configurable[bool]
	Visibility     []string
	Srcs           []string
	Installable    *bool
	Sdk_version    *string
	System_modules *string
	Patch_module   *string
	Libs           []string
	Static_libs    []string
	Compile_dex    *bool
	Java_version   *string
	Openjdk9       struct {
		Srcs       []string
		Javacflags []string
	}
	Dist struct {
		Targets []string
		Dest    *string
		Dir     *string
		Tag     *string
	}
	Is_stubs_module       *bool
	Stub_contributing_api *string
}

func (module *SdkLibrary) stubsLibraryProps(mctx android.DefaultableHookContext, apiScope *apiScope) libraryProperties {
	props := libraryProperties{}
	props.Enabled = module.EnabledProperty()
	props.Visibility = []string{"//visibility:override", "//visibility:private"}
	// sources are generated from the droiddoc
	sdkVersion := module.sdkVersionForStubsLibrary(mctx, apiScope)
	props.Sdk_version = proptools.StringPtr(sdkVersion)
	props.System_modules = module.deviceProperties.System_modules
	props.Patch_module = module.properties.Patch_module
	props.Installable = proptools.BoolPtr(false)
	props.Libs = module.sdkLibraryProperties.Stub_only_libs
	props.Libs = append(props.Libs, module.scopeToProperties[apiScope].Libs...)
	props.Static_libs = module.sdkLibraryProperties.Stub_only_static_libs
	// The stub-annotations library contains special versions of the annotations
	// with CLASS retention policy, so that they're kept.
	if proptools.Bool(module.sdkLibraryProperties.Annotations_enabled) {
		props.Libs = append(props.Libs, "stub-annotations")
	}
	props.Openjdk9.Srcs = module.properties.Openjdk9.Srcs
	props.Openjdk9.Javacflags = module.properties.Openjdk9.Javacflags
	// We compile the stubs for 1.8 in line with the main android.jar stubs, and potential
	// interop with older developer tools that don't support 1.9.
	props.Java_version = proptools.StringPtr("1.8")
	props.Is_stubs_module = proptools.BoolPtr(true)
	props.Stub_contributing_api = proptools.StringPtr(apiScope.kind.String())

	return props
}

// Creates the from-source stub [Library] with ".stubs.<[apiScope.name]>.from-source" suffix.
func (module *SdkLibrary) createFromSourceStubsLibrary(mctx android.DefaultableHookContext, apiScope *apiScope) {

	props := module.stubsLibraryProps(mctx, apiScope)
	props.Name = proptools.StringPtr(module.fromSourceStubsLibraryModuleName(apiScope))
	props.Srcs = []string{":" + module.droidstubsModuleName(apiScope)}

	mctx.CreateModule(LibraryFactory, &props, module.sdkComponentPropertiesForChildLibrary())
}

// Creates the "exportable" from-source stub [Library] with
// ".stubs.exportable.<[apiScope.name]>" suffix.
func (module *SdkLibrary) createExportableFromSourceStubsLibrary(mctx android.DefaultableHookContext, apiScope *apiScope) {
	props := module.stubsLibraryProps(mctx, apiScope)
	props.Name = proptools.StringPtr(module.exportableFromSourceStubsLibraryModuleName(apiScope))
	props.Srcs = []string{":" + module.droidstubsModuleName(apiScope) + "{.exportable}"}

	mctx.CreateModule(LibraryFactory, &props, module.sdkComponentPropertiesForChildLibrary())
}

// Creates the from-text stub [ApiLibrary] with ".stubs.<[apiScope.name]>.from-text" suffix.
func (module *SdkLibrary) createApiLibrary(mctx android.DefaultableHookContext, apiScope *apiScope) {
	props := struct {
		Name              *string
		Enabled           proptools.Configurable[bool]
		Visibility        []string
		Api_contributions []string
		Libs              proptools.Configurable[[]string]
		Static_libs       []string
		System_modules    *string
		Enable_validation *bool
		Stubs_type        *string
		Sdk_version       *string
		Previous_api      *string
	}{}

	props.Name = proptools.StringPtr(module.fromTextStubsLibraryModuleName(apiScope))
	props.Enabled = module.EnabledProperty()
	props.Visibility = []string{"//visibility:override", "//visibility:private"}

	apiContributions := []string{}

	// Api surfaces are not independent of each other, but have subset relationships,
	// and so does the api files. To generate from-text stubs for api surfaces other than public,
	// all subset api domains' api_contriubtions must be added as well.
	scope := apiScope
	for scope != nil {
		apiContributions = append(apiContributions, module.droidstubsModuleName(scope)+".api.contribution")
		scope = scope.extends
	}
	if apiScope == apiScopePublic {
		additionalApiContribution := module.apiLibraryAdditionalApiContribution()
		if additionalApiContribution != "" {
			apiContributions = append(apiContributions, additionalApiContribution)
		}
	}

	props.Api_contributions = apiContributions

	// Ensure that stub-annotations is added to the classpath before any other libs
	props.Libs = proptools.NewConfigurable[[]string](nil, nil)
	props.Libs.AppendSimpleValue([]string{"stub-annotations"})
	props.Libs.AppendSimpleValue(module.properties.Libs)
	props.Libs.Append(module.properties.Static_libs)
	props.Libs.AppendSimpleValue(module.sdkLibraryProperties.Stub_only_libs)
	props.Libs.AppendSimpleValue(module.scopeToProperties[apiScope].Libs)
	props.Static_libs = module.sdkLibraryProperties.Stub_only_static_libs

	props.System_modules = module.deviceProperties.System_modules
	props.Enable_validation = proptools.BoolPtr(true)
	props.Stubs_type = proptools.StringPtr("everything")

	if module.deviceProperties.Sdk_version != nil {
		props.Sdk_version = module.deviceProperties.Sdk_version
	}

	if module.compareAgainstLatestApi(apiScope) {
		// check against the latest released API
		latestApiFilegroupName := proptools.StringPtr(module.latestApiFilegroupName(apiScope))
		props.Previous_api = latestApiFilegroupName
	}

	mctx.CreateModule(ApiLibraryFactory, &props, module.sdkComponentPropertiesForChildLibrary())
}

func (module *SdkLibrary) topLevelStubsLibraryProps(mctx android.DefaultableHookContext, apiScope *apiScope, doDist bool) libraryProperties {
	props := libraryProperties{}

	props.Enabled = module.EnabledProperty()
	props.Visibility = childModuleVisibility(module.sdkLibraryProperties.Stubs_library_visibility)
	sdkVersion := module.sdkVersionForStubsLibrary(mctx, apiScope)
	props.Sdk_version = proptools.StringPtr(sdkVersion)

	props.System_modules = module.deviceProperties.System_modules

	// The imports need to be compiled to dex if the java_sdk_library requests it.
	compileDex := module.dexProperties.Compile_dex
	if module.stubLibrariesCompiledForDex() {
		compileDex = proptools.BoolPtr(true)
	}
	props.Compile_dex = compileDex

	props.Stub_contributing_api = proptools.StringPtr(apiScope.kind.String())

	if !Bool(module.sdkLibraryProperties.No_dist) && doDist {
		props.Dist.Targets = []string{"sdk", "win_sdk"}
		props.Dist.Dest = proptools.StringPtr(fmt.Sprintf("%v.jar", module.distStem()))
		props.Dist.Dir = proptools.StringPtr(module.apiDistPath(apiScope))
		props.Dist.Tag = proptools.StringPtr(".jar")
	}
	props.Is_stubs_module = proptools.BoolPtr(true)

	return props
}

// Creates the stub [Library] with ".stubs.<[apiScope.name]>" suffix.
func (module *SdkLibrary) createTopLevelStubsLibrary(
	mctx android.DefaultableHookContext, apiScope *apiScope) {

	// Dist the "everything" stubs when the RELEASE_HIDDEN_API_EXPORTABLE_STUBS build flag is false
	doDist := !mctx.Config().ReleaseHiddenApiExportableStubs()
	props := module.topLevelStubsLibraryProps(mctx, apiScope, doDist)
	props.Name = proptools.StringPtr(module.stubsLibraryModuleName(apiScope))

	// Add the stub compiling java_library/java_api_library as static lib based on build config
	staticLib := module.fromSourceStubsLibraryModuleName(apiScope)
	if mctx.Config().BuildFromTextStub() && module.ModuleBuildFromTextStubs() {
		staticLib = module.fromTextStubsLibraryModuleName(apiScope)
	}
	props.Static_libs = append(props.Static_libs, staticLib)

	mctx.CreateModule(LibraryFactory, &props, module.sdkComponentPropertiesForChildLibrary())
}

// Creates the "exportable" stub [Library] with ".stubs.exportable.<[apiScope.name]>" suffix.
func (module *SdkLibrary) createTopLevelExportableStubsLibrary(
	mctx android.DefaultableHookContext, apiScope *apiScope) {

	// Dist the "exportable" stubs when the RELEASE_HIDDEN_API_EXPORTABLE_STUBS build flag is true
	doDist := mctx.Config().ReleaseHiddenApiExportableStubs()
	props := module.topLevelStubsLibraryProps(mctx, apiScope, doDist)
	props.Name = proptools.StringPtr(module.exportableStubsLibraryModuleName(apiScope))

	staticLib := module.exportableFromSourceStubsLibraryModuleName(apiScope)
	props.Static_libs = append(props.Static_libs, staticLib)

	mctx.CreateModule(LibraryFactory, &props, module.sdkComponentPropertiesForChildLibrary())
}

// Creates the [sdkLibraryXml] with ".xml" suffix.
func (module *SdkLibrary) createXmlFile(mctx android.DefaultableHookContext) {
	moduleMinApiLevel := module.Library.MinSdkVersion(mctx)
	var moduleMinApiLevelStr = moduleMinApiLevel.String()
	if moduleMinApiLevel == android.NoneApiLevel {
		moduleMinApiLevelStr = "current"
	}
	props := struct {
		Name                      *string
		Enabled                   proptools.Configurable[bool]
		Lib_name                  *string
		Apex_available            []string
		On_bootclasspath_since    *string
		On_bootclasspath_before   *string
		Min_device_sdk            *string
		Max_device_sdk            *string
		Sdk_library_min_api_level *string
		Uses_libs_dependencies    []string
	}{
		Name:                      proptools.StringPtr(module.xmlPermissionsModuleName()),
		Enabled:                   module.EnabledProperty(),
		Lib_name:                  proptools.StringPtr(module.BaseModuleName()),
		Apex_available:            module.ApexProperties.Apex_available,
		On_bootclasspath_since:    module.commonSdkLibraryProperties.On_bootclasspath_since,
		On_bootclasspath_before:   module.commonSdkLibraryProperties.On_bootclasspath_before,
		Min_device_sdk:            module.commonSdkLibraryProperties.Min_device_sdk,
		Max_device_sdk:            module.commonSdkLibraryProperties.Max_device_sdk,
		Sdk_library_min_api_level: &moduleMinApiLevelStr,
		Uses_libs_dependencies:    module.usesLibraryProperties.Uses_libs,
	}

	mctx.CreateModule(sdkLibraryXmlFactory, &props)
}

// ---------------------------------------------------------------------------------------------
// Build rules of the submodules generated by java_sdk_library_import.
// Note that the java_sdk_library_import module does not generate the implementation library.
// Instead, it will create a dependency to the source implemenetation library if one exists.
// java_sdk_library_import "framework-foo" generates the following submodules:
//
// - "framework-foo.stubs.<[apiScope.name]>" (type: [Import]): prebuilt stub library module that
//		provides the stub jar file checked in the tree.
//
// - "framework-foo.stubs.source.<[apiScope.name]>" (type: [PrebuiltStubsSources]): prebuilt
//		droidstubs module that provides the stub source jar file checked in the tree.
//
// - "framework-foo.stubs.source.<[apiScope.name]>.api.contribution"
//		(type [JavaApiContributionImport]): prebuilt java_api_contribution module that provides
//		the prebuilt api file for previously released from-text stub generation.
// ---------------------------------------------------------------------------------------------

// Creates the prebuilt stub [Import] with ".stubs.<[apiScope.name]>" suffix.
func (module *SdkLibraryImport) createJavaImportForStubs(mctx android.DefaultableHookContext, apiScope *apiScope, scopeProperties *sdkLibraryScopeProperties) {
	// Creates a java import for the jar with ".stubs" suffix
	props := struct {
		Name                             *string
		Source_module_name               *string
		Created_by_java_sdk_library_name *string
		Sdk_version                      *string
		Libs                             []string
		Jars                             []string
		Compile_dex                      *bool
		Is_stubs_module                  *bool

		android.UserSuppliedPrebuiltProperties
	}{}
	props.Name = proptools.StringPtr(module.stubsLibraryModuleName(apiScope))
	props.Source_module_name = proptools.StringPtr(apiScope.stubsLibraryModuleName(module.BaseModuleName()))
	props.Created_by_java_sdk_library_name = proptools.StringPtr(module.RootLibraryName())
	props.Sdk_version = scopeProperties.Sdk_version
	// Prepend any of the libs from the legacy public properties to the libs for each of the
	// scopes to avoid having to duplicate them in each scope.
	props.Libs = append(module.properties.Libs, scopeProperties.Libs...)
	props.Jars = scopeProperties.Jars

	// The imports are preferred if the java_sdk_library_import is preferred.
	props.CopyUserSuppliedPropertiesFromPrebuilt(&module.prebuilt)

	// The imports need to be compiled to dex if the java_sdk_library_import requests it.
	compileDex := module.properties.Compile_dex
	if module.stubLibrariesCompiledForDex() {
		compileDex = proptools.BoolPtr(true)
	}
	props.Compile_dex = compileDex
	props.Is_stubs_module = proptools.BoolPtr(true)

	mctx.CreateModule(ImportFactory, &props, module.sdkComponentPropertiesForChildLibrary())
}

func (module *SdkLibraryImport) createPrebuiltStubsSources(mctx android.DefaultableHookContext, apiScope *apiScope, scopeProperties *sdkLibraryScopeProperties) {
	props := struct {
		Name                             *string
		Source_module_name               *string
		Created_by_java_sdk_library_name *string
		Srcs                             []string

		android.UserSuppliedPrebuiltProperties
	}{}
	props.Name = proptools.StringPtr(module.droidstubsModuleName(apiScope))
	props.Source_module_name = proptools.StringPtr(apiScope.stubsSourceModuleName(module.BaseModuleName()))
	props.Created_by_java_sdk_library_name = proptools.StringPtr(module.RootLibraryName())
	props.Srcs = scopeProperties.Stub_srcs

	// The stubs source is preferred if the java_sdk_library_import is preferred.
	props.CopyUserSuppliedPropertiesFromPrebuilt(&module.prebuilt)

	mctx.CreateModule(PrebuiltStubsSourcesFactory, &props, module.sdkComponentPropertiesForChildLibrary())
}

// Creates the prebuilt api contribution [JavaApiContributionImport] with
// ".stubs.source.<[apiScope.name]>.api.contribution" suffix.
func (module *SdkLibraryImport) createPrebuiltApiContribution(mctx android.DefaultableHookContext, apiScope *apiScope, scopeProperties *sdkLibraryScopeProperties) {
	api_file := scopeProperties.Current_api
	api_surface := &apiScope.name

	props := struct {
		Name                             *string
		Source_module_name               *string
		Created_by_java_sdk_library_name *string
		Api_surface                      *string
		Api_file                         *string
		Visibility                       []string
	}{}

	props.Name = proptools.StringPtr(module.droidstubsModuleName(apiScope) + ".api.contribution")
	props.Source_module_name = proptools.StringPtr(apiScope.stubsSourceModuleName(module.BaseModuleName()) + ".api.contribution")
	props.Created_by_java_sdk_library_name = proptools.StringPtr(module.RootLibraryName())
	props.Api_surface = api_surface
	props.Api_file = api_file
	props.Visibility = []string{"//visibility:override", "//visibility:public"}

	mctx.CreateModule(ApiContributionImportFactory, &props, module.sdkComponentPropertiesForChildLibrary())
}

// ---------------------------------------------------------------------------------------------
// End of the build rules of the submodules generated by java_sdk_library_import.
// ---------------------------------------------------------------------------------------------

// Definition of the [sdkLibraryXml] module. The module generates the permissions xml file,
// so that the apps can specify the java_sdk_library using <uses-permission> tag in the
// AndroidManifest.xml file.
type sdkLibraryXml struct {
	android.ModuleBase
	android.DefaultableModuleBase
	android.ApexModuleBase

	properties sdkLibraryXmlProperties

	outputFilePath android.OutputPath
	installDirPath android.InstallPath

	hideApexVariantFromMake bool
}

type sdkLibraryXmlProperties struct {
	// canonical name of the lib
	Lib_name *string

	// Signals that this shared library is part of the bootclasspath starting
	// on the version indicated in this attribute.
	//
	// This will make platforms at this level and above to ignore
	// <uses-library> tags with this library name because the library is already
	// available
	On_bootclasspath_since *string

	// Signals that this shared library was part of the bootclasspath before
	// (but not including) the version indicated in this attribute.
	//
	// The system will automatically add a <uses-library> tag with this library to
	// apps that target any SDK less than the version indicated in this attribute.
	On_bootclasspath_before *string

	// Indicates that PackageManager should ignore this shared library if the
	// platform is below the version indicated in this attribute.
	//
	// This means that the device won't recognise this library as installed.
	Min_device_sdk *string

	// Indicates that PackageManager should ignore this shared library if the
	// platform is above the version indicated in this attribute.
	//
	// This means that the device won't recognise this library as installed.
	Max_device_sdk *string

	// The SdkLibrary's min api level as a string
	//
	// This value comes from the ApiLevel of the MinSdkVersion property.
	Sdk_library_min_api_level *string

	// Uses-libs dependencies that the shared library requires to work correctly.
	//
	// This will add dependency="foo:bar" to the <library> section.
	Uses_libs_dependencies []string
}

// java_sdk_library_xml builds the permission xml file for a java_sdk_library.
// Not to be used directly by users. java_sdk_library internally uses this.
func sdkLibraryXmlFactory() android.Module {
	module := &sdkLibraryXml{}

	module.AddProperties(&module.properties)

	android.InitApexModule(module)
	android.InitAndroidArchModule(module, android.DeviceSupported, android.MultilibCommon)

	return module
}

func (module *sdkLibraryXml) UniqueApexVariations() bool {
	// sdkLibraryXml needs a unique variation per APEX because the generated XML file contains the path to the
	// mounted APEX, which contains the name of the APEX.
	return true
}

// from android.PrebuiltEtcModule
func (module *sdkLibraryXml) BaseDir() string {
	return "etc"
}

// from android.PrebuiltEtcModule
func (module *sdkLibraryXml) SubDir() string {
	return "permissions"
}

var _ etc.PrebuiltEtcModule = (*sdkLibraryXml)(nil)

// from android.ApexModule
func (module *sdkLibraryXml) AvailableFor(what string) bool {
	return true
}

func (module *sdkLibraryXml) DepsMutator(ctx android.BottomUpMutatorContext) {
	// do nothing
}

var _ android.ApexModule = (*sdkLibraryXml)(nil)

// Implements android.ApexModule
func (module *sdkLibraryXml) ShouldSupportSdkVersion(ctx android.BaseModuleContext,
	sdkVersion android.ApiLevel) error {
	// sdkLibraryXml doesn't need to be checked separately because java_sdk_library is checked
	return nil
}

// File path to the runtime implementation library
func (module *sdkLibraryXml) implPath(ctx android.ModuleContext) string {
	implName := proptools.String(module.properties.Lib_name)
	if apexInfo, _ := android.ModuleProvider(ctx, android.ApexInfoProvider); !apexInfo.IsForPlatform() {
		// TODO(b/146468504): ApexVariationName() is only a soong module name, not apex name.
		// In most cases, this works fine. But when apex_name is set or override_apex is used
		// this can be wrong.
		return fmt.Sprintf("/apex/%s/javalib/%s.jar", apexInfo.BaseApexName, implName)
	}
	partition := "system"
	if module.SocSpecific() {
		partition = "vendor"
	} else if module.DeviceSpecific() {
		partition = "odm"
	} else if module.ProductSpecific() {
		partition = "product"
	} else if module.SystemExtSpecific() {
		partition = "system_ext"
	}
	return "/" + partition + "/framework/" + implName + ".jar"
}

func formattedOptionalSdkLevelAttribute(ctx android.ModuleContext, attrName string, value *string) string {
	if value == nil {
		return ""
	}
	apiLevel, err := android.ApiLevelFromUser(ctx, *value)
	if err != nil {
		// attributes in bp files have underscores but in the xml have dashes.
		ctx.PropertyErrorf(strings.ReplaceAll(attrName, "-", "_"), err.Error())
		return ""
	}
	if apiLevel.IsCurrent() {
		// passing "current" would always mean a future release, never the current (or the current in
		// progress) which means some conditions would never be triggered.
		ctx.PropertyErrorf(strings.ReplaceAll(attrName, "-", "_"),
			`"current" is not an allowed value for this attribute`)
		return ""
	}
	// "safeValue" is safe because it translates finalized codenames to a string
	// with their SDK int.
	safeValue := apiLevel.String()
	return formattedOptionalAttribute(attrName, &safeValue)
}

// formats an attribute for the xml permissions file if the value is not null
// returns empty string otherwise
func formattedOptionalAttribute(attrName string, value *string) string {
	if value == nil {
		return ""
	}
	return fmt.Sprintf("        %s=\"%s\"\n", attrName, *value)
}

func formattedDependenciesAttribute(dependencies []string) string {
	if dependencies == nil {
		return ""
	}
	return fmt.Sprintf("        dependency=\"%s\"\n", strings.Join(dependencies, ":"))
}

func (module *sdkLibraryXml) permissionsContents(ctx android.ModuleContext) string {
	libName := proptools.String(module.properties.Lib_name)
	libNameAttr := formattedOptionalAttribute("name", &libName)
	filePath := module.implPath(ctx)
	filePathAttr := formattedOptionalAttribute("file", &filePath)
	implicitFromAttr := formattedOptionalSdkLevelAttribute(ctx, "on-bootclasspath-since", module.properties.On_bootclasspath_since)
	implicitUntilAttr := formattedOptionalSdkLevelAttribute(ctx, "on-bootclasspath-before", module.properties.On_bootclasspath_before)
	minSdkAttr := formattedOptionalSdkLevelAttribute(ctx, "min-device-sdk", module.properties.Min_device_sdk)
	maxSdkAttr := formattedOptionalSdkLevelAttribute(ctx, "max-device-sdk", module.properties.Max_device_sdk)
	dependenciesAttr := formattedDependenciesAttribute(module.properties.Uses_libs_dependencies)
	// <library> is understood in all android versions whereas <apex-library> is only understood from API T (and ignored before that).
	// similarly, min_device_sdk is only understood from T. So if a library is using that, we need to use the apex-library to make sure this library is not loaded before T
	var libraryTag string
	if module.properties.Min_device_sdk != nil {
		libraryTag = "    <apex-library\n"
	} else {
		libraryTag = "    <library\n"
	}

	return strings.Join([]string{
		"<?xml version=\"1.0\" encoding=\"utf-8\"?>\n",
		"<!-- Copyright (C) 2018 The Android Open Source Project\n",
		"\n",
		"    Licensed under the Apache License, Version 2.0 (the \"License\");\n",
		"    you may not use this file except in compliance with the License.\n",
		"    You may obtain a copy of the License at\n",
		"\n",
		"        http://www.apache.org/licenses/LICENSE-2.0\n",
		"\n",
		"    Unless required by applicable law or agreed to in writing, software\n",
		"    distributed under the License is distributed on an \"AS IS\" BASIS,\n",
		"    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n",
		"    See the License for the specific language governing permissions and\n",
		"    limitations under the License.\n",
		"-->\n",
		"<permissions>\n",
		libraryTag,
		libNameAttr,
		filePathAttr,
		implicitFromAttr,
		implicitUntilAttr,
		minSdkAttr,
		maxSdkAttr,
		dependenciesAttr,
		"    />\n",
		"</permissions>\n",
	}, "")
}

func (module *sdkLibraryXml) GenerateAndroidBuildActions(ctx android.ModuleContext) {
	apexInfo, _ := android.ModuleProvider(ctx, android.ApexInfoProvider)
	module.hideApexVariantFromMake = !apexInfo.IsForPlatform()

	libName := proptools.String(module.properties.Lib_name)
	module.selfValidate(ctx)
	xmlContent := module.permissionsContents(ctx)

	module.outputFilePath = android.PathForModuleOut(ctx, libName+".xml").OutputPath
	android.WriteFileRuleVerbatim(ctx, module.outputFilePath, xmlContent)

	module.installDirPath = android.PathForModuleInstall(ctx, "etc", module.SubDir())
	ctx.PackageFile(module.installDirPath, libName+".xml", module.outputFilePath)

	ctx.SetOutputFiles(android.OutputPaths{module.outputFilePath}.Paths(), "")
}

func (module *sdkLibraryXml) AndroidMkEntries() []android.AndroidMkEntries {
	if module.hideApexVariantFromMake {
		return []android.AndroidMkEntries{{
			Disabled: true,
		}}
	}

	return []android.AndroidMkEntries{{
		Class:      "ETC",
		OutputFile: android.OptionalPathForPath(module.outputFilePath),
		ExtraEntries: []android.AndroidMkExtraEntriesFunc{
			func(ctx android.AndroidMkExtraEntriesContext, entries *android.AndroidMkEntries) {
				entries.SetString("LOCAL_MODULE_TAGS", "optional")
				entries.SetString("LOCAL_MODULE_PATH", module.installDirPath.String())
				entries.SetString("LOCAL_INSTALLED_MODULE_STEM", module.outputFilePath.Base())
			},
		},
	}}
}

func (module *sdkLibraryXml) selfValidate(ctx android.ModuleContext) {
	module.validateAtLeastTAttributes(ctx)
	module.validateMinAndMaxDeviceSdk(ctx)
	module.validateMinMaxDeviceSdkAndModuleMinSdk(ctx)
	module.validateOnBootclasspathBeforeRequirements(ctx)
}

func (module *sdkLibraryXml) validateAtLeastTAttributes(ctx android.ModuleContext) {
	t := android.ApiLevelOrPanic(ctx, "Tiramisu")
	module.attrAtLeastT(ctx, t, module.properties.Min_device_sdk, "min_device_sdk")
	module.attrAtLeastT(ctx, t, module.properties.Max_device_sdk, "max_device_sdk")
	module.attrAtLeastT(ctx, t, module.properties.On_bootclasspath_before, "on_bootclasspath_before")
	module.attrAtLeastT(ctx, t, module.properties.On_bootclasspath_since, "on_bootclasspath_since")
}

func (module *sdkLibraryXml) attrAtLeastT(ctx android.ModuleContext, t android.ApiLevel, attr *string, attrName string) {
	if attr != nil {
		if level, err := android.ApiLevelFromUser(ctx, *attr); err == nil {
			// we will inform the user of invalid inputs when we try to write the
			// permissions xml file so we don't need to do it here
			if t.GreaterThan(level) {
				ctx.PropertyErrorf(attrName, "Attribute value needs to be at least T")
			}
		}
	}
}

func (module *sdkLibraryXml) validateMinAndMaxDeviceSdk(ctx android.ModuleContext) {
	if module.properties.Min_device_sdk != nil && module.properties.Max_device_sdk != nil {
		min, minErr := android.ApiLevelFromUser(ctx, *module.properties.Min_device_sdk)
		max, maxErr := android.ApiLevelFromUser(ctx, *module.properties.Max_device_sdk)
		if minErr == nil && maxErr == nil {
			// we will inform the user of invalid inputs when we try to write the
			// permissions xml file so we don't need to do it here
			if min.GreaterThan(max) {
				ctx.ModuleErrorf("min_device_sdk can't be greater than max_device_sdk")
			}
		}
	}
}

func (module *sdkLibraryXml) validateMinMaxDeviceSdkAndModuleMinSdk(ctx android.ModuleContext) {
	moduleMinApi := android.ApiLevelOrPanic(ctx, *module.properties.Sdk_library_min_api_level)
	if module.properties.Min_device_sdk != nil {
		api, err := android.ApiLevelFromUser(ctx, *module.properties.Min_device_sdk)
		if err == nil {
			if moduleMinApi.GreaterThan(api) {
				ctx.PropertyErrorf("min_device_sdk", "Can't be less than module's min sdk (%s)", moduleMinApi)
			}
		}
	}
	if module.properties.Max_device_sdk != nil {
		api, err := android.ApiLevelFromUser(ctx, *module.properties.Max_device_sdk)
		if err == nil {
			if moduleMinApi.GreaterThan(api) {
				ctx.PropertyErrorf("max_device_sdk", "Can't be less than module's min sdk (%s)", moduleMinApi)
			}
		}
	}
}

func (module *sdkLibraryXml) validateOnBootclasspathBeforeRequirements(ctx android.ModuleContext) {
	moduleMinApi := android.ApiLevelOrPanic(ctx, *module.properties.Sdk_library_min_api_level)
	if module.properties.On_bootclasspath_before != nil {
		t := android.ApiLevelOrPanic(ctx, "Tiramisu")
		// if we use the attribute, then we need to do this validation
		if moduleMinApi.LessThan(t) {
			// if minAPi is < T, then we need to have min_device_sdk (which only accepts T+)
			if module.properties.Min_device_sdk == nil {
				ctx.PropertyErrorf("on_bootclasspath_before", "Using this property requires that the module's min_sdk_version or the shared library's min_device_sdk is at least T")
			}
		}
	}
}
