// Copyright (C) 2021 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 api

import (
	"fmt"
	"sort"
	"strings"

	"github.com/google/blueprint/proptools"

	"android/soong/android"
	"android/soong/genrule"
	"android/soong/java"
)

const art = "art.module.public.api"
const conscrypt = "conscrypt.module.public.api"
const i18n = "i18n.module.public.api"
const virtualization = "framework-virtualization"
const location = "framework-location"

var core_libraries_modules = []string{art, conscrypt, i18n}

// List of modules that are not yet updatable, and hence they can still compile
// against hidden APIs. These modules are filtered out when building the
// updatable-framework-module-impl (because updatable-framework-module-impl is
// built against module_current SDK). Instead they are directly statically
// linked into the all-framework-module-lib, which is building against hidden
// APIs.
// In addition, the modules in this list are allowed to contribute to test APIs
// stubs.
var non_updatable_modules = []string{virtualization, location}

// The intention behind this soong plugin is to generate a number of "merged"
// API-related modules that would otherwise require a large amount of very
// similar Android.bp boilerplate to define. For example, the merged current.txt
// API definitions (created by merging the non-updatable current.txt with all
// the module current.txts). This simplifies the addition of new android
// modules, by reducing the number of genrules etc a new module must be added to.

// The properties of the combined_apis module type.
type CombinedApisProperties struct {
	// Module libraries in the bootclasspath
	Bootclasspath []string
	// Module libraries on the bootclasspath if include_nonpublic_framework_api is true.
	Conditional_bootclasspath []string
	// Module libraries in system server
	System_server_classpath []string
}

type CombinedApis struct {
	android.ModuleBase
	android.DefaultableModuleBase

	properties CombinedApisProperties
}

func init() {
	registerBuildComponents(android.InitRegistrationContext)
}

func registerBuildComponents(ctx android.RegistrationContext) {
	ctx.RegisterModuleType("combined_apis", combinedApisModuleFactory)
	ctx.RegisterModuleType("combined_apis_defaults", CombinedApisModuleDefaultsFactory)
}

var PrepareForCombinedApisTest = android.FixtureRegisterWithContext(registerBuildComponents)

func (a *CombinedApis) apiFingerprintStubDeps() []string {
	ret := []string{}
	ret = append(
		ret,
		transformArray(a.properties.Bootclasspath, "", ".stubs")...,
	)
	ret = append(
		ret,
		transformArray(a.properties.Bootclasspath, "", ".stubs.system")...,
	)
	ret = append(
		ret,
		transformArray(a.properties.Bootclasspath, "", ".stubs.module_lib")...,
	)
	ret = append(
		ret,
		transformArray(a.properties.System_server_classpath, "", ".stubs.system_server")...,
	)
	return ret
}

func (a *CombinedApis) DepsMutator(ctx android.BottomUpMutatorContext) {
	ctx.AddDependency(ctx.Module(), nil, a.apiFingerprintStubDeps()...)
}

func (a *CombinedApis) GenerateAndroidBuildActions(ctx android.ModuleContext) {
	ctx.WalkDeps(func(child, parent android.Module) bool {
		if _, ok := child.(java.AndroidLibraryDependency); ok && child.Name() != "framework-res" {
			// Stubs of BCP and SSCP libraries should not have any dependencies on apps
			// This check ensures that we do not run into circular dependencies when UNBUNDLED_BUILD_TARGET_SDK_WITH_API_FINGERPRINT=true
			ctx.ModuleErrorf(
				"Module %s is not a valid dependency of the stub library %s\n."+
					"If this dependency has been added via `libs` of java_sdk_library, please move it to `impl_only_libs`\n",
				child.Name(), parent.Name())
			return false // error detected
		}
		return true
	})

}

type genruleProps struct {
	Name       *string
	Cmd        *string
	Dists      []android.Dist
	Out        []string
	Srcs       []string
	Tools      []string
	Visibility []string
}

