// Copyright 2019 Google Inc. All rights reserved.
//
// 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 android

// This file provides module types that implement wrapper module types that add conditionals on
// Soong config variables.

import (
	"fmt"
	"path/filepath"
	"reflect"
	"strings"
	"sync"
	"text/scanner"

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

	"android/soong/android/soongconfig"
)

func init() {
	RegisterSoongConfigModuleBuildComponents(InitRegistrationContext)
}

func RegisterSoongConfigModuleBuildComponents(ctx RegistrationContext) {
	ctx.RegisterModuleType("soong_config_module_type_import", SoongConfigModuleTypeImportFactory)
	ctx.RegisterModuleType("soong_config_module_type", SoongConfigModuleTypeFactory)
	ctx.RegisterModuleType("soong_config_string_variable", SoongConfigStringVariableDummyFactory)
	ctx.RegisterModuleType("soong_config_bool_variable", SoongConfigBoolVariableDummyFactory)
	ctx.RegisterModuleType("soong_config_value_variable", SoongConfigValueVariableDummyFactory)
}

var PrepareForTestWithSoongConfigModuleBuildComponents = FixtureRegisterWithContext(RegisterSoongConfigModuleBuildComponents)

type soongConfigModuleTypeImport struct {
	ModuleBase
	properties soongConfigModuleTypeImportProperties
}

type soongConfigModuleTypeImportProperties struct {
	From         string
	Module_types []string
}

// soong_config_module_type_import imports module types with conditionals on Soong config
// variables from another Android.bp file.  The imported module type will exist for all
// modules after the import in the Android.bp file.
//
// Each soong_config_variable supports an additional value `conditions_default`. The properties
// specified in `conditions_default` will only be used under the following conditions:
//   bool variable: the variable is unspecified or not set to a true value
//   value variable: the variable is unspecified
//   list variable: the variable is unspecified
//   string variable: the variable is unspecified or the variable is set to a string unused in the
//                    given module. For example, string variable `test` takes values: "a" and "b",
//                    if the module contains a property `a` and `conditions_default`, when test=b,
//                    the properties under `conditions_default` will be used. To specify that no
//                    properties should be amended for `b`, you can set `b: {},`.
//
// For example, an Android.bp file could have:
//
//     soong_config_module_type_import {
//         from: "device/acme/Android.bp",
//         module_types: ["acme_cc_defaults"],
//     }
//
//     acme_cc_defaults {
//         name: "acme_defaults",
//         cflags: ["-DGENERIC"],
//         soong_config_variables: {
//             board: {
//                 soc_a: {
//                     cflags: ["-DSOC_A"],
//                 },
//                 soc_b: {
//                     cflags: ["-DSOC_B"],
//                 },
//                 conditions_default: {
//                     cflags: ["-DSOC_DEFAULT"],
//                 },
//             },
//             feature: {
//                 cflags: ["-DFEATURE"],
//                 conditions_default: {
//                     cflags: ["-DFEATURE_DEFAULT"],
//                 },
//             },
//             width: {
//                 cflags: ["-DWIDTH=%s"],
//                 conditions_default: {
//                     cflags: ["-DWIDTH=DEFAULT"],
//                 },
//             },
//             impl: {
//                 srcs: ["impl/%s"],
//                 conditions_default: {
//                     srcs: ["impl/default.cpp"],
//                 },
//             },
//         },
//     }
//
//     cc_library {
//         name: "libacme_foo",
//         defaults: ["acme_defaults"],
//         srcs: ["*.cpp"],
//     }
//
// And device/acme/Android.bp could have:
//
//     soong_config_module_type {
//         name: "acme_cc_defaults",
//         module_type: "cc_defaults",
//         config_namespace: "acme",
//         variables: ["board"],
//         bool_variables: ["feature"],
//         value_variables: ["width"],
//         list_variables: ["impl"],
//         properties: ["cflags", "srcs"],
//     }
//
//     soong_config_string_variable {
//         name: "board",
//         values: ["soc_a", "soc_b", "soc_c"],
//     }
//
// If an acme BoardConfig.mk file contained:
//     $(call add_sonng_config_namespace, acme)
//     $(call add_soong_config_var_value, acme, board, soc_a)
//     $(call add_soong_config_var_value, acme, feature, true)
//     $(call add_soong_config_var_value, acme, width, 200)
//     $(call add_soong_config_var_value, acme, impl, foo.cpp bar.cpp)
//
// Then libacme_foo would build with cflags "-DGENERIC -DSOC_A -DFEATURE -DWIDTH=200" and srcs
// ["*.cpp", "impl/foo.cpp", "impl/bar.cpp"].
//
// Alternatively, if acme BoardConfig.mk file contained:
//
//     SOONG_CONFIG_NAMESPACES += acme
//     SOONG_CONFIG_acme += \
//         board \
//         feature \
//
//     SOONG_CONFIG_acme_feature := false
//
// Then libacme_foo would build with cflags:
//   "-DGENERIC -DSOC_DEFAULT -DFEATURE_DEFAULT -DSIZE=DEFAULT"
// and with srcs:
//   ["*.cpp", "impl/default.cpp"].
//
// Similarly, if acme BoardConfig.mk file contained:
//
//     SOONG_CONFIG_NAMESPACES += acme
//     SOONG_CONFIG_acme += \
//         board \
//         feature \
//
//     SOONG_CONFIG_acme_board := soc_c
//     SOONG_CONFIG_acme_impl := foo.cpp bar.cpp
//
// Then libacme_foo would build with cflags:
//   "-DGENERIC -DSOC_DEFAULT -DFEATURE_DEFAULT -DSIZE=DEFAULT"
// and with srcs:
//   ["*.cpp", "impl/foo.cpp", "impl/bar.cpp"].
//

