// Copyright (C) 2019 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.

// sysprop package defines a module named sysprop_library that can implement sysprop as API
// See https://source.android.com/devices/architecture/sysprops-apis for details
package sysprop

import (
	"fmt"
	"io"
	"os"
	"path"
	"sync"

	"android/soong/bazel"
	"android/soong/sysprop/bp2build"
	"android/soong/ui/metrics/bp2build_metrics_proto"

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

	"android/soong/android"
	"android/soong/cc"
	"android/soong/java"
)

type dependencyTag struct {
	blueprint.BaseDependencyTag
	name string
}

type syspropGenProperties struct {
	Srcs      []string `android:"path"`
	Scope     string
	Name      *string
	Check_api *string
}

type syspropJavaGenRule struct {
	android.ModuleBase

	properties syspropGenProperties

	genSrcjars android.Paths
}

var _ android.OutputFileProducer = (*syspropJavaGenRule)(nil)

var (
	syspropJava = pctx.AndroidStaticRule("syspropJava",
		blueprint.RuleParams{
			Command: `rm -rf $out.tmp && mkdir -p $out.tmp && ` +
				`$syspropJavaCmd --scope $scope --java-output-dir $out.tmp $in && ` +
				`$soongZipCmd -jar -o $out -C $out.tmp -D $out.tmp && rm -rf $out.tmp`,
			CommandDeps: []string{
				"$syspropJavaCmd",
				"$soongZipCmd",
			},
		}, "scope")
)

func init() {
	pctx.HostBinToolVariable("soongZipCmd", "soong_zip")
	pctx.HostBinToolVariable("syspropJavaCmd", "sysprop_java")
}

// syspropJavaGenRule module generates srcjar containing generated java APIs.
// It also depends on check api rule, so api check has to pass to use sysprop_library.
func (g *syspropJavaGenRule) GenerateAndroidBuildActions(ctx android.ModuleContext) {
	var checkApiFileTimeStamp android.WritablePath

	ctx.VisitDirectDeps(func(dep android.Module) {
		if m, ok := dep.(*syspropLibrary); ok {
			checkApiFileTimeStamp = m.checkApiFileTimeStamp
		}
	})

	for _, syspropFile := range android.PathsForModuleSrc(ctx, g.properties.Srcs) {
		srcJarFile := android.GenPathWithExt(ctx, "sysprop", syspropFile, "srcjar")

		ctx.Build(pctx, android.BuildParams{
			Rule:        syspropJava,
			Description: "sysprop_java " + syspropFile.Rel(),
			Output:      srcJarFile,
			Input:       syspropFile,
			Implicit:    checkApiFileTimeStamp,
			Args: map[string]string{
				"scope": g.properties.Scope,
			},
		})

		g.genSrcjars = append(g.genSrcjars, srcJarFile)
	}
}

func (g *syspropJavaGenRule) DepsMutator(ctx android.BottomUpMutatorContext) {
	// Add a dependency from the stubs to sysprop library so that the generator rule can depend on
	// the check API rule of the sysprop library.
	ctx.AddFarVariationDependencies(nil, nil, proptools.String(g.properties.Check_api))
}

func (g *syspropJavaGenRule) OutputFiles(tag string) (android.Paths, error) {
	switch tag {
	case "":
		return g.genSrcjars, nil
	default:
		return nil, fmt.Errorf("unsupported module reference tag %q", tag)
	}
}

func syspropJavaGenFactory() android.Module {
	g := &syspropJavaGenRule{}
	g.AddProperties(&g.properties)
	android.InitAndroidModule(g)
	return g
}

type syspropLibrary struct {
	android.ModuleBase
	android.ApexModuleBase
	android.BazelModuleBase

	properties syspropLibraryProperties

	checkApiFileTimeStamp android.WritablePath
	latestApiFile         android.OptionalPath
	currentApiFile        android.OptionalPath
	dumpedApiFile         android.WritablePath
}

