// Copyright 2015 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 (
	"bytes"
	"path/filepath"
	"runtime"
	"testing"

	mkparser "android/soong/androidmk/parser"
)

func TestSrcIsModule(t *testing.T) {
	type args struct {
		s string
	}
	tests := []struct {
		name       string
		args       args
		wantModule string
	}{
		{
			name: "file",
			args: args{
				s: "foo",
			},
			wantModule: "",
		},
		{
			name: "module",
			args: args{
				s: ":foo",
			},
			wantModule: "foo",
		},
		{
			name: "tag",
			args: args{
				s: ":foo{.bar}",
			},
			wantModule: "foo{.bar}",
		},
		{
			name: "extra colon",
			args: args{
				s: ":foo:bar",
			},
			wantModule: "foo:bar",
		},
		{
			name: "fully qualified",
			args: args{
				s: "//foo:bar",
			},
			wantModule: "//foo:bar",
		},
		{
			name: "fully qualified with tag",
			args: args{
				s: "//foo:bar{.tag}",
			},
			wantModule: "//foo:bar{.tag}",
		},
		{
			name: "invalid unqualified name",
			args: args{
				s: ":foo/bar",
			},
			wantModule: "",
		},
	}
	for _, tt := range tests {
		t.Run(tt.name, func(t *testing.T) {
			if gotModule := SrcIsModule(tt.args.s); gotModule != tt.wantModule {
				t.Errorf("SrcIsModule() = %v, want %v", gotModule, tt.wantModule)
			}
		})
	}
}

func TestSrcIsModuleWithTag(t *testing.T) {
	type args struct {
		s string
	}
	tests := []struct {
		name       string
		args       args
		wantModule string
		wantTag    string
	}{
		{
			name: "file",
			args: args{
				s: "foo",
			},
			wantModule: "",
			wantTag:    "",
		},
		{
			name: "module",
			args: args{
				s: ":foo",
			},
			wantModule: "foo",
			wantTag:    "",
		},
		{
			name: "tag",
			args: args{
				s: ":foo{.bar}",
			},
			wantModule: "foo",
			wantTag:    ".bar",
		},
		{
			name: "empty tag",
			args: args{
				s: ":foo{}",
			},
			wantModule: "foo",
			wantTag:    "",
		},
		{
			name: "extra colon",
			args: args{
				s: ":foo:bar",
			},
			wantModule: "foo:bar",
		},
		{
			name: "invalid tag",
			args: args{
				s: ":foo{.bar",
			},
			wantModule: "foo{.bar",
		},
		{
			name: "invalid tag 2",
			args: args{
				s: ":foo.bar}",
			},
			wantModule: "foo.bar}",
		},
		{
			name: "fully qualified",
			args: args{
				s: "//foo:bar",
			},
			wantModule: "//foo:bar",
		},
		{
			name: "fully qualified with tag",
			args: args{
				s: "//foo:bar{.tag}",
			},
			wantModule: "//foo:bar",
			wantTag:    ".tag",
		},
		{
			name: "invalid unqualified name",
			args: args{
				s: ":foo/bar",
			},
			wantModule: "",
		},
		{
			name: "invalid unqualified name with tag",
			args: args{
				s: ":foo/bar{.tag}",
			},
			wantModule: "",
		},
	}
	for _, tt := range tests {
		t.Run(tt.name, func(t *testing.T) {
			gotModule, gotTag := SrcIsModuleWithTag(tt.args.s)
			if gotModule != tt.wantModule {
				t.Errorf("SrcIsModuleWithTag() gotModule = %v, want %v", gotModule, tt.wantModule)
			}
			if gotTag != tt.wantTag {
				t.Errorf("SrcIsModuleWithTag() gotTag = %v, want %v", gotTag, tt.wantTag)
			}
		})
	}
}

type depsModule struct {
	ModuleBase
	props struct {
		Deps []string
	}
}