func SoongConfigModuleTypeImportFactory() Module {
	module := &soongConfigModuleTypeImport{}

	module.AddProperties(&module.properties)
	AddLoadHook(module, func(ctx LoadHookContext) {
		importModuleTypes(ctx, module.properties.From, module.properties.Module_types...)
	})

	initAndroidModuleBase(module)
	return module
}

func (m *soongConfigModuleTypeImport) Name() string {
	// The generated name is non-deterministic, but it does not
	// matter because this module does not emit any rules.
	return soongconfig.CanonicalizeToProperty(m.properties.From) +
		"soong_config_module_type_import_" + fmt.Sprintf("%p", m)
}

func (*soongConfigModuleTypeImport) Namespaceless()                            {}
func (*soongConfigModuleTypeImport) GenerateAndroidBuildActions(ModuleContext) {}

// Create dummy modules for soong_config_module_type and soong_config_*_variable

type soongConfigModuleTypeModule struct {
	ModuleBase
	properties soongconfig.ModuleTypeProperties
}

// soong_config_module_type defines module types with conditionals on Soong config
// variables.  The new module type will exist for all modules after the definition
// in an Android.bp file, and can be imported into other Android.bp files using
// soong_config_module_type_import.
//
// Each soong_config_variable supports an additional value `conditions_default`. The properties
// specified in `conditions_default` will only be used under the following conditions:
//
//	bool variable: the variable is unspecified or not set to a true value
//	value variable: the variable is unspecified
//	list variable: the variable is unspecified
//	string variable: the variable is unspecified or the variable is set to a string unused in the
//	                 given module. For example, string variable `test` takes values: "a" and "b",
//	                 if the module contains a property `a` and `conditions_default`, when test=b,
//	                 the properties under `conditions_default` will be used. To specify that no
//	                 properties should be amended for `b`, you can set `b: {},`.
//
// For example, an Android.bp file could have:
//
//	soong_config_module_type {
//	    name: "acme_cc_defaults",
//	    module_type: "cc_defaults",
//	    config_namespace: "acme",
//	    variables: ["board"],
//	    bool_variables: ["feature"],
//	    value_variables: ["width"],
//	    list_variables: ["impl"],
//	    properties: ["cflags", "srcs"],
//	}
//
//	soong_config_string_variable {
//	    name: "board",
//	    values: ["soc_a", "soc_b"],
//	}
//
//	acme_cc_defaults {
//	    name: "acme_defaults",
//	    cflags: ["-DGENERIC"],
//	    soong_config_variables: {
//	        board: {
//	            soc_a: {
//	                cflags: ["-DSOC_A"],
//	            },
//	            soc_b: {
//	                cflags: ["-DSOC_B"],
//	            },
//	            conditions_default: {
//	                cflags: ["-DSOC_DEFAULT"],
//	            },
//	        },
//	        feature: {
//	            cflags: ["-DFEATURE"],
//	            conditions_default: {
//	                cflags: ["-DFEATURE_DEFAULT"],
//	            },
//	        },
//	        width: {
//	            cflags: ["-DWIDTH=%s"],
//	            conditions_default: {
//	                cflags: ["-DWIDTH=DEFAULT"],
//	            },
//	        },
//	        impl: {
//	            srcs: ["impl/%s"],
//	            conditions_default: {
//	                srcs: ["impl/default.cpp"],
//	            },
//	        },
//	    },
//	}
//
//	cc_library {
//	    name: "libacme_foo",
//	    defaults: ["acme_defaults"],
//	    srcs: ["*.cpp"],
//	}
//
// If an acme BoardConfig.mk file contained:
//
//	SOONG_CONFIG_NAMESPACES += acme
//	SOONG_CONFIG_acme += \
//	    board \
//	    feature \
//
//	SOONG_CONFIG_acme_board := soc_a
//	SOONG_CONFIG_acme_feature := true
//	SOONG_CONFIG_acme_width := 200
//	SOONG_CONFIG_acme_impl := foo.cpp bar.cpp
//
// Then libacme_foo would build with cflags "-DGENERIC -DSOC_A -DFEATURE" and srcs
// ["*.cpp", "impl/foo.cpp", "impl/bar.cpp"].
func SoongConfigModuleTypeFactory() Module {
	module := &soongConfigModuleTypeModule{}

	module.AddProperties(&module.properties)

	AddLoadHook(module, func(ctx LoadHookContext) {
		// A soong_config_module_type module should implicitly import itself.
		importModuleTypes(ctx, ctx.BlueprintsFile(), module.properties.Name)
	})

	initAndroidModuleBase(module)

	return module
}