type libraryProps struct {
	Name            *string
	Sdk_version     *string
	Static_libs     []string
	Visibility      []string
	Defaults        []string
	Is_stubs_module *bool
}

type fgProps struct {
	Name       *string
	Srcs       []string
	Visibility []string
}

type defaultsProps struct {
	Name                *string
	Api_surface         *string
	Api_contributions   []string
	Defaults_visibility []string
	Previous_api        *string
}

// Struct to pass parameters for the various merged [current|removed].txt file modules we create.
type MergedTxtDefinition struct {
	// "current.txt" or "removed.txt"
	TxtFilename string
	// Filename in the new dist dir. "android.txt" or "android-removed.txt"
	DistFilename string
	// The module for the non-updatable / non-module part of the api.
	BaseTxt string
	// The list of modules that are relevant for this merged txt.
	Modules []string
	// The output tag for each module to use.e.g. {.public.api.txt} for current.txt
	ModuleTag string
	// public, system, module-lib or system-server
	Scope string
}

func createMergedTxt(ctx android.LoadHookContext, txt MergedTxtDefinition, stubsTypeSuffix string, doDist bool) {
	metalavaCmd := "$(location metalava)"
	// Silence reflection warnings. See b/168689341
	metalavaCmd += " -J--add-opens=java.base/java.util=ALL-UNNAMED "
	metalavaCmd += " --quiet merge-signatures --format=v2 "

	filename := txt.TxtFilename
	if txt.Scope != "public" {
		filename = txt.Scope + "-" + filename
	}
	moduleName := ctx.ModuleName() + stubsTypeSuffix + filename

	props := genruleProps{}
	props.Name = proptools.StringPtr(moduleName)
	props.Tools = []string{"metalava"}
	props.Out = []string{filename}
	props.Cmd = proptools.StringPtr(metalavaCmd + "$(in) --out $(out)")
	props.Srcs = append([]string{txt.BaseTxt}, createSrcs(txt.Modules, txt.ModuleTag)...)
	if doDist {
		props.Dists = []android.Dist{
			{
				Targets: []string{"droidcore"},
				Dir:     proptools.StringPtr("api"),
				Dest:    proptools.StringPtr(filename),
			},
			{
				Targets: []string{"api_txt", "sdk"},
				Dir:     proptools.StringPtr("apistubs/android/" + txt.Scope + "/api"),
				Dest:    proptools.StringPtr(txt.DistFilename),
			},
		}
	}
	props.Visibility = []string{"//visibility:public"}
	ctx.CreateModule(genrule.GenRuleFactory, &props)
}

func createMergedAnnotationsFilegroups(ctx android.LoadHookContext, modules, system_server_modules []string) {
	for _, i := range []struct {
		name    string
		tag     string
		modules []string
	}{
		{
			name:    "all-modules-public-annotations",
			tag:     "{.public.annotations.zip}",
			modules: modules,
		}, {
			name:    "all-modules-system-annotations",
			tag:     "{.system.annotations.zip}",
			modules: modules,
		}, {
			name:    "all-modules-module-lib-annotations",
			tag:     "{.module-lib.annotations.zip}",
			modules: modules,
		}, {
			name:    "all-modules-system-server-annotations",
			tag:     "{.system-server.annotations.zip}",
			modules: system_server_modules,
		},
	} {
		props := fgProps{}
		props.Name = proptools.StringPtr(i.name)
		props.Srcs = createSrcs(i.modules, i.tag)
		ctx.CreateModule(android.FileGroupFactory, &props)
	}
}

func createMergedPublicStubs(ctx android.LoadHookContext, modules []string) {
	props := libraryProps{}
	props.Name = proptools.StringPtr("all-modules-public-stubs")
	props.Static_libs = transformArray(modules, "", ".stubs")
	props.Sdk_version = proptools.StringPtr("module_current")
	props.Visibility = []string{"//frameworks/base"}
	props.Is_stubs_module = proptools.BoolPtr(true)
	ctx.CreateModule(java.LibraryFactory, &props)
}

