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

import (
	"testing"
)

type soongConfigTestDefaultsModuleProperties struct {
}

type soongConfigTestDefaultsModule struct {
	ModuleBase
	DefaultsModuleBase
}

func soongConfigTestDefaultsModuleFactory() Module {
	m := &soongConfigTestDefaultsModule{}
	m.AddProperties(&soongConfigTestModuleProperties{})
	InitDefaultsModule(m)
	return m
}

type soongConfigTestModule struct {
	ModuleBase
	DefaultableModuleBase
	props soongConfigTestModuleProperties
}

type soongConfigTestModuleProperties struct {
	Cflags []string
}

func soongConfigTestModuleFactory() Module {
	m := &soongConfigTestModule{}
	m.AddProperties(&m.props)
	InitAndroidModule(m)
	InitDefaultableModule(m)
	return m
}

func (t soongConfigTestModule) GenerateAndroidBuildActions(ModuleContext) {}

func TestSoongConfigModule(t *testing.T) {
	configBp := `
		soong_config_module_type {
			name: "acme_test",
			module_type: "test",
			config_namespace: "acme",
			variables: ["board", "feature1", "FEATURE3", "unused_string_var"],
			bool_variables: ["feature2", "unused_feature", "always_true"],
			value_variables: ["size", "unused_size"],
			properties: ["cflags", "srcs", "defaults"],
		}

		soong_config_string_variable {
			name: "board",
			values: ["soc_a", "soc_b", "soc_c", "soc_d"],
		}

		soong_config_string_variable {
			name: "unused_string_var",
			values: ["a", "b"],
		}

		soong_config_bool_variable {
			name: "feature1",
		}

		soong_config_bool_variable {
			name: "FEATURE3",
		}
	`

	importBp := `
		soong_config_module_type_import {
			from: "SoongConfig.bp",
			module_types: ["acme_test"],
		}
	`

	bp := `
		test_defaults {
			name: "foo_defaults",
			cflags: ["DEFAULT"],
		}

		acme_test {
			name: "foo",
			cflags: ["-DGENERIC"],
			defaults: ["foo_defaults"],
			soong_config_variables: {
				board: {
					soc_a: {
						cflags: ["-DSOC_A"],
					},
					soc_b: {
						cflags: ["-DSOC_B"],
					},
					soc_c: {},
					conditions_default: {
						cflags: ["-DSOC_CONDITIONS_DEFAULT"],
					},
				},
				size: {
					cflags: ["-DSIZE=%s"],
					conditions_default: {
						cflags: ["-DSIZE=CONDITIONS_DEFAULT"],
					},
				},
				feature1: {
					  conditions_default: {
						  cflags: ["-DF1_CONDITIONS_DEFAULT"],
					  },
					cflags: ["-DFEATURE1"],
				},
				feature2: {
					cflags: ["-DFEATURE2"],
					 conditions_default: {
						 cflags: ["-DF2_CONDITIONS_DEFAULT"],
					 },
				},
				FEATURE3: {
					cflags: ["-DFEATURE3"],
				},
			},
		}

		test_defaults {
			name: "foo_defaults_a",
			cflags: ["DEFAULT_A"],
		}

		test_defaults {
			name: "foo_defaults_b",
			cflags: ["DEFAULT_B"],
		}

		test_defaults {
			name: "foo_defaults_always_true",
			cflags: ["DEFAULT_ALWAYS_TRUE"],
		}

		acme_test {
			name: "foo_with_defaults",
			cflags: ["-DGENERIC"],
			defaults: ["foo_defaults"],
			soong_config_variables: {
				board: {
					soc_a: {
						cflags: ["-DSOC_A"],
						defaults: ["foo_defaults_a"],
					},
					soc_b: {
						cflags: ["-DSOC_B"],
						defaults: ["foo_defaults_b"],
					},
					soc_c: {},
				},
				size: {
					cflags: ["-DSIZE=%s"],
				},
				feature1: {
					cflags: ["-DFEATURE1"],
				},
				feature2: {
					cflags: ["-DFEATURE2"],
				},
				FEATURE3: {
					cflags: ["-DFEATURE3"],
				},
				always_true: {
					defaults: ["foo_defaults_always_true"],
					conditions_default: {
						// verify that conditions_default is skipped if the
						// soong config variable is true by specifying a
						// non-existent module in conditions_default
						defaults: ["//nonexistent:defaults"],
					}
				},
			},
		}
    `

	fixtureForVendorVars := func(vars map[string]map[string]string) FixturePreparer {
		return FixtureModifyProductVariables(func(variables FixtureProductVariables) {
			variables.VendorVars = vars
		})
	}

	run := func(t *testing.T, bp string, fs MockFS) {
		testCases := []struct {
			name                     string
			preparer                 FixturePreparer
			fooExpectedFlags         []string
			fooDefaultsExpectedFlags []string
		}{
			{
				name: "withValues",
				preparer: fixtureForVendorVars(map[string]map[string]string{
					"acme": {
						"board":    "soc_a",
						"size":     "42",
						"feature1": "true",
						"feature2": "false",
						// FEATURE3 unset
						"unused_feature":    "true", // unused
						"unused_size":       "1",    // unused
						"unused_string_var": "a",    // unused
						"always_true":       "true",
					},
				}),
				fooExpectedFlags: []string{
					"DEFAULT",
					"-DGENERIC",
					"-DF2_CONDITIONS_DEFAULT",
					"-DSIZE=42",
					"-DSOC_A",
					"-DFEATURE1",
				},
				fooDefaultsExpectedFlags: []string{
					"DEFAULT_A",
					"DEFAULT_ALWAYS_TRUE",
					"DEFAULT",
					"-DGENERIC",
					"-DSIZE=42",
					"-DSOC_A",
					"-DFEATURE1",
				},
			},
			{
				name: "empty_prop_for_string_var",
				preparer: fixtureForVendorVars(map[string]map[string]string{
					"acme": {
						"board":       "soc_c",
						"always_true": "true",
					}}),
				fooExpectedFlags: []string{
					"DEFAULT",
					"-DGENERIC",
					"-DF2_CONDITIONS_DEFAULT",
					"-DSIZE=CONDITIONS_DEFAULT",
					"-DF1_CONDITIONS_DEFAULT",
				},
				fooDefaultsExpectedFlags: []string{
					"DEFAULT_ALWAYS_TRUE",
					"DEFAULT",
					"-DGENERIC",
				},
			},
			{
				name: "unused_string_var",
				preparer: fixtureForVendorVars(map[string]map[string]string{
					"acme": {
						"board":       "soc_d",
						"always_true": "true",
					}}),
				fooExpectedFlags: []string{
					"DEFAULT",
					"-DGENERIC",
					"-DF2_CONDITIONS_DEFAULT",
					"-DSIZE=CONDITIONS_DEFAULT",
					"-DSOC_CONDITIONS_DEFAULT", // foo does not contain a prop "soc_d", so we use the default
					"-DF1_CONDITIONS_DEFAULT",
				},
				fooDefaultsExpectedFlags: []string{
					"DEFAULT_ALWAYS_TRUE",
					"DEFAULT",
					"-DGENERIC",
				},
			},

			{
				name: "conditions_default",
				preparer: fixtureForVendorVars(map[string]map[string]string{
					"acme": {
						"always_true": "true",
					}}),
				fooExpectedFlags: []string{
					"DEFAULT",
					"-DGENERIC",
					"-DF2_CONDITIONS_DEFAULT",
					"-DSIZE=CONDITIONS_DEFAULT",
					"-DSOC_CONDITIONS_DEFAULT",
					"-DF1_CONDITIONS_DEFAULT",
				},
				fooDefaultsExpectedFlags: []string{
					"DEFAULT_ALWAYS_TRUE",
					"DEFAULT",
					"-DGENERIC",
				},
			},
		}

		for _, tc := range testCases {
			t.Run(tc.name, func(t *testing.T) {
				result := GroupFixturePreparers(
					tc.preparer,
					PrepareForTestWithDefaults,
					FixtureRegisterWithContext(func(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("test_defaults", soongConfigTestDefaultsModuleFactory)
						ctx.RegisterModuleType("test", soongConfigTestModuleFactory)
					}),
					fs.AddToFixture(),
					FixtureWithRootAndroidBp(bp),
				).RunTest(t)

				foo := result.ModuleForTests("foo", "").Module().(*soongConfigTestModule)
				AssertDeepEquals(t, "foo cflags", tc.fooExpectedFlags, foo.props.Cflags)

				fooDefaults := result.ModuleForTests("foo_with_defaults", "").Module().(*soongConfigTestModule)
				AssertDeepEquals(t, "foo_with_defaults cflags", tc.fooDefaultsExpectedFlags, fooDefaults.props.Cflags)
			})
		}
	}

	t.Run("single file", func(t *testing.T) {
		run(t, configBp+bp, nil)
	})

	t.Run("import", func(t *testing.T) {
		run(t, importBp+bp, map[string][]byte{
			"SoongConfig.bp": []byte(configBp),
		})
	})
}