func (m *depsModule) GenerateAndroidBuildActions(ctx ModuleContext) {
	outputFile := PathForModuleOut(ctx, ctx.ModuleName())
	ctx.Build(pctx, BuildParams{
		Rule:   Touch,
		Output: outputFile,
	})
	installFile := ctx.InstallFile(PathForModuleInstall(ctx), ctx.ModuleName(), outputFile)
	ctx.InstallSymlink(PathForModuleInstall(ctx, "symlinks"), ctx.ModuleName(), installFile)
}

func (m *depsModule) DepsMutator(ctx BottomUpMutatorContext) {
	ctx.AddDependency(ctx.Module(), installDepTag{}, m.props.Deps...)
}

func depsModuleFactory() Module {
	m := &depsModule{}
	m.AddProperties(&m.props)
	InitAndroidArchModule(m, HostAndDeviceDefault, MultilibCommon)
	return m
}

var prepareForModuleTests = FixtureRegisterWithContext(func(ctx RegistrationContext) {
	ctx.RegisterModuleType("deps", depsModuleFactory)
})

func TestErrorDependsOnDisabledModule(t *testing.T) {
	bp := `
		deps {
			name: "foo",
			deps: ["bar"],
		}
		deps {
			name: "bar",
			enabled: false,
		}
	`

	prepareForModuleTests.
		ExtendWithErrorHandler(FixtureExpectsAtLeastOneErrorMatchingPattern(`module "foo": depends on disabled module "bar"`)).
		RunTestWithBp(t, bp)
}

func TestValidateCorrectBuildParams(t *testing.T) {
	config := TestConfig(t.TempDir(), nil, "", nil)
	pathContext := PathContextForTesting(config)
	bparams := convertBuildParams(BuildParams{
		// Test with Output
		Output:        PathForOutput(pathContext, "undeclared_symlink"),
		SymlinkOutput: PathForOutput(pathContext, "undeclared_symlink"),
	})

	err := validateBuildParams(bparams)
	if err != nil {
		t.Error(err)
	}

	bparams = convertBuildParams(BuildParams{
		// Test with ImplicitOutput
		ImplicitOutput: PathForOutput(pathContext, "undeclared_symlink"),
		SymlinkOutput:  PathForOutput(pathContext, "undeclared_symlink"),
	})

	err = validateBuildParams(bparams)
	if err != nil {
		t.Error(err)
	}
}

func TestValidateIncorrectBuildParams(t *testing.T) {
	config := TestConfig(t.TempDir(), nil, "", nil)
	pathContext := PathContextForTesting(config)
	params := BuildParams{
		Output:          PathForOutput(pathContext, "regular_output"),
		Outputs:         PathsForOutput(pathContext, []string{"out1", "out2"}),
		ImplicitOutput:  PathForOutput(pathContext, "implicit_output"),
		ImplicitOutputs: PathsForOutput(pathContext, []string{"i_out1", "_out2"}),
		SymlinkOutput:   PathForOutput(pathContext, "undeclared_symlink"),
	}

	bparams := convertBuildParams(params)
	err := validateBuildParams(bparams)
	if err != nil {
		FailIfNoMatchingErrors(t, "undeclared_symlink is not a declared output or implicit output", []error{err})
	} else {
		t.Errorf("Expected build params to fail validation: %+v", bparams)
	}
}

