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

package sysprop

import (
	"fmt"
	"io"
	"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()
	})
}

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.Path
	currentApiFile        android.Path
	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

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

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) CcModuleName() 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.Path {
	return m.currentApiFile
}

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
	}

	m.currentApiFile = android.PathForSource(ctx, ctx.ModuleDir(), "api", baseModuleName+"-current.txt")
	m.latestApiFile = android.PathForSource(ctx, ctx.ModuleDir(), "api", baseModuleName+"-latest.txt")

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

	// check API rule
	rule = android.NewRuleBuilder()

	// 1. current.txt <-> 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 && rm -rf %q && cp -f %q %q\n`+
		`******************************\n`, baseModuleName, baseModuleName,
		m.currentApiFile.String(), m.dumpedApiFile.String(), m.currentApiFile.String())

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

	// 2. current.txt <-> 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(ctx, "sysprop_api_checker").
		Input(m.latestApiFile).
		Input(m.currentApiFile).
		Text(" || ( echo").Flag("-e").
		Flag(`"` + msg + `"`).
		Text("; exit 38) )")

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

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

	rule.Build(pctx, ctx, 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())
			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())
		}}
}

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

	missing_api := false

	for _, txt := range []string{"-current.txt", "-latest.txt"} {
		path := path.Join(ctx.ModuleDir(), "api", m.BaseModuleName()+txt)
		file := android.ExistentPathForSource(ctx, path)
		if !file.Valid() {
			ctx.ModuleErrorf("API file %#v doesn't exist", path)
			missing_api = true
		}
	}

	if missing_api {
		script := "build/soong/scripts/gen-sysprop-api-files.sh"
		p := android.ExistentPathForSource(ctx, script)

		if !p.Valid() {
			panic(fmt.Sprintf("script file %s doesn't exist", script))
		}

		ctx.ModuleErrorf("One or more api files are missing. "+
			"You can create them by:\n"+
			"%s %q %q", script, ctx.ModuleDir(), m.BaseModuleName())
		return
	}

	// ctx's Platform or Specific functions represent where this sysprop_library installed.
	installedInSystem := ctx.Platform() || ctx.SystemExtSpecific()
	installedInVendorOrOdm := ctx.SocSpecific() || ctx.DeviceSpecific()
	isOwnerPlatform := false
	stub := "sysprop-library-stub-"

	switch m.Owner() {
	case "Platform":
		// Every partition can access platform-defined properties
		stub += "platform"
		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")
		}
		stub += "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")
		}
		stub += "vendor"
	default:
		ctx.PropertyErrorf("property_owner",
			"Unknown value %s: must be one of Platform, Vendor or Odm", m.Owner())
	}

	ccProps := ccLibraryProperties{}
	ccProps.Name = proptools.StringPtr(m.CcModuleName())
	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.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.
		scope = "public"
	} else if isOwnerPlatform && installedInVendorOrOdm {
		// Vendor or Odm should use public version of Platform's sysprop_library.
		scope = "public"
	}

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

	// 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{stub},
			Stem:        proptools.StringPtr(m.BaseModuleName()),
		})
	}

	if m.ExportedToMake() {
		syspropLibrariesLock.Lock()
		defer syspropLibrariesLock.Unlock()

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

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