// Copyright 2017 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 (
	"errors"
	"path/filepath"
	"reflect"
	"testing"

	"github.com/google/blueprint"
)

func TestDependingOnModuleInSameNamespace(t *testing.T) {
	ctx := setupTest(t,
		map[string]string{
			"dir1": `
			soong_namespace {
			}
			test_module {
				name: "a",
			}
			test_module {
				name: "b",
				deps: ["a"],
			}
			`,
		},
	)

	a := getModule(ctx, "a")
	b := getModule(ctx, "b")
	if !dependsOn(ctx, b, a) {
		t.Errorf("module b does not depend on module a in the same namespace")
	}
}

func TestDependingOnModuleInRootNamespace(t *testing.T) {
	ctx := setupTest(t,
		map[string]string{
			".": `
			test_module {
				name: "b",
				deps: ["a"],
			}
			test_module {
				name: "a",
			}
			`,
		},
	)

	a := getModule(ctx, "a")
	b := getModule(ctx, "b")
	if !dependsOn(ctx, b, a) {
		t.Errorf("module b in root namespace does not depend on module a in the root namespace")
	}
}

func TestImplicitlyImportRootNamespace(t *testing.T) {
	_ = setupTest(t,
		map[string]string{
			".": `
			test_module {
				name: "a",
			}
			`,
			"dir1": `
			soong_namespace {
			}
			test_module {
				name: "b",
				deps: ["a"],
			}
			`,
		},
	)

	// setupTest will report any errors
}

func TestDependingOnBlueprintModuleInRootNamespace(t *testing.T) {
	_ = setupTest(t,
		map[string]string{
			".": `
			blueprint_test_module {
				name: "a",
			}
			`,
			"dir1": `
			soong_namespace {
			}
			blueprint_test_module {
				name: "b",
				deps: ["a"],
			}
			`,
		},
	)

	// setupTest will report any errors
}

func TestDependingOnModuleInImportedNamespace(t *testing.T) {
	ctx := setupTest(t,
		map[string]string{
			"dir1": `
			soong_namespace {
			}
			test_module {
				name: "a",
			}
			`,
			"dir2": `
			soong_namespace {
				imports: ["dir1"],
			}
			test_module {
				name: "b",
				deps: ["a"],
			}
			`,
		},
	)

	a := getModule(ctx, "a")
	b := getModule(ctx, "b")
	if !dependsOn(ctx, b, a) {
		t.Errorf("module b does not depend on module a in the same namespace")
	}
}

func TestDependingOnModuleInNonImportedNamespace(t *testing.T) {
	_, errs := setupTestExpectErrs(t,
		map[string]string{
			"dir1": `
			soong_namespace {
			}
			test_module {
				name: "a",
			}
			`,
			"dir2": `
			soong_namespace {
			}
			test_module {
				name: "a",
			}
			`,
			"dir3": `
			soong_namespace {
			}
			test_module {
				name: "b",
				deps: ["a"],
			}
			`,
		},
	)

	expectedErrors := []error{
		errors.New(
			`dir3/Android.bp:4:4: "b" depends on undefined module "a"
Module "b" is defined in namespace "dir3" which can read these 2 namespaces: ["dir3" "."]
Module "a" can be found in these namespaces: ["dir1" "dir2"]`),
	}

	if len(errs) != 1 || errs[0].Error() != expectedErrors[0].Error() {
		t.Errorf("Incorrect errors. Expected:\n%v\n, got:\n%v\n", expectedErrors, errs)
	}
}

func TestDependingOnModuleByFullyQualifiedReference(t *testing.T) {
	ctx := setupTest(t,
		map[string]string{
			"dir1": `
			soong_namespace {
			}
			test_module {
				name: "a",
			}
			`,
			"dir2": `
			soong_namespace {
			}
			test_module {
				name: "b",
				deps: ["//dir1:a"],
			}
			`,
		},
	)
	a := getModule(ctx, "a")
	b := getModule(ctx, "b")
	if !dependsOn(ctx, b, a) {
		t.Errorf("module b does not depend on module a")
	}
}

func TestSameNameInTwoNamespaces(t *testing.T) {
	ctx := setupTest(t,
		map[string]string{
			"dir1": `
			soong_namespace {
			}
			test_module {
				name: "a",
				id: "1",
			}
			test_module {
				name: "b",
				deps: ["a"],
				id: "2",
			}
			`,
			"dir2": `
			soong_namespace {
			}
			test_module {
				name: "a",
				id:"3",
			}
			test_module {
				name: "b",
				deps: ["a"],
				id:"4",
			}
			`,
		},
	)

	one := findModuleById(ctx, "1")
	two := findModuleById(ctx, "2")
	three := findModuleById(ctx, "3")
	four := findModuleById(ctx, "4")
	if !dependsOn(ctx, two, one) {
		t.Fatalf("Module 2 does not depend on module 1 in its namespace")
	}
	if dependsOn(ctx, two, three) {
		t.Fatalf("Module 2 depends on module 3 in another namespace")
	}
	if !dependsOn(ctx, four, three) {
		t.Fatalf("Module 4 does not depend on module 3 in its namespace")
	}
	if dependsOn(ctx, four, one) {
		t.Fatalf("Module 4 depends on module 1 in another namespace")
	}
}