func createMergedPublicExportableStubs(ctx android.LoadHookContext, modules []string) {
	props := libraryProps{}
	props.Name = proptools.StringPtr("all-modules-public-stubs-exportable")
	props.Static_libs = transformArray(modules, "", ".stubs.exportable")
	props.Sdk_version = proptools.StringPtr("module_current")
	props.Visibility = []string{"//frameworks/base"}
	props.Is_stubs_module = proptools.BoolPtr(true)
	ctx.CreateModule(java.LibraryFactory, &props)
}

func createMergedSystemStubs(ctx android.LoadHookContext, modules []string) {
	// First create the all-updatable-modules-system-stubs
	{
		updatable_modules := removeAll(modules, non_updatable_modules)
		props := libraryProps{}
		props.Name = proptools.StringPtr("all-updatable-modules-system-stubs")
		props.Static_libs = transformArray(updatable_modules, "", ".stubs.system")
		props.Sdk_version = proptools.StringPtr("module_current")
		props.Visibility = []string{"//frameworks/base"}
		props.Is_stubs_module = proptools.BoolPtr(true)
		ctx.CreateModule(java.LibraryFactory, &props)
	}
	// Now merge all-updatable-modules-system-stubs and stubs from non-updatable modules
	// into all-modules-system-stubs.
	{
		props := libraryProps{}
		props.Name = proptools.StringPtr("all-modules-system-stubs")
		props.Static_libs = transformArray(non_updatable_modules, "", ".stubs.system")
		props.Static_libs = append(props.Static_libs, "all-updatable-modules-system-stubs")
		props.Sdk_version = proptools.StringPtr("module_current")
		props.Visibility = []string{"//frameworks/base"}
		props.Is_stubs_module = proptools.BoolPtr(true)
		ctx.CreateModule(java.LibraryFactory, &props)
	}
}

func createMergedSystemExportableStubs(ctx android.LoadHookContext, modules []string) {
	// First create the all-updatable-modules-system-stubs
	{
		updatable_modules := removeAll(modules, non_updatable_modules)
		props := libraryProps{}
		props.Name = proptools.StringPtr("all-updatable-modules-system-stubs-exportable")
		props.Static_libs = transformArray(updatable_modules, "", ".stubs.exportable.system")
		props.Sdk_version = proptools.StringPtr("module_current")
		props.Visibility = []string{"//frameworks/base"}
		props.Is_stubs_module = proptools.BoolPtr(true)
		ctx.CreateModule(java.LibraryFactory, &props)
	}
	// Now merge all-updatable-modules-system-stubs and stubs from non-updatable modules
	// into all-modules-system-stubs.
	{
		props := libraryProps{}
		props.Name = proptools.StringPtr("all-modules-system-stubs-exportable")
		props.Static_libs = transformArray(non_updatable_modules, "", ".stubs.exportable.system")
		props.Static_libs = append(props.Static_libs, "all-updatable-modules-system-stubs-exportable")
		props.Sdk_version = proptools.StringPtr("module_current")
		props.Visibility = []string{"//frameworks/base"}
		props.Is_stubs_module = proptools.BoolPtr(true)
		ctx.CreateModule(java.LibraryFactory, &props)
	}
}

func createMergedTestStubsForNonUpdatableModules(ctx android.LoadHookContext) {
	props := libraryProps{}
	props.Name = proptools.StringPtr("all-non-updatable-modules-test-stubs")
	props.Static_libs = transformArray(non_updatable_modules, "", ".stubs.test")
	props.Sdk_version = proptools.StringPtr("module_current")
	props.Visibility = []string{"//frameworks/base"}
	props.Is_stubs_module = proptools.BoolPtr(true)
	ctx.CreateModule(java.LibraryFactory, &props)
}