func TestDistErrorChecking(t *testing.T) {
	bp := `
		deps {
			name: "foo",
      dist: {
        dest: "../invalid-dest",
        dir: "../invalid-dir",
        suffix: "invalid/suffix",
      },
      dists: [
        {
          dest: "../invalid-dest0",
          dir: "../invalid-dir0",
          suffix: "invalid/suffix0",
        },
        {
          dest: "../invalid-dest1",
          dir: "../invalid-dir1",
          suffix: "invalid/suffix1",
        },
      ],
 		}
	`

	expectedErrs := []string{
		"\\QAndroid.bp:5:13: module \"foo\": dist.dest: Path is outside directory: ../invalid-dest\\E",
		"\\QAndroid.bp:6:12: module \"foo\": dist.dir: Path is outside directory: ../invalid-dir\\E",
		"\\QAndroid.bp:7:15: module \"foo\": dist.suffix: Suffix may not contain a '/' character.\\E",
		"\\QAndroid.bp:11:15: module \"foo\": dists[0].dest: Path is outside directory: ../invalid-dest0\\E",
		"\\QAndroid.bp:12:14: module \"foo\": dists[0].dir: Path is outside directory: ../invalid-dir0\\E",
		"\\QAndroid.bp:13:17: module \"foo\": dists[0].suffix: Suffix may not contain a '/' character.\\E",
		"\\QAndroid.bp:16:15: module \"foo\": dists[1].dest: Path is outside directory: ../invalid-dest1\\E",
		"\\QAndroid.bp:17:14: module \"foo\": dists[1].dir: Path is outside directory: ../invalid-dir1\\E",
		"\\QAndroid.bp:18:17: module \"foo\": dists[1].suffix: Suffix may not contain a '/' character.\\E",
	}

	prepareForModuleTests.
		ExtendWithErrorHandler(FixtureExpectsAllErrorsToMatchAPattern(expectedErrs)).
		RunTestWithBp(t, bp)
}

func TestInstall(t *testing.T) {
	if runtime.GOOS != "linux" {
		t.Skip("requires linux")
	}
	bp := `
		deps {
			name: "foo",
			deps: ["bar"],
		}

		deps {
			name: "bar",
			deps: ["baz", "qux"],
		}

		deps {
			name: "baz",
			deps: ["qux"],
		}

		deps {
			name: "qux",
		}
	`

	result := GroupFixturePreparers(
		prepareForModuleTests,
		PrepareForTestWithArchMutator,
	).RunTestWithBp(t, bp)

	module := func(name string, host bool) TestingModule {
		variant := "android_common"
		if host {
			variant = result.Config.BuildOSCommonTarget.String()
		}
		return result.ModuleForTests(name, variant)
	}

	outputRule := func(name string) TestingBuildParams { return module(name, false).Output(name) }

	installRule := func(name string) TestingBuildParams {
		return module(name, false).Output(filepath.Join("out/soong/target/product/test_device/system", name))
	}

	symlinkRule := func(name string) TestingBuildParams {
		return module(name, false).Output(filepath.Join("out/soong/target/product/test_device/system/symlinks", name))
	}

	hostOutputRule := func(name string) TestingBuildParams { return module(name, true).Output(name) }

	hostInstallRule := func(name string) TestingBuildParams {
		return module(name, true).Output(filepath.Join("out/soong/host/linux-x86", name))
	}

	hostSymlinkRule := func(name string) TestingBuildParams {
		return module(name, true).Output(filepath.Join("out/soong/host/linux-x86/symlinks", name))
	}

	assertInputs := func(params TestingBuildParams, inputs ...Path) {
		t.Helper()
		AssertArrayString(t, "expected inputs", Paths(inputs).Strings(),
			append(PathsIfNonNil(params.Input), params.Inputs...).Strings())
	}

	assertImplicits := func(params TestingBuildParams, implicits ...Path) {
		t.Helper()
		AssertArrayString(t, "expected implicit dependencies", Paths(implicits).Strings(),
			append(PathsIfNonNil(params.Implicit), params.Implicits...).Strings())
	}

	assertOrderOnlys := func(params TestingBuildParams, orderonlys ...Path) {
		t.Helper()
		AssertArrayString(t, "expected orderonly dependencies", Paths(orderonlys).Strings(),
			params.OrderOnly.Strings())
	}

	// Check host install rule dependencies
	assertInputs(hostInstallRule("foo"), hostOutputRule("foo").Output)
	assertImplicits(hostInstallRule("foo"),
		hostInstallRule("bar").Output,
		hostSymlinkRule("bar").Output,
		hostInstallRule("baz").Output,
		hostSymlinkRule("baz").Output,
		hostInstallRule("qux").Output,
		hostSymlinkRule("qux").Output,
	)
	assertOrderOnlys(hostInstallRule("foo"))

	// Check host symlink rule dependencies.  Host symlinks must use a normal dependency, not an
	// order-only dependency, so that the tool gets updated when the symlink is depended on.
	assertInputs(hostSymlinkRule("foo"), hostInstallRule("foo").Output)
	assertImplicits(hostSymlinkRule("foo"))
	assertOrderOnlys(hostSymlinkRule("foo"))

	// Check device install rule dependencies
	assertInputs(installRule("foo"), outputRule("foo").Output)
	assertImplicits(installRule("foo"))
	assertOrderOnlys(installRule("foo"),
		installRule("bar").Output,
		symlinkRule("bar").Output,
		installRule("baz").Output,
		symlinkRule("baz").Output,
		installRule("qux").Output,
		symlinkRule("qux").Output,
	)

	// Check device symlink rule dependencies.  Device symlinks could use an order-only dependency,
	// but the current implementation uses a normal dependency.
	assertInputs(symlinkRule("foo"), installRule("foo").Output)
	assertImplicits(symlinkRule("foo"))
	assertOrderOnlys(symlinkRule("foo"))
}