func TestSearchOrder(t *testing.T) {
	ctx := setupTest(t,
		map[string]string{
			"dir1": `
			soong_namespace {
			}
			test_module {
				name: "a",
				id: "1",
			}
			`,
			"dir2": `
			soong_namespace {
			}
			test_module {
				name: "a",
				id:"2",
			}
			test_module {
				name: "b",
				id:"3",
			}
			`,
			"dir3": `
			soong_namespace {
			}
			test_module {
				name: "a",
				id:"4",
			}
			test_module {
				name: "b",
				id:"5",
			}
			test_module {
				name: "c",
				id:"6",
			}
			`,
			".": `
			test_module {
				name: "a",
				id: "7",
			}
			test_module {
				name: "b",
				id: "8",
			}
			test_module {
				name: "c",
				id: "9",
			}
			test_module {
				name: "d",
				id: "10",
			}
			`,
			"dir4": `
			soong_namespace {
				imports: ["dir1", "dir2", "dir3"]
			}
			test_module {
				name: "test_me",
				id:"0",
				deps: ["a", "b", "c", "d"],
			}
			`,
		},
	)

	testMe := findModuleById(ctx, "0")
	if !dependsOn(ctx, testMe, findModuleById(ctx, "1")) {
		t.Errorf("test_me doesn't depend on id 1")
	}
	if !dependsOn(ctx, testMe, findModuleById(ctx, "3")) {
		t.Errorf("test_me doesn't depend on id 3")
	}
	if !dependsOn(ctx, testMe, findModuleById(ctx, "6")) {
		t.Errorf("test_me doesn't depend on id 6")
	}
	if !dependsOn(ctx, testMe, findModuleById(ctx, "10")) {
		t.Errorf("test_me doesn't depend on id 10")
	}
	if numDeps(ctx, testMe) != 4 {
		t.Errorf("num dependencies of test_me = %v, not 4\n", numDeps(ctx, testMe))
	}
}

func TestTwoNamespacesCanImportEachOther(t *testing.T) {
	_ = setupTest(t,
		map[string]string{
			"dir1": `
			soong_namespace {
				imports: ["dir2"]
			}
			test_module {
				name: "a",
			}
			test_module {
				name: "c",
				deps: ["b"],
			}
			`,
			"dir2": `
			soong_namespace {
				imports: ["dir1"],
			}
			test_module {
				name: "b",
				deps: ["a"],
			}
			`,
		},
	)

	// setupTest will report any errors
}

func TestImportingNonexistentNamespace(t *testing.T) {
	_, errs := setupTestExpectErrs(t,
		map[string]string{
			"dir1": `
			soong_namespace {
				imports: ["a_nonexistent_namespace"]
			}
			test_module {
				name: "a",
				deps: ["a_nonexistent_module"]
			}
			`,
		},
	)

	// should complain about the missing namespace and not complain about the unresolvable dependency
	expectedErrors := []error{
		errors.New(`dir1/Android.bp:2:4: module "soong_namespace": namespace a_nonexistent_namespace does not exist`),
	}
	if len(errs) != 1 || errs[0].Error() != expectedErrors[0].Error() {
		t.Errorf("Incorrect errors. Expected:\n%v\n, got:\n%v\n", expectedErrors, errs)
	}
}

func TestNamespacesDontInheritParentNamespaces(t *testing.T) {
	_, errs := setupTestExpectErrs(t,
		map[string]string{
			"dir1": `
			soong_namespace {
			}
			test_module {
				name: "a",
			}
			`,
			"dir1/subdir1": `
			soong_namespace {
			}
			test_module {
				name: "b",
				deps: ["a"],
			}
			`,
		},
	)

	expectedErrors := []error{
		errors.New(`dir1/subdir1/Android.bp:4:4: "b" depends on undefined module "a"
Module "b" is defined in namespace "dir1/subdir1" which can read these 2 namespaces: ["dir1/subdir1" "."]
Module "a" can be found in these namespaces: ["dir1"]`),
	}
	if len(errs) != 1 || errs[0].Error() != expectedErrors[0].Error() {
		t.Errorf("Incorrect errors. Expected:\n%v\n, got:\n%v\n", expectedErrors, errs)
	}
}