func (m *soongConfigModuleTypeModule) Name() string {
	return m.properties.Name + fmt.Sprintf("%p", m)
}
func (*soongConfigModuleTypeModule) Namespaceless()                                {}
func (*soongConfigModuleTypeModule) GenerateAndroidBuildActions(ctx ModuleContext) {}

type soongConfigStringVariableDummyModule struct {
	ModuleBase
	properties       soongconfig.VariableProperties
	stringProperties soongconfig.StringVariableProperties
}

type soongConfigBoolVariableDummyModule struct {
	ModuleBase
	properties soongconfig.VariableProperties
}

type soongConfigValueVariableDummyModule struct {
	ModuleBase
	properties soongconfig.VariableProperties
}

// soong_config_string_variable defines a variable and a set of possible string values for use
// in a soong_config_module_type definition.
func SoongConfigStringVariableDummyFactory() Module {
	module := &soongConfigStringVariableDummyModule{}
	module.AddProperties(&module.properties, &module.stringProperties)
	initAndroidModuleBase(module)
	return module
}

// soong_config_string_variable defines a variable with true or false values for use
// in a soong_config_module_type definition.
func SoongConfigBoolVariableDummyFactory() Module {
	module := &soongConfigBoolVariableDummyModule{}
	module.AddProperties(&module.properties)
	initAndroidModuleBase(module)
	return module
}

// soong_config_value_variable defines a variable whose value can be expanded into
// the value of a string property.
func SoongConfigValueVariableDummyFactory() Module {
	module := &soongConfigValueVariableDummyModule{}
	module.AddProperties(&module.properties)
	initAndroidModuleBase(module)
	return module
}

func (m *soongConfigStringVariableDummyModule) Name() string {
	return m.properties.Name + fmt.Sprintf("%p", m)
}
func (*soongConfigStringVariableDummyModule) Namespaceless()                                {}
func (*soongConfigStringVariableDummyModule) GenerateAndroidBuildActions(ctx ModuleContext) {}