func TestInstallKatiEnabled(t *testing.T) {
	if runtime.GOOS != "linux" {
		t.Skip("requires linux")
	}
	bp := `
		deps {
			name: "foo",
			deps: ["bar"],
		}

		deps {
			name: "bar",
			deps: ["baz", "qux"],
		}

		deps {
			name: "baz",
			deps: ["qux"],
		}

		deps {
			name: "qux",
		}
	`

	result := GroupFixturePreparers(
		prepareForModuleTests,
		PrepareForTestWithArchMutator,
		FixtureModifyConfig(SetKatiEnabledForTests),
		FixtureRegisterWithContext(func(ctx RegistrationContext) {
			ctx.RegisterSingletonType("makevars", makeVarsSingletonFunc)
		}),
	).RunTestWithBp(t, bp)

	installs := result.SingletonForTests("makevars").Singleton().(*makeVarsSingleton).installsForTesting
	buf := bytes.NewBuffer(append([]byte(nil), installs...))
	parser := mkparser.NewParser("makevars", buf)

	nodes, errs := parser.Parse()
	if len(errs) > 0 {
		t.Fatalf("error parsing install rules: %s", errs[0])
	}

	rules := parseMkRules(t, result.Config, nodes)

	module := func(name string, host bool) TestingModule {
		variant := "android_common"
		if host {
			variant = result.Config.BuildOSCommonTarget.String()
		}
		return result.ModuleForTests(name, variant)
	}

	outputRule := func(name string) TestingBuildParams { return module(name, false).Output(name) }

	ruleForOutput := func(output string) installMakeRule {
		for _, rule := range rules {
			if rule.target == output {
				return rule
			}
		}
		t.Fatalf("no make install rule for %s", output)
		return installMakeRule{}
	}

	installRule := func(name string) installMakeRule {
		return ruleForOutput(filepath.Join("out/target/product/test_device/system", name))
	}

	symlinkRule := func(name string) installMakeRule {
		return ruleForOutput(filepath.Join("out/target/product/test_device/system/symlinks", name))
	}

	hostOutputRule := func(name string) TestingBuildParams { return module(name, true).Output(name) }

	hostInstallRule := func(name string) installMakeRule {
		return ruleForOutput(filepath.Join("out/host/linux-x86", name))
	}

	hostSymlinkRule := func(name string) installMakeRule {
		return ruleForOutput(filepath.Join("out/host/linux-x86/symlinks", name))
	}

	assertDeps := func(rule installMakeRule, deps ...string) {
		t.Helper()
		AssertArrayString(t, "expected inputs", deps, rule.deps)
	}

	assertOrderOnlys := func(rule installMakeRule, orderonlys ...string) {
		t.Helper()
		AssertArrayString(t, "expected orderonly dependencies", orderonlys, rule.orderOnlyDeps)
	}

	// Check host install rule dependencies
	assertDeps(hostInstallRule("foo"),
		hostOutputRule("foo").Output.String(),
		hostInstallRule("bar").target,
		hostSymlinkRule("bar").target,
		hostInstallRule("baz").target,
		hostSymlinkRule("baz").target,
		hostInstallRule("qux").target,
		hostSymlinkRule("qux").target,
	)
	assertOrderOnlys(hostInstallRule("foo"))

	// Check host symlink rule dependencies.  Host symlinks must use a normal dependency, not an
	// order-only dependency, so that the tool gets updated when the symlink is depended on.
	assertDeps(hostSymlinkRule("foo"), hostInstallRule("foo").target)
	assertOrderOnlys(hostSymlinkRule("foo"))

	// Check device install rule dependencies
	assertDeps(installRule("foo"), outputRule("foo").Output.String())
	assertOrderOnlys(installRule("foo"),
		installRule("bar").target,
		symlinkRule("bar").target,
		installRule("baz").target,
		symlinkRule("baz").target,
		installRule("qux").target,
		symlinkRule("qux").target,
	)

	// Check device symlink rule dependencies.  Device symlinks could use an order-only dependency,
	// but the current implementation uses a normal dependency.
	assertDeps(symlinkRule("foo"), installRule("foo").target)
	assertOrderOnlys(symlinkRule("foo"))
}