func TestModulesDoReceiveParentNamespace(t *testing.T) {
	_ = setupTest(t,
		map[string]string{
			"dir1": `
			soong_namespace {
			}
			test_module {
				name: "a",
			}
			`,
			"dir1/subdir": `
			test_module {
				name: "b",
				deps: ["a"],
			}
			`,
		},
	)

	// setupTest will report any errors
}

func TestNamespaceImportsNotTransitive(t *testing.T) {
	_, errs := setupTestExpectErrs(t,
		map[string]string{
			"dir1": `
			soong_namespace {
			}
			test_module {
				name: "a",
			}
			`,
			"dir2": `
			soong_namespace {
				imports: ["dir1"],
			}
			test_module {
				name: "b",
				deps: ["a"],
			}
			`,
			"dir3": `
			soong_namespace {
				imports: ["dir2"],
			}
			test_module {
				name: "c",
				deps: ["a"],
			}
			`,
		},
	)

	expectedErrors := []error{
		errors.New(`dir3/Android.bp:5:4: "c" depends on undefined module "a"
Module "c" is defined in namespace "dir3" which can read these 3 namespaces: ["dir3" "dir2" "."]
Module "a" can be found in these namespaces: ["dir1"]`),
	}
	if len(errs) != 1 || errs[0].Error() != expectedErrors[0].Error() {
		t.Errorf("Incorrect errors. Expected:\n%v\n, got:\n%v\n", expectedErrors, errs)
	}
}

func TestTwoNamepacesInSameDir(t *testing.T) {
	_, errs := setupTestExpectErrs(t,
		map[string]string{
			"dir1": `
			soong_namespace {
			}
			soong_namespace {
			}
			`,
		},
	)

	expectedErrors := []error{
		errors.New(`dir1/Android.bp:4:4: namespace dir1 already exists`),
	}
	if len(errs) != 1 || errs[0].Error() != expectedErrors[0].Error() {
		t.Errorf("Incorrect errors. Expected:\n%v\n, got:\n%v\n", expectedErrors, errs)
	}
}

func TestNamespaceNotAtTopOfFile(t *testing.T) {
	_, errs := setupTestExpectErrs(t,
		map[string]string{
			"dir1": `
			test_module {
				name: "a"
			}
			soong_namespace {
			}
			`,
		},
	)

	expectedErrors := []error{
		errors.New(`dir1/Android.bp:5:4: a namespace must be the first module in the file`),
	}
	if len(errs) != 1 || errs[0].Error() != expectedErrors[0].Error() {
		t.Errorf("Incorrect errors. Expected:\n%v\n, got:\n%v\n", expectedErrors, errs)
	}
}

func TestTwoModulesWithSameNameInSameNamespace(t *testing.T) {
	_, errs := setupTestExpectErrs(t,
		map[string]string{
			"dir1": `
			soong_namespace {
			}
			test_module {
				name: "a"
			}
			test_module {
				name: "a"
			}
			`,
		},
	)

	expectedErrors := []error{
		errors.New(`dir1/Android.bp:7:4: module "a" already defined
       dir1/Android.bp:4:4 <-- previous definition here`),
	}
	if len(errs) != 1 || errs[0].Error() != expectedErrors[0].Error() {
		t.Errorf("Incorrect errors. Expected:\n%v\n, got:\n%v\n", expectedErrors, errs)
	}
}

func TestDeclaringNamespaceInNonAndroidBpFile(t *testing.T) {
	_, errs := setupTestFromFiles(t,
		map[string][]byte{
			"Android.bp": []byte(`
				build = ["include.bp"]
			`),
			"include.bp": []byte(`
				soong_namespace {
				}
			`),
		},
	)

	expectedErrors := []error{
		errors.New(`include.bp:2:5: A namespace may only be declared in a file named Android.bp`),
	}

	if len(errs) != 1 || errs[0].Error() != expectedErrors[0].Error() {
		t.Errorf("Incorrect errors. Expected:\n%v\n, got:\n%v\n", expectedErrors, errs)
	}
}

// so that the generated .ninja file will have consistent names
func TestConsistentNamespaceNames(t *testing.T) {
	ctx := setupTest(t,
		map[string]string{
			"dir1": "soong_namespace{}",
			"dir2": "soong_namespace{}",
			"dir3": "soong_namespace{}",
		})

	ns1, _ := ctx.NameResolver.namespaceAt("dir1")
	ns2, _ := ctx.NameResolver.namespaceAt("dir2")
	ns3, _ := ctx.NameResolver.namespaceAt("dir3")
	actualIds := []string{ns1.id, ns2.id, ns3.id}
	expectedIds := []string{"1", "2", "3"}
	if !reflect.DeepEqual(actualIds, expectedIds) {
		t.Errorf("Incorrect namespace ids.\nactual: %s\nexpected: %s\n", actualIds, expectedIds)
	}
}