func createMergedTestExportableStubsForNonUpdatableModules(ctx android.LoadHookContext) {
	props := libraryProps{}
	props.Name = proptools.StringPtr("all-non-updatable-modules-test-stubs-exportable")
	props.Static_libs = transformArray(non_updatable_modules, "", ".stubs.exportable.test")
	props.Sdk_version = proptools.StringPtr("module_current")
	props.Visibility = []string{"//frameworks/base"}
	props.Is_stubs_module = proptools.BoolPtr(true)
	ctx.CreateModule(java.LibraryFactory, &props)
}

func createMergedFrameworkImpl(ctx android.LoadHookContext, modules []string) {
	// This module is for the "framework-all" module, which should not include the core libraries.
	modules = removeAll(modules, core_libraries_modules)
	// Remove the modules that belong to non-updatable APEXes since those are allowed to compile
	// against unstable APIs.
	modules = removeAll(modules, non_updatable_modules)
	// First create updatable-framework-module-impl, which contains all updatable modules.
	// This module compiles against module_lib SDK.
	{
		props := libraryProps{}
		props.Name = proptools.StringPtr("updatable-framework-module-impl")
		props.Static_libs = transformArray(modules, "", ".impl")
		props.Sdk_version = proptools.StringPtr("module_current")
		props.Visibility = []string{"//frameworks/base"}
		ctx.CreateModule(java.LibraryFactory, &props)
	}

	// Now create all-framework-module-impl, which contains updatable-framework-module-impl
	// and all non-updatable modules. This module compiles against hidden APIs.
	{
		props := libraryProps{}
		props.Name = proptools.StringPtr("all-framework-module-impl")
		props.Static_libs = transformArray(non_updatable_modules, "", ".impl")
		props.Static_libs = append(props.Static_libs, "updatable-framework-module-impl")
		props.Sdk_version = proptools.StringPtr("core_platform")
		props.Visibility = []string{"//frameworks/base"}
		ctx.CreateModule(java.LibraryFactory, &props)
	}
}

func createMergedFrameworkModuleLibExportableStubs(ctx android.LoadHookContext, modules []string) {
	// The user of this module compiles against the "core" SDK and against non-updatable modules,
	// so remove to avoid dupes.
	modules = removeAll(modules, core_libraries_modules)
	modules = removeAll(modules, non_updatable_modules)
	props := libraryProps{}
	props.Name = proptools.StringPtr("framework-updatable-stubs-module_libs_api-exportable")
	props.Static_libs = transformArray(modules, "", ".stubs.exportable.module_lib")
	props.Sdk_version = proptools.StringPtr("module_current")
	props.Visibility = []string{"//frameworks/base"}
	props.Is_stubs_module = proptools.BoolPtr(true)
	ctx.CreateModule(java.LibraryFactory, &props)
}

func createMergedFrameworkModuleLibStubs(ctx android.LoadHookContext, modules []string) {
	// The user of this module compiles against the "core" SDK and against non-updatable modules,
	// so remove to avoid dupes.
	modules = removeAll(modules, core_libraries_modules)
	modules = removeAll(modules, non_updatable_modules)
	props := libraryProps{}
	props.Name = proptools.StringPtr("framework-updatable-stubs-module_libs_api")
	props.Static_libs = transformArray(modules, "", ".stubs.module_lib")
	props.Sdk_version = proptools.StringPtr("module_current")
	props.Visibility = []string{"//frameworks/base"}
	props.Is_stubs_module = proptools.BoolPtr(true)
	ctx.CreateModule(java.LibraryFactory, &props)
}

func createPublicStubsSourceFilegroup(ctx android.LoadHookContext, modules []string) {
	props := fgProps{}
	props.Name = proptools.StringPtr("all-modules-public-stubs-source")
	props.Srcs = createSrcs(modules, "{.public.stubs.source}")
	props.Visibility = []string{"//frameworks/base"}
	ctx.CreateModule(android.FileGroupFactory, &props)
}