type syspropLibraryProperties struct {
	// Determine who owns this sysprop library. Possible values are
	// "Platform", "Vendor", or "Odm"
	Property_owner string

	// list of package names that will be documented and publicized as API
	Api_packages []string

	// If set to true, allow this module to be dexed and installed on devices.
	Installable *bool

	// Make this module available when building for ramdisk
	Ramdisk_available *bool

	// Make this module available when building for recovery
	Recovery_available *bool

	// Make this module available when building for vendor
	Vendor_available *bool

	// Make this module available when building for product
	Product_available *bool

	// list of .sysprop files which defines the properties.
	Srcs []string `android:"path"`

	// If set to true, build a variant of the module for the host.  Defaults to false.
	Host_supported *bool

	Cpp struct {
		// Minimum sdk version that the artifact should support when it runs as part of mainline modules(APEX).
		// Forwarded to cc_library.min_sdk_version
		Min_sdk_version *string
	}

	Java struct {
		// Minimum sdk version that the artifact should support when it runs as part of mainline modules(APEX).
		// Forwarded to java_library.min_sdk_version
		Min_sdk_version *string
	}
}

var (
	pctx         = android.NewPackageContext("android/soong/sysprop")
	syspropCcTag = dependencyTag{name: "syspropCc"}

	syspropLibrariesKey  = android.NewOnceKey("syspropLibraries")
	syspropLibrariesLock sync.Mutex
)

// List of sysprop_library used by property_contexts to perform type check.
func syspropLibraries(config android.Config) *[]string {
	return config.Once(syspropLibrariesKey, func() interface{} {
		return &[]string{}
	}).(*[]string)
}

func SyspropLibraries(config android.Config) []string {
	return append([]string{}, *syspropLibraries(config)...)
}

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

func registerSyspropBuildComponents(ctx android.RegistrationContext) {
	ctx.RegisterModuleType("sysprop_library", syspropLibraryFactory)
}

func (m *syspropLibrary) Name() string {
	return m.BaseModuleName() + "_sysprop_library"
}

func (m *syspropLibrary) Owner() string {
	return m.properties.Property_owner
}

func (m *syspropLibrary) CcImplementationModuleName() string {
	return "lib" + m.BaseModuleName()
}

func (m *syspropLibrary) javaPublicStubName() string {
	return m.BaseModuleName() + "_public"
}

func (m *syspropLibrary) javaGenModuleName() string {
	return m.BaseModuleName() + "_java_gen"
}

func (m *syspropLibrary) javaGenPublicStubName() string {
	return m.BaseModuleName() + "_java_gen_public"
}

func (m *syspropLibrary) bp2buildJavaImplementationModuleName() string {
	return m.BaseModuleName() + "_java_library"
}

func (m *syspropLibrary) BaseModuleName() string {
	return m.ModuleBase.Name()
}

func (m *syspropLibrary) CurrentSyspropApiFile() android.OptionalPath {
	return m.currentApiFile
}