// so that the generated .ninja file will have consistent names
func TestRename(t *testing.T) {
	_ = setupTest(t,
		map[string]string{
			"dir1": `
			soong_namespace {
			}
			test_module {
				name: "a",
				deps: ["c"],
			}
			test_module {
				name: "b",
				rename: "c",
			}
		`})
	// setupTest will report any errors
}

// some utils to support the tests

func mockFiles(bps map[string]string) (files map[string][]byte) {
	files = make(map[string][]byte, len(bps))
	files["Android.bp"] = []byte("")
	for dir, text := range bps {
		files[filepath.Join(dir, "Android.bp")] = []byte(text)
	}
	return files
}

func setupTestFromFiles(t *testing.T, bps MockFS) (ctx *TestContext, errs []error) {
	result := GroupFixturePreparers(
		FixtureModifyContext(func(ctx *TestContext) {
			ctx.RegisterModuleType("test_module", newTestModule)
			ctx.Context.RegisterModuleType("blueprint_test_module", newBlueprintTestModule)
			ctx.PreDepsMutators(func(ctx RegisterMutatorsContext) {
				ctx.BottomUp("rename", renameMutator)
			})
		}),
		PrepareForTestWithNamespace,
		bps.AddToFixture(),
	).
		// Ignore errors for now so tests can check them later.
		ExtendWithErrorHandler(FixtureIgnoreErrors).
		RunTest(t)

	return result.TestContext, result.Errs
}

func setupTestExpectErrs(t *testing.T, bps map[string]string) (ctx *TestContext, errs []error) {
	files := make(map[string][]byte, len(bps))
	files["Android.bp"] = []byte("")
	for dir, text := range bps {
		files[filepath.Join(dir, "Android.bp")] = []byte(text)
	}
	return setupTestFromFiles(t, files)
}

func setupTest(t *testing.T, bps map[string]string) (ctx *TestContext) {
	t.Helper()
	ctx, errs := setupTestExpectErrs(t, bps)
	FailIfErrored(t, errs)
	return ctx
}

func dependsOn(ctx *TestContext, module TestingModule, possibleDependency TestingModule) bool {
	depends := false
	visit := func(dependency blueprint.Module) {
		if dependency == possibleDependency.module {
			depends = true
		}
	}
	ctx.VisitDirectDeps(module.module, visit)
	return depends
}

func numDeps(ctx *TestContext, module TestingModule) int {
	count := 0
	visit := func(dependency blueprint.Module) {
		count++
	}
	ctx.VisitDirectDeps(module.module, visit)
	return count
}

func getModule(ctx *TestContext, moduleName string) TestingModule {
	return ctx.ModuleForTests(moduleName, "")
}

func findModuleById(ctx *TestContext, id string) (module TestingModule) {
	visit := func(candidate blueprint.Module) {
		testModule, ok := candidate.(*testModule)
		if ok {
			if testModule.properties.Id == id {
				module = newTestingModule(ctx.config, testModule)
			}
		}
	}
	ctx.VisitAllModules(visit)
	return module
}

type testModule struct {
	ModuleBase
	properties struct {
		Rename string
		Deps   []string
		Id     string
	}
}

func (m *testModule) DepsMutator(ctx BottomUpMutatorContext) {
	if m.properties.Rename != "" {
		ctx.Rename(m.properties.Rename)
	}
	for _, d := range m.properties.Deps {
		ctx.AddDependency(ctx.Module(), nil, d)
	}
}

func (m *testModule) GenerateAndroidBuildActions(ModuleContext) {
}

func renameMutator(ctx BottomUpMutatorContext) {
	if m, ok := ctx.Module().(*testModule); ok {
		if m.properties.Rename != "" {
			ctx.Rename(m.properties.Rename)
		}
	}
}

func newTestModule() Module {
	m := &testModule{}
	m.AddProperties(&m.properties)
	InitAndroidModule(m)
	return m
}

type blueprintTestModule struct {
	blueprint.SimpleName
	properties struct {
		Deps []string
	}
}

func (b *blueprintTestModule) DynamicDependencies(ctx blueprint.DynamicDependerModuleContext) []string {
	return b.properties.Deps
}

func (b *blueprintTestModule) GenerateBuildActions(blueprint.ModuleContext) {
}

func newBlueprintTestModule() (blueprint.Module, []interface{}) {
	m := &blueprintTestModule{}
	return m, []interface{}{&m.properties, &m.SimpleName.Properties}
}