type installMakeRule struct {
	target        string
	deps          []string
	orderOnlyDeps []string
}

func parseMkRules(t *testing.T, config Config, nodes []mkparser.Node) []installMakeRule {
	var rules []installMakeRule
	for _, node := range nodes {
		if mkParserRule, ok := node.(*mkparser.Rule); ok {
			var rule installMakeRule

			if targets := mkParserRule.Target.Words(); len(targets) == 0 {
				t.Fatalf("no targets for rule %s", mkParserRule.Dump())
			} else if len(targets) > 1 {
				t.Fatalf("unsupported multiple targets for rule %s", mkParserRule.Dump())
			} else if !targets[0].Const() {
				t.Fatalf("unsupported non-const target for rule %s", mkParserRule.Dump())
			} else {
				rule.target = normalizeStringRelativeToTop(config, targets[0].Value(nil))
			}

			prereqList := &rule.deps
			for _, prereq := range mkParserRule.Prerequisites.Words() {
				if !prereq.Const() {
					t.Fatalf("unsupported non-const prerequisite for rule %s", mkParserRule.Dump())
				}

				if prereq.Value(nil) == "|" {
					prereqList = &rule.orderOnlyDeps
					continue
				}

				*prereqList = append(*prereqList, normalizeStringRelativeToTop(config, prereq.Value(nil)))
			}

			rules = append(rules, rule)
		}
	}

	return rules
}

type PropsTestModuleEmbedded struct {
	Embedded_prop *string
}

type propsTestModule struct {
	ModuleBase
	DefaultableModuleBase
	props struct {
		A string `android:"arch_variant"`
		B *bool
		C []string
	}
	otherProps struct {
		PropsTestModuleEmbedded

		D      *int64
		Nested struct {
			E *string
		}
		F *string `blueprint:"mutated"`
	}
}

func propsTestModuleFactory() Module {
	module := &propsTestModule{}
	module.AddProperties(&module.props, &module.otherProps)
	InitAndroidArchModule(module, HostAndDeviceSupported, MultilibBoth)
	InitDefaultableModule(module)
	return module
}

type propsTestModuleDefaults struct {
	ModuleBase
	DefaultsModuleBase
}