func TestNonExistentPropertyInSoongConfigModule(t *testing.T) {
	bp := `
		soong_config_module_type {
			name: "acme_test",
			module_type: "test",
			config_namespace: "acme",
			bool_variables: ["feature1"],
			properties: ["made_up_property"],
		}

		acme_test {
			name: "foo",
			cflags: ["-DGENERIC"],
			soong_config_variables: {
				feature1: {
					made_up_property: true,
				},
			},
		}
    `

	fixtureForVendorVars := func(vars map[string]map[string]string) FixturePreparer {
		return FixtureModifyProductVariables(func(variables FixtureProductVariables) {
			variables.VendorVars = vars
		})
	}

	GroupFixturePreparers(
		fixtureForVendorVars(map[string]map[string]string{"acme": {"feature1": "1"}}),
		PrepareForTestWithDefaults,
		FixtureRegisterWithContext(func(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("test_defaults", soongConfigTestDefaultsModuleFactory)
			ctx.RegisterModuleType("test", soongConfigTestModuleFactory)
		}),
		FixtureWithRootAndroidBp(bp),
	).ExtendWithErrorHandler(FixtureExpectsAllErrorsToMatchAPattern([]string{
		// TODO(b/171232169): improve the error message for non-existent properties
		`unrecognized property "soong_config_variables`,
	})).RunTest(t)
}