// GenerateAndroidBuildActions of sysprop_library handles API dump and API check.
// generated java_library will depend on these API files.
func (m *syspropLibrary) GenerateAndroidBuildActions(ctx android.ModuleContext) {
	baseModuleName := m.BaseModuleName()

	for _, syspropFile := range android.PathsForModuleSrc(ctx, m.properties.Srcs) {
		if syspropFile.Ext() != ".sysprop" {
			ctx.PropertyErrorf("srcs", "srcs contains non-sysprop file %q", syspropFile.String())
		}
	}

	if ctx.Failed() {
		return
	}

	apiDirectoryPath := path.Join(ctx.ModuleDir(), "api")
	currentApiFilePath := path.Join(apiDirectoryPath, baseModuleName+"-current.txt")
	latestApiFilePath := path.Join(apiDirectoryPath, baseModuleName+"-latest.txt")
	m.currentApiFile = android.ExistentPathForSource(ctx, currentApiFilePath)
	m.latestApiFile = android.ExistentPathForSource(ctx, latestApiFilePath)

	// dump API rule
	rule := android.NewRuleBuilder(pctx, ctx)
	m.dumpedApiFile = android.PathForModuleOut(ctx, "api-dump.txt")
	rule.Command().
		BuiltTool("sysprop_api_dump").
		Output(m.dumpedApiFile).
		Inputs(android.PathsForModuleSrc(ctx, m.properties.Srcs))
	rule.Build(baseModuleName+"_api_dump", baseModuleName+" api dump")

	// check API rule
	rule = android.NewRuleBuilder(pctx, ctx)

	// We allow that the API txt files don't exist, when the sysprop_library only contains internal
	// properties. But we have to feed current api file and latest api file to the rule builder.
	// Currently we can't get android.Path representing the null device, so we add any existing API
	// txt files to implicits, and then directly feed string paths, rather than calling Input(Path)
	// method.
	var apiFileList android.Paths
	currentApiArgument := os.DevNull
	if m.currentApiFile.Valid() {
		apiFileList = append(apiFileList, m.currentApiFile.Path())
		currentApiArgument = m.currentApiFile.String()
	}

	latestApiArgument := os.DevNull
	if m.latestApiFile.Valid() {
		apiFileList = append(apiFileList, m.latestApiFile.Path())
		latestApiArgument = m.latestApiFile.String()
	}

	// 1. compares current.txt to api-dump.txt
	// current.txt should be identical to api-dump.txt.
	msg := fmt.Sprintf(`\n******************************\n`+
		`API of sysprop_library %s doesn't match with current.txt\n`+
		`Please update current.txt by:\n`+
		`m %s-dump-api && mkdir -p %q && rm -rf %q && cp -f %q %q\n`+
		`******************************\n`, baseModuleName, baseModuleName,
		apiDirectoryPath, currentApiFilePath, m.dumpedApiFile.String(), currentApiFilePath)

	rule.Command().
		Text("( cmp").Flag("-s").
		Input(m.dumpedApiFile).
		Text(currentApiArgument).
		Text("|| ( echo").Flag("-e").
		Flag(`"` + msg + `"`).
		Text("; exit 38) )")

	// 2. compares current.txt to latest.txt (frozen API)
	// current.txt should be compatible with latest.txt
	msg = fmt.Sprintf(`\n******************************\n`+
		`API of sysprop_library %s doesn't match with latest version\n`+
		`Please fix the breakage and rebuild.\n`+
		`******************************\n`, baseModuleName)

	rule.Command().
		Text("( ").
		BuiltTool("sysprop_api_checker").
		Text(latestApiArgument).
		Text(currentApiArgument).
		Text(" || ( echo").Flag("-e").
		Flag(`"` + msg + `"`).
		Text("; exit 38) )").
		Implicits(apiFileList)

	m.checkApiFileTimeStamp = android.PathForModuleOut(ctx, "check_api.timestamp")

	rule.Command().
		Text("touch").
		Output(m.checkApiFileTimeStamp)

	rule.Build(baseModuleName+"_check_api", baseModuleName+" check api")
}