func (m *soongConfigBoolVariableDummyModule) Name() string {
	return m.properties.Name + fmt.Sprintf("%p", m)
}
func (*soongConfigBoolVariableDummyModule) Namespaceless()                                {}
func (*soongConfigBoolVariableDummyModule) GenerateAndroidBuildActions(ctx ModuleContext) {}

func (m *soongConfigValueVariableDummyModule) Name() string {
	return m.properties.Name + fmt.Sprintf("%p", m)
}
func (*soongConfigValueVariableDummyModule) Namespaceless()                                {}
func (*soongConfigValueVariableDummyModule) GenerateAndroidBuildActions(ctx ModuleContext) {}

// importModuleTypes registers the module factories for a list of module types defined
// in an Android.bp file. These module factories are scoped for the current Android.bp
// file only.
func importModuleTypes(ctx LoadHookContext, from string, moduleTypes ...string) {
	from = filepath.Clean(from)
	if filepath.Ext(from) != ".bp" {
		ctx.PropertyErrorf("from", "%q must be a file with extension .bp", from)
		return
	}

	if strings.HasPrefix(from, "../") {
		ctx.PropertyErrorf("from", "%q must not use ../ to escape the source tree",
			from)
		return
	}

	moduleTypeDefinitions := loadSoongConfigModuleTypeDefinition(ctx, from)
	if moduleTypeDefinitions == nil {
		return
	}
	for _, moduleType := range moduleTypes {
		if factory, ok := moduleTypeDefinitions[moduleType]; ok {
			ctx.registerScopedModuleType(moduleType, factory)
		} else {
			ctx.PropertyErrorf("module_types", "module type %q not defined in %q",
				moduleType, from)
		}
	}
}

// loadSoongConfigModuleTypeDefinition loads module types from an Android.bp file.  It caches the
// result so each file is only parsed once.
func loadSoongConfigModuleTypeDefinition(ctx LoadHookContext, from string) map[string]blueprint.ModuleFactory {
	type onceKeyType string
	key := NewCustomOnceKey(onceKeyType(filepath.Clean(from)))

	reportErrors := func(ctx LoadHookContext, filename string, errs ...error) {
		for _, err := range errs {
			if parseErr, ok := err.(*parser.ParseError); ok {
				ctx.Errorf(parseErr.Pos, "%s", parseErr.Err)
			} else {
				ctx.Errorf(scanner.Position{Filename: filename}, "%s", err)
			}
		}
	}

	return ctx.Config().Once(key, func() interface{} {
		ctx.AddNinjaFileDeps(from)
		r, err := ctx.Config().fs.Open(from)
		if err != nil {
			ctx.PropertyErrorf("from", "failed to open %q: %s", from, err)
			return (map[string]blueprint.ModuleFactory)(nil)
		}
		defer r.Close()

		mtDef, errs := soongconfig.Parse(r, from)
		if len(errs) > 0 {
			reportErrors(ctx, from, errs...)
			return (map[string]blueprint.ModuleFactory)(nil)
		}

		globalModuleTypes := ctx.moduleFactories()

		factories := make(map[string]blueprint.ModuleFactory)

		for name, moduleType := range mtDef.ModuleTypes {
			factory := globalModuleTypes[moduleType.BaseModuleType]
			if factory != nil {
				factories[name] = configModuleFactory(factory, moduleType)
			} else {
				reportErrors(ctx, from,
					fmt.Errorf("missing global module type factory for %q", moduleType.BaseModuleType))
			}
		}

		if ctx.Failed() {
			return (map[string]blueprint.ModuleFactory)(nil)
		}

		return factories
	}).(map[string]blueprint.ModuleFactory)
}

// tracingConfig is a wrapper to soongconfig.SoongConfig which records all accesses to SoongConfig.
type tracingConfig struct {
	config    soongconfig.SoongConfig
	boolSet   map[string]bool
	stringSet map[string]string
	isSetSet  map[string]bool
}