func propsTestModuleDefaultsFactory() Module {
	defaults := &propsTestModuleDefaults{}
	module := propsTestModule{}
	defaults.AddProperties(&module.props, &module.otherProps)
	InitDefaultsModule(defaults)
	return defaults
}

func (p *propsTestModule) GenerateAndroidBuildActions(ctx ModuleContext) {
	str := "abc"
	p.otherProps.F = &str
}

func TestUsedProperties(t *testing.T) {
	testCases := []struct {
		desc          string
		bp            string
		expectedProps []propInfo
	}{
		{
			desc: "only name",
			bp: `test {
			name: "foo",
		}
	`,
			expectedProps: []propInfo{
				propInfo{"Name", "string"},
			},
		},
		{
			desc: "some props",
			bp: `test {
			name: "foo",
			a: "abc",
			b: true,
			d: 123,
		}
	`,
			expectedProps: []propInfo{
				propInfo{"A", "string"},
				propInfo{"B", "bool"},
				propInfo{"D", "int64"},
				propInfo{"Name", "string"},
			},
		},
		{
			desc: "unused non-pointer prop",
			bp: `test {
			name: "foo",
			b: true,
			d: 123,
		}
	`,
			expectedProps: []propInfo{
				// for non-pointer cannot distinguish between unused and intentionally set to empty
				propInfo{"A", "string"},
				propInfo{"B", "bool"},
				propInfo{"D", "int64"},
				propInfo{"Name", "string"},
			},
		},
		{
			desc: "nested props",
			bp: `test {
			name: "foo",
			nested: {
				e: "abc",
			}
		}
	`,
			expectedProps: []propInfo{
				propInfo{"Nested.E", "string"},
				propInfo{"Name", "string"},
			},
		},
		{
			desc: "arch props",
			bp: `test {
			name: "foo",
			arch: {
				x86_64: {
					a: "abc",
				},
			}
		}
	`,
			expectedProps: []propInfo{
				propInfo{"Name", "string"},
				propInfo{"Arch.X86_64.A", "string"},
			},
		},
		{
			desc: "embedded props",
			bp: `test {
			name: "foo",
			embedded_prop: "a",
		}
	`,
			expectedProps: []propInfo{
				propInfo{"Embedded_prop", "string"},
				propInfo{"Name", "string"},
			},
		},
		{
			desc: "defaults",
			bp: `
test_defaults {
	name: "foo_defaults",
	a: "a",
	b: true,
	embedded_prop:"a",
	arch: {
		x86_64: {
			a: "a",
		},
	},
}
test {
	name: "foo",
	defaults: ["foo_defaults"],
	c: ["a"],
	nested: {
		e: "d",
	},
	target: {
		linux: {
			a: "a",
		},
	},
}
	`,
			expectedProps: []propInfo{
				propInfo{"A", "string"},
				propInfo{"B", "bool"},
				propInfo{"C", "string slice"},
				propInfo{"Embedded_prop", "string"},
				propInfo{"Nested.E", "string"},
				propInfo{"Name", "string"},
				propInfo{"Arch.X86_64.A", "string"},
				propInfo{"Target.Linux.A", "string"},
				propInfo{"Defaults", "string slice"},
			},
		},
	}

	for _, tc := range testCases {
		t.Run(tc.desc, func(t *testing.T) {
			result := GroupFixturePreparers(
				PrepareForTestWithAllowMissingDependencies,
				PrepareForTestWithDefaults,
				FixtureRegisterWithContext(func(ctx RegistrationContext) {
					ctx.RegisterModuleType("test", propsTestModuleFactory)
					ctx.RegisterModuleType("test_defaults", propsTestModuleDefaultsFactory)
				}),
				FixtureWithRootAndroidBp(tc.bp),
			).RunTest(t)

			foo := result.ModuleForTests("foo", "").Module().base()

			AssertDeepEquals(t, "foo ", tc.expectedProps, foo.propertiesWithValues())

		})
	}
}