func createMergedTxts(ctx android.LoadHookContext, bootclasspath, system_server_classpath []string, baseTxtModulePrefix, stubsTypeSuffix string, doDist bool) {
	var textFiles []MergedTxtDefinition

	tagSuffix := []string{".api.txt}", ".removed-api.txt}"}
	distFilename := []string{"android.txt", "android-removed.txt"}
	for i, f := range []string{"current.txt", "removed.txt"} {
		textFiles = append(textFiles, MergedTxtDefinition{
			TxtFilename:  f,
			DistFilename: distFilename[i],
			BaseTxt:      ":" + baseTxtModulePrefix + f,
			Modules:      bootclasspath,
			ModuleTag:    "{.public" + tagSuffix[i],
			Scope:        "public",
		})
		textFiles = append(textFiles, MergedTxtDefinition{
			TxtFilename:  f,
			DistFilename: distFilename[i],
			BaseTxt:      ":" + baseTxtModulePrefix + "system-" + f,
			Modules:      bootclasspath,
			ModuleTag:    "{.system" + tagSuffix[i],
			Scope:        "system",
		})
		textFiles = append(textFiles, MergedTxtDefinition{
			TxtFilename:  f,
			DistFilename: distFilename[i],
			BaseTxt:      ":" + baseTxtModulePrefix + "module-lib-" + f,
			Modules:      bootclasspath,
			ModuleTag:    "{.module-lib" + tagSuffix[i],
			Scope:        "module-lib",
		})
		textFiles = append(textFiles, MergedTxtDefinition{
			TxtFilename:  f,
			DistFilename: distFilename[i],
			BaseTxt:      ":" + baseTxtModulePrefix + "system-server-" + f,
			Modules:      system_server_classpath,
			ModuleTag:    "{.system-server" + tagSuffix[i],
			Scope:        "system-server",
		})
	}
	for _, txt := range textFiles {
		createMergedTxt(ctx, txt, stubsTypeSuffix, doDist)
	}
}

func createApiContributionDefaults(ctx android.LoadHookContext, modules []string) {
	defaultsSdkKinds := []android.SdkKind{
		android.SdkPublic, android.SdkSystem, android.SdkModule,
	}
	for _, sdkKind := range defaultsSdkKinds {
		props := defaultsProps{}
		props.Name = proptools.StringPtr(
			sdkKind.DefaultJavaLibraryName() + "_contributions")
		if sdkKind == android.SdkModule {
			props.Name = proptools.StringPtr(
				sdkKind.DefaultJavaLibraryName() + "_contributions_full")
		}
		props.Api_surface = proptools.StringPtr(sdkKind.String())
		apiSuffix := ""
		if sdkKind != android.SdkPublic {
			apiSuffix = "." + strings.ReplaceAll(sdkKind.String(), "-", "_")
		}
		props.Api_contributions = transformArray(
			modules, "", fmt.Sprintf(".stubs.source%s.api.contribution", apiSuffix))
		props.Defaults_visibility = []string{"//visibility:public"}
		props.Previous_api = proptools.StringPtr(":android.api.public.latest")
		ctx.CreateModule(java.DefaultsFactory, &props)
	}
}

func createFullApiLibraries(ctx android.LoadHookContext) {
	javaLibraryNames := []string{
		"android_stubs_current",
		"android_system_stubs_current",
		"android_test_stubs_current",
		"android_test_frameworks_core_stubs_current",
		"android_module_lib_stubs_current",
		"android_system_server_stubs_current",
	}

	for _, libraryName := range javaLibraryNames {
		props := libraryProps{}
		props.Name = proptools.StringPtr(libraryName)
		staticLib := libraryName + ".from-source"
		if ctx.Config().BuildFromTextStub() {
			staticLib = libraryName + ".from-text"
		}
		props.Static_libs = []string{staticLib}
		props.Defaults = []string{"android.jar_defaults"}
		props.Visibility = []string{"//visibility:public"}
		props.Is_stubs_module = proptools.BoolPtr(true)

		ctx.CreateModule(java.LibraryFactory, &props)
	}
}