func (c *tracingConfig) Bool(name string) bool {
	c.boolSet[name] = c.config.Bool(name)
	return c.boolSet[name]
}

func (c *tracingConfig) String(name string) string {
	c.stringSet[name] = c.config.String(name)
	return c.stringSet[name]
}

func (c *tracingConfig) IsSet(name string) bool {
	c.isSetSet[name] = c.config.IsSet(name)
	return c.isSetSet[name]
}

func (c *tracingConfig) getTrace() soongConfigTrace {
	ret := soongConfigTrace{}

	for k, v := range c.boolSet {
		ret.Bools = append(ret.Bools, fmt.Sprintf("%q:%t", k, v))
	}
	for k, v := range c.stringSet {
		ret.Strings = append(ret.Strings, fmt.Sprintf("%q:%q", k, v))
	}
	for k, v := range c.isSetSet {
		ret.IsSets = append(ret.IsSets, fmt.Sprintf("%q:%t", k, v))
	}

	return ret
}

func newTracingConfig(config soongconfig.SoongConfig) *tracingConfig {
	c := tracingConfig{
		config:    config,
		boolSet:   make(map[string]bool),
		stringSet: make(map[string]string),
		isSetSet:  make(map[string]bool),
	}
	return &c
}

var _ soongconfig.SoongConfig = (*tracingConfig)(nil)

// configModuleFactory takes an existing soongConfigModuleFactory and a
// ModuleType to create a new ModuleFactory that uses a custom loadhook.
func configModuleFactory(factory blueprint.ModuleFactory, moduleType *soongconfig.ModuleType) blueprint.ModuleFactory {
	// Defer creation of conditional properties struct until the first call from the factory
	// method. That avoids having to make a special call to the factory to create the properties
	// structs from which the conditional properties struct is created. This is needed in order to
	// allow singleton modules to be customized by soong_config_module_type as the
	// SingletonModuleFactoryAdaptor factory registers a load hook for the singleton module
	// everytime that it is called. Calling the factory twice causes a build failure as the load
	// hook is called twice, the first time it updates the singleton module to indicate that it has
	// been registered as a module, and the second time it fails because it thinks it has been
	// registered again and a singleton module can only be registered once.
	//
	// This is an issue for singleton modules because:
	// * Load hooks are registered on the module object and are only called when the module object
	//   is created by Blueprint while processing the Android.bp file.
	// * The module factory for a singleton module returns the same module object each time it is
	//   called, and registers its load hook on that same module object.
	// * When the module factory is called by Blueprint it then calls all the load hooks that have
	//   been registered for every call to that module factory.
	//
	// It is not an issue for normal modules because they return a new module object each time the
	// factory is called and so any load hooks registered on module objects which are discarded will
	// not be run.
	once := &sync.Once{}
	conditionalFactoryProps := reflect.Value{}
	getConditionalFactoryProps := func(props []interface{}) reflect.Value {
		once.Do(func() {
			conditionalFactoryProps = soongconfig.CreateProperties(props, moduleType)
		})
		return conditionalFactoryProps
	}

	return func() (blueprint.Module, []interface{}) {
		module, props := factory()
		conditionalFactoryProps := getConditionalFactoryProps(props)
		if !conditionalFactoryProps.IsValid() {
			return module, props
		}

		conditionalProps := proptools.CloneEmptyProperties(conditionalFactoryProps)
		props = append(props, conditionalProps.Interface())

		// Regular Soong operation wraps the existing module factory with a
		// conditional on Soong config variables by reading the product
		// config variables from Make.
		AddLoadHook(module, func(ctx LoadHookContext) {
			tracingConfig := newTracingConfig(ctx.Config().VendorConfig(moduleType.ConfigNamespace))
			newProps, err := soongconfig.PropertiesToApply(moduleType, conditionalProps, tracingConfig)
			if err != nil {
				ctx.ModuleErrorf("%s", err)
				return
			}
			for _, ps := range newProps {
				ctx.AppendProperties(ps)
			}

			module.(Module).base().commonProperties.SoongConfigTrace = tracingConfig.getTrace()
		})
		return module, props
	}
}