func (m *syspropLibrary) AndroidMk() android.AndroidMkData {
	return android.AndroidMkData{
		Custom: func(w io.Writer, name, prefix, moduleDir string, data android.AndroidMkData) {
			// sysprop_library module itself is defined as a FAKE module to perform API check.
			// Actual implementation libraries are created on LoadHookMutator
			fmt.Fprintln(w, "\ninclude $(CLEAR_VARS)", " # sysprop.syspropLibrary")
			fmt.Fprintln(w, "LOCAL_MODULE :=", m.Name())
			data.Entries.WriteLicenseVariables(w)
			fmt.Fprintf(w, "LOCAL_MODULE_CLASS := FAKE\n")
			fmt.Fprintf(w, "LOCAL_MODULE_TAGS := optional\n")
			fmt.Fprintf(w, "include $(BUILD_SYSTEM)/base_rules.mk\n\n")
			fmt.Fprintf(w, "$(LOCAL_BUILT_MODULE): %s\n", m.checkApiFileTimeStamp.String())
			fmt.Fprintf(w, "\ttouch $@\n\n")
			fmt.Fprintf(w, ".PHONY: %s-check-api %s-dump-api\n\n", name, name)

			// dump API rule
			fmt.Fprintf(w, "%s-dump-api: %s\n\n", name, m.dumpedApiFile.String())

			// check API rule
			fmt.Fprintf(w, "%s-check-api: %s\n\n", name, m.checkApiFileTimeStamp.String())
		}}
}

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

// Implements android.ApexModule
func (m *syspropLibrary) ShouldSupportSdkVersion(ctx android.BaseModuleContext,
	sdkVersion android.ApiLevel) error {
	return fmt.Errorf("sysprop_library is not supposed to be part of apex modules")
}

// sysprop_library creates schematized APIs from sysprop description files (.sysprop).
// Both Java and C++ modules can link against sysprop_library, and API stability check
// against latest APIs (see build/soong/scripts/freeze-sysprop-api-files.sh)
// is performed. Note that the generated C++ module has its name prefixed with
// `lib`, and it is this module that should be depended on from other C++
// modules; i.e., if the sysprop_library module is named `foo`, C++ modules
// should depend on `libfoo`.
func syspropLibraryFactory() android.Module {
	m := &syspropLibrary{}

	m.AddProperties(
		&m.properties,
	)
	android.InitAndroidModule(m)
	android.InitApexModule(m)
	android.InitBazelModule(m)
	android.AddLoadHook(m, func(ctx android.LoadHookContext) { syspropLibraryHook(ctx, m) })
	return m
}

type ccLibraryProperties struct {
	Name             *string
	Srcs             []string
	Soc_specific     *bool
	Device_specific  *bool
	Product_specific *bool
	Sysprop          struct {
		Platform *bool
	}
	Target struct {
		Android struct {
			Header_libs []string
			Shared_libs []string
		}
		Host struct {
			Static_libs []string
		}
	}
	Required           []string
	Recovery           *bool
	Recovery_available *bool
	Vendor_available   *bool
	Product_available  *bool
	Ramdisk_available  *bool
	Host_supported     *bool
	Apex_available     []string
	Min_sdk_version    *string
	Bazel_module       struct {
		Label *string
	}
}

type javaLibraryProperties struct {
	Name              *string
	Srcs              []string
	Soc_specific      *bool
	Device_specific   *bool
	Product_specific  *bool
	Required          []string
	Sdk_version       *string
	Installable       *bool
	Libs              []string
	Stem              *string
	SyspropPublicStub string
	Apex_available    []string
	Min_sdk_version   *string
	Bazel_module      struct {
		Bp2build_available *bool
		Label              *string
	}
}