func createFullExportableApiLibraries(ctx android.LoadHookContext) {
	javaLibraryNames := []string{
		"android_stubs_current_exportable",
		"android_system_stubs_current_exportable",
		"android_test_stubs_current_exportable",
		"android_module_lib_stubs_current_exportable",
		"android_system_server_stubs_current_exportable",
	}

	for _, libraryName := range javaLibraryNames {
		props := libraryProps{}
		props.Name = proptools.StringPtr(libraryName)
		staticLib := libraryName + ".from-source"
		props.Static_libs = []string{staticLib}
		props.Defaults = []string{"android.jar_defaults"}
		props.Visibility = []string{"//visibility:public"}
		props.Is_stubs_module = proptools.BoolPtr(true)

		ctx.CreateModule(java.LibraryFactory, &props)
	}
}

func (a *CombinedApis) createInternalModules(ctx android.LoadHookContext) {
	bootclasspath := a.properties.Bootclasspath
	system_server_classpath := a.properties.System_server_classpath
	if ctx.Config().VendorConfig("ANDROID").Bool("include_nonpublic_framework_api") {
		bootclasspath = append(bootclasspath, a.properties.Conditional_bootclasspath...)
		sort.Strings(bootclasspath)
	}
	createMergedTxts(ctx, bootclasspath, system_server_classpath, "non-updatable-", "-", false)
	createMergedTxts(ctx, bootclasspath, system_server_classpath, "non-updatable-exportable-", "-exportable-", true)

	createMergedPublicStubs(ctx, bootclasspath)
	createMergedSystemStubs(ctx, bootclasspath)
	createMergedTestStubsForNonUpdatableModules(ctx)
	createMergedFrameworkModuleLibStubs(ctx, bootclasspath)
	createMergedFrameworkImpl(ctx, bootclasspath)

	createMergedPublicExportableStubs(ctx, bootclasspath)
	createMergedSystemExportableStubs(ctx, bootclasspath)
	createMergedTestExportableStubsForNonUpdatableModules(ctx)
	createMergedFrameworkModuleLibExportableStubs(ctx, bootclasspath)

	createMergedAnnotationsFilegroups(ctx, bootclasspath, system_server_classpath)

	createPublicStubsSourceFilegroup(ctx, bootclasspath)

	createApiContributionDefaults(ctx, bootclasspath)

	createFullApiLibraries(ctx)

	createFullExportableApiLibraries(ctx)
}

func combinedApisModuleFactory() android.Module {
	module := &CombinedApis{}
	module.AddProperties(&module.properties)
	android.InitAndroidModule(module)
	android.InitDefaultableModule(module)
	android.AddLoadHook(module, func(ctx android.LoadHookContext) { module.createInternalModules(ctx) })
	return module
}

// Various utility methods below.

// Creates an array of ":<m><tag>" for each m in <modules>.
func createSrcs(modules []string, tag string) []string {
	return transformArray(modules, ":", tag)
}

// Creates an array of "<prefix><m><suffix>", for each m in <modules>.
func transformArray(modules []string, prefix, suffix string) []string {
	a := make([]string, 0, len(modules))
	for _, module := range modules {
		a = append(a, prefix+module+suffix)
	}
	return a
}

func removeAll(s []string, vs []string) []string {
	for _, v := range vs {
		s = remove(s, v)
	}
	return s
}

func remove(s []string, v string) []string {
	s2 := make([]string, 0, len(s))
	for _, sv := range s {
		if sv != v {
			s2 = append(s2, sv)
		}
	}
	return s2
}

// Defaults
type CombinedApisModuleDefaults struct {
	android.ModuleBase
	android.DefaultsModuleBase
}

func CombinedApisModuleDefaultsFactory() android.Module {
	module := &CombinedApisModuleDefaults{}
	module.AddProperties(&CombinedApisProperties{})
	android.InitDefaultsModule(module)
	return module
}
