// 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"
	"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) 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)")
			fmt.Fprintf(w, "LOCAL_MODULE := %s\n", 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 {
		Bp2build_available *bool
	}
}

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
}

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())
	}

	// 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
	// A Bazel macro handles this, so this module does not need to be handled
	// in bp2build
	// TODO(b/237810289) perhaps do something different here so that we aren't
	//                   also disabling these modules in mixed builds
	ccProps.Bazel_module.Bp2build_available = proptools.BoolPtr(false)
	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,
	})

	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()),
		})
	}

	// 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.TopDownMutatorContext) {
	labels := cc.SyspropLibraryLabels{
		SyspropLibraryLabel: m.BaseModuleName(),
		SharedLibraryLabel:  m.CcImplementationModuleName(),
		StaticLibraryLabel:  cc.BazelLabelNameForStaticModule(m.CcImplementationModuleName()),
	}
	cc.Bp2buildSysprop(ctx,
		labels,
		bazel.MakeLabelListAttribute(android.BazelLabelForModuleSrc(ctx, m.properties.Srcs)),
		m.properties.Cpp.Min_sdk_version)
}