func syspropLibraryHook(ctx android.LoadHookContext, m *syspropLibrary) {
	if len(m.properties.Srcs) == 0 {
		ctx.PropertyErrorf("srcs", "sysprop_library must specify srcs")
	}

	// ctx's Platform or Specific functions represent where this sysprop_library installed.
	installedInSystem := ctx.Platform() || ctx.SystemExtSpecific()
	installedInVendorOrOdm := ctx.SocSpecific() || ctx.DeviceSpecific()
	installedInProduct := ctx.ProductSpecific()
	isOwnerPlatform := false
	var javaSyspropStub string

	// javaSyspropStub contains stub libraries used by generated APIs, instead of framework stub.
	// This is to make sysprop_library link against core_current.
	if installedInVendorOrOdm {
		javaSyspropStub = "sysprop-library-stub-vendor"
	} else if installedInProduct {
		javaSyspropStub = "sysprop-library-stub-product"
	} else {
		javaSyspropStub = "sysprop-library-stub-platform"
	}

	switch m.Owner() {
	case "Platform":
		// Every partition can access platform-defined properties
		isOwnerPlatform = true
	case "Vendor":
		// System can't access vendor's properties
		if installedInSystem {
			ctx.ModuleErrorf("None of soc_specific, device_specific, product_specific is true. " +
				"System can't access sysprop_library owned by Vendor")
		}
	case "Odm":
		// Only vendor can access Odm-defined properties
		if !installedInVendorOrOdm {
			ctx.ModuleErrorf("Neither soc_speicifc nor device_specific is true. " +
				"Odm-defined properties should be accessed only in Vendor or Odm")
		}
	default:
		ctx.PropertyErrorf("property_owner",
			"Unknown value %s: must be one of Platform, Vendor or Odm", m.Owner())
	}

	var label *string
	if b, ok := ctx.Module().(android.Bazelable); ok && b.ShouldConvertWithBp2build(ctx) {
		// TODO: b/295566168 - this will need to change once build files are checked in to account for
		// checked in modules in mixed builds
		label = proptools.StringPtr(
			fmt.Sprintf("//%s:%s", ctx.ModuleDir(), m.CcImplementationModuleName()))
	}

	// Generate a C++ implementation library.
	// cc_library can receive *.sysprop files as their srcs, generating sources itself.
	ccProps := ccLibraryProperties{}
	ccProps.Name = proptools.StringPtr(m.CcImplementationModuleName())
	ccProps.Srcs = m.properties.Srcs
	ccProps.Soc_specific = proptools.BoolPtr(ctx.SocSpecific())
	ccProps.Device_specific = proptools.BoolPtr(ctx.DeviceSpecific())
	ccProps.Product_specific = proptools.BoolPtr(ctx.ProductSpecific())
	ccProps.Sysprop.Platform = proptools.BoolPtr(isOwnerPlatform)
	ccProps.Target.Android.Header_libs = []string{"libbase_headers"}
	ccProps.Target.Android.Shared_libs = []string{"liblog"}
	ccProps.Target.Host.Static_libs = []string{"libbase", "liblog"}
	ccProps.Recovery_available = m.properties.Recovery_available
	ccProps.Vendor_available = m.properties.Vendor_available
	ccProps.Product_available = m.properties.Product_available
	ccProps.Ramdisk_available = m.properties.Ramdisk_available
	ccProps.Host_supported = m.properties.Host_supported
	ccProps.Apex_available = m.ApexProperties.Apex_available
	ccProps.Min_sdk_version = m.properties.Cpp.Min_sdk_version
	ccProps.Bazel_module.Label = label
	ctx.CreateModule(cc.LibraryFactory, &ccProps)

	scope := "internal"

	// We need to only use public version, if the partition where sysprop_library will be installed
	// is different from owner.
	if ctx.ProductSpecific() {
		// Currently product partition can't own any sysprop_library. So product always uses public.
		scope = "public"
	} else if isOwnerPlatform && installedInVendorOrOdm {
		// Vendor or Odm should use public version of Platform's sysprop_library.
		scope = "public"
	}

	// Generate a Java implementation library.
	// Contrast to C++, syspropJavaGenRule module will generate srcjar and the srcjar will be fed
	// to Java implementation library.
	ctx.CreateModule(syspropJavaGenFactory, &syspropGenProperties{
		Srcs:      m.properties.Srcs,
		Scope:     scope,
		Name:      proptools.StringPtr(m.javaGenModuleName()),
		Check_api: proptools.StringPtr(ctx.ModuleName()),
	})

	// if platform sysprop_library is installed in /system or /system-ext, we regard it as an API
	// and allow any modules (even from different partition) to link against the sysprop_library.
	// To do that, we create a public stub and expose it to modules with sdk_version: system_*.
	var publicStub string
	if isOwnerPlatform && installedInSystem {
		publicStub = m.javaPublicStubName()
	}

	ctx.CreateModule(java.LibraryFactory, &javaLibraryProperties{
		Name:              proptools.StringPtr(m.BaseModuleName()),
		Srcs:              []string{":" + m.javaGenModuleName()},
		Soc_specific:      proptools.BoolPtr(ctx.SocSpecific()),
		Device_specific:   proptools.BoolPtr(ctx.DeviceSpecific()),
		Product_specific:  proptools.BoolPtr(ctx.ProductSpecific()),
		Installable:       m.properties.Installable,
		Sdk_version:       proptools.StringPtr("core_current"),
		Libs:              []string{javaSyspropStub},
		SyspropPublicStub: publicStub,
		Apex_available:    m.ApexProperties.Apex_available,
		Min_sdk_version:   m.properties.Java.Min_sdk_version,
		Bazel_module: struct {
			Bp2build_available *bool
			Label              *string
		}{
			Label: proptools.StringPtr(
				fmt.Sprintf("//%s:%s", ctx.ModuleDir(), m.bp2buildJavaImplementationModuleName())),
		},
	})

	if publicStub != "" {
		ctx.CreateModule(syspropJavaGenFactory, &syspropGenProperties{
			Srcs:      m.properties.Srcs,
			Scope:     "public",
			Name:      proptools.StringPtr(m.javaGenPublicStubName()),
			Check_api: proptools.StringPtr(ctx.ModuleName()),
		})

		ctx.CreateModule(java.LibraryFactory, &javaLibraryProperties{
			Name:        proptools.StringPtr(publicStub),
			Srcs:        []string{":" + m.javaGenPublicStubName()},
			Installable: proptools.BoolPtr(false),
			Sdk_version: proptools.StringPtr("core_current"),
			Libs:        []string{javaSyspropStub},
			Stem:        proptools.StringPtr(m.BaseModuleName()),
			Bazel_module: struct {
				Bp2build_available *bool
				Label              *string
			}{
				Bp2build_available: proptools.BoolPtr(false),
			},
		})
	}

	// syspropLibraries will be used by property_contexts to check types.
	// Record absolute paths of sysprop_library to prevent soong_namespace problem.
	if m.ExportedToMake() {
		syspropLibrariesLock.Lock()
		defer syspropLibrariesLock.Unlock()

		libraries := syspropLibraries(ctx.Config())
		*libraries = append(*libraries, "//"+ctx.ModuleDir()+":"+ctx.ModuleName())
	}
}

// TODO(b/240463568): Additional properties will be added for API validation
func (m *syspropLibrary) ConvertWithBp2build(ctx android.Bp2buildMutatorContext) {
	if m.Owner() != "Platform" {
		ctx.MarkBp2buildUnconvertible(bp2build_metrics_proto.UnconvertedReasonType_UNSUPPORTED, "Only sysprop libraries owned by platform are supported at this time")
		return
	}
	labels := bp2build.SyspropLibraryLabels{
		SyspropLibraryLabel:  m.BaseModuleName(),
		CcSharedLibraryLabel: m.CcImplementationModuleName(),
		CcStaticLibraryLabel: cc.BazelLabelNameForStaticModule(m.CcImplementationModuleName()),
		JavaLibraryLabel:     m.bp2buildJavaImplementationModuleName(),
	}
	bp2build.Bp2buildBaseSyspropLibrary(ctx, labels.SyspropLibraryLabel, bazel.MakeLabelListAttribute(android.BazelLabelForModuleSrc(ctx, m.properties.Srcs)))
	bp2build.Bp2buildSyspropCc(ctx, labels, m.properties.Cpp.Min_sdk_version)
	bp2build.Bp2buildSyspropJava(ctx, labels, m.properties.Java.Min_sdk_version)
}