func TestDuplicateStringValueInSoongConfigStringVariable(t *testing.T) {
	bp := `
		soong_config_string_variable {
			name: "board",
			values: ["soc_a", "soc_b", "soc_c", "soc_a"],
		}

		soong_config_module_type {
			name: "acme_test",
			module_type: "test",
			config_namespace: "acme",
			variables: ["board"],
			properties: ["cflags", "srcs", "defaults"],
		}
    `

	fixtureForVendorVars := func(vars map[string]map[string]string) FixturePreparer {
		return FixtureModifyProductVariables(func(variables FixtureProductVariables) {
			variables.VendorVars = vars
		})
	}

	GroupFixturePreparers(
		fixtureForVendorVars(map[string]map[string]string{"acme": {"feature1": "1"}}),
		PrepareForTestWithDefaults,
		FixtureRegisterWithContext(func(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("test_defaults", soongConfigTestDefaultsModuleFactory)
			ctx.RegisterModuleType("test", soongConfigTestModuleFactory)
		}),
		FixtureWithRootAndroidBp(bp),
	).ExtendWithErrorHandler(FixtureExpectsAllErrorsToMatchAPattern([]string{
		// TODO(b/171232169): improve the error message for non-existent properties
		`Android.bp: soong_config_string_variable: values property error: duplicate value: "soc_a"`,
	})).RunTest(t)
}

func testConfigWithVendorVars(buildDir, bp string, fs map[string][]byte, vendorVars map[string]map[string]string) Config {
	config := TestConfig(buildDir, nil, bp, fs)

	config.TestProductVariables.VendorVars = vendorVars

	return config
}
