// 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"

	"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
}

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")

	android.PreArchMutators(func(ctx android.RegisterMutatorsContext) {
		ctx.BottomUp("sysprop_deps", syspropDepsMutator).Parallel()
	})
}

// 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) 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

	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 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

	// Whether public stub exists or not.
	Public_stub *bool `blueprint:"mutated"`

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

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() {
	android.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 {
	if proptools.Bool(m.properties.Public_stub) {
		return m.BaseModuleName() + "_public"
	}
	return ""
}

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) HasPublicStub() bool {
	return proptools.Bool(m.properties.Public_stub)
}

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.
func syspropLibraryFactory() android.Module {
	m := &syspropLibrary{}

	m.AddProperties(
		&m.properties,
	)
	android.InitAndroidModule(m)
	android.InitApexModule(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
	Host_supported     *bool
	Apex_available     []string
	Min_sdk_version    *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
}

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.Host_supported = m.properties.Host_supported
	ccProps.Apex_available = m.ApexProperties.Apex_available
	ccProps.Min_sdk_version = m.properties.Cpp.Min_sdk_version
	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()),
	})

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

	// 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_*.
	if isOwnerPlatform && installedInSystem {
		m.properties.Public_stub = proptools.BoolPtr(true)
		ctx.CreateModule(syspropJavaGenFactory, &syspropGenProperties{
			Srcs:  m.properties.Srcs,
			Scope: "public",
			Name:  proptools.StringPtr(m.javaGenPublicStubName()),
		})

		ctx.CreateModule(java.LibraryFactory, &javaLibraryProperties{
			Name:        proptools.StringPtr(m.JavaPublicStubName()),
			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())
	}
}

// syspropDepsMutator adds dependencies from java implementation library to sysprop library.
// java implementation library then depends on check API rule of sysprop library.
func syspropDepsMutator(ctx android.BottomUpMutatorContext) {
	if m, ok := ctx.Module().(*syspropLibrary); ok {
		ctx.AddReverseDependency(m, nil, m.javaGenModuleName())

		if proptools.Bool(m.properties.Public_stub) {
			ctx.AddReverseDependency(m, nil, m.javaGenPublicStubName())
		}
	}
}
