// Copyright 2020 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 blueprint

import (
	"fmt"
	"reflect"
	"strings"
	"testing"
)

type providerTestModule struct {
	SimpleName
	properties struct {
		Deps []string
	}

	mutatorProviderValues              []string
	generateBuildActionsProviderValues []string
}

func newProviderTestModule() (Module, []interface{}) {
	m := &providerTestModule{}
	return m, []interface{}{&m.properties, &m.SimpleName.Properties}
}

type providerTestMutatorInfo struct {
	Values []string
}

type providerTestGenerateBuildActionsInfo struct {
	Value string
}

type providerTestUnsetInfo string

var providerTestMutatorInfoProvider = NewMutatorProvider(&providerTestMutatorInfo{}, "provider_mutator")
var providerTestGenerateBuildActionsInfoProvider = NewProvider(&providerTestGenerateBuildActionsInfo{})
var providerTestUnsetInfoProvider = NewMutatorProvider((providerTestUnsetInfo)(""), "provider_mutator")
var providerTestUnusedMutatorProvider = NewMutatorProvider(&struct{ unused string }{}, "nonexistent_mutator")

func (p *providerTestModule) GenerateBuildActions(ctx ModuleContext) {
	unset := ctx.Provider(providerTestUnsetInfoProvider).(providerTestUnsetInfo)
	if unset != "" {
		panic(fmt.Sprintf("expected zero value for providerTestGenerateBuildActionsInfoProvider before it was set, got %q",
			unset))
	}

	_ = ctx.Provider(providerTestUnusedMutatorProvider)

	ctx.SetProvider(providerTestGenerateBuildActionsInfoProvider, &providerTestGenerateBuildActionsInfo{
		Value: ctx.ModuleName(),
	})

	mp := ctx.Provider(providerTestMutatorInfoProvider).(*providerTestMutatorInfo)
	if mp != nil {
		p.mutatorProviderValues = mp.Values
	}

	ctx.VisitDirectDeps(func(module Module) {
		gbap := ctx.OtherModuleProvider(module, providerTestGenerateBuildActionsInfoProvider).(*providerTestGenerateBuildActionsInfo)
		if gbap != nil {
			p.generateBuildActionsProviderValues = append(p.generateBuildActionsProviderValues, gbap.Value)
		}
	})
}

func providerTestDepsMutator(ctx BottomUpMutatorContext) {
	if p, ok := ctx.Module().(*providerTestModule); ok {
		ctx.AddDependency(ctx.Module(), nil, p.properties.Deps...)
	}
}

func providerTestMutator(ctx BottomUpMutatorContext) {
	values := []string{strings.ToLower(ctx.ModuleName())}

	ctx.VisitDirectDeps(func(module Module) {
		mp := ctx.OtherModuleProvider(module, providerTestMutatorInfoProvider).(*providerTestMutatorInfo)
		if mp != nil {
			values = append(values, mp.Values...)
		}
	})

	ctx.SetProvider(providerTestMutatorInfoProvider, &providerTestMutatorInfo{
		Values: values,
	})
}

func providerTestAfterMutator(ctx BottomUpMutatorContext) {
	_ = ctx.Provider(providerTestMutatorInfoProvider)
}

func TestProviders(t *testing.T) {
	ctx := NewContext()
	ctx.RegisterModuleType("provider_module", newProviderTestModule)
	ctx.RegisterBottomUpMutator("provider_deps_mutator", providerTestDepsMutator)
	ctx.RegisterBottomUpMutator("provider_mutator", providerTestMutator)
	ctx.RegisterBottomUpMutator("provider_after_mutator", providerTestAfterMutator)

	ctx.MockFileSystem(map[string][]byte{
		"Android.bp": []byte(`
			provider_module {
				name: "A",
				deps: ["B"],
			}
	
			provider_module {
				name: "B",
				deps: ["C", "D"],
			}
	
			provider_module {
				name: "C",
				deps: ["D"],
			}
	
			provider_module {
				name: "D",
			}
		`),
	})

	_, errs := ctx.ParseBlueprintsFiles("Android.bp", nil)
	if len(errs) == 0 {
		_, errs = ctx.ResolveDependencies(nil)
	}
	if len(errs) == 0 {
		_, errs = ctx.PrepareBuildActions(nil)
	}
	if len(errs) > 0 {
		t.Errorf("unexpected errors:")
		for _, err := range errs {
			t.Errorf("  %s", err)
		}
		t.FailNow()
	}

	aModule := ctx.moduleGroupFromName("A", nil).moduleByVariantName("").logicModule.(*providerTestModule)
	if g, w := aModule.generateBuildActionsProviderValues, []string{"B"}; !reflect.DeepEqual(g, w) {
		t.Errorf("expected A.generateBuildActionsProviderValues %q, got %q", w, g)
	}
	if g, w := aModule.mutatorProviderValues, []string{"a", "b", "c", "d", "d"}; !reflect.DeepEqual(g, w) {
		t.Errorf("expected A.mutatorProviderValues %q, got %q", w, g)
	}

	bModule := ctx.moduleGroupFromName("B", nil).moduleByVariantName("").logicModule.(*providerTestModule)
	if g, w := bModule.generateBuildActionsProviderValues, []string{"C", "D"}; !reflect.DeepEqual(g, w) {
		t.Errorf("expected B.generateBuildActionsProviderValues %q, got %q", w, g)
	}
	if g, w := bModule.mutatorProviderValues, []string{"b", "c", "d", "d"}; !reflect.DeepEqual(g, w) {
		t.Errorf("expected B.mutatorProviderValues %q, got %q", w, g)
	}
}

type invalidProviderUsageMutatorInfo string
type invalidProviderUsageGenerateBuildActionsInfo string

var invalidProviderUsageMutatorInfoProvider = NewMutatorProvider(invalidProviderUsageMutatorInfo(""), "mutator_under_test")
var invalidProviderUsageGenerateBuildActionsInfoProvider = NewProvider(invalidProviderUsageGenerateBuildActionsInfo(""))

type invalidProviderUsageTestModule struct {
	parent *invalidProviderUsageTestModule

	SimpleName
	properties struct {
		Deps []string

		Early_mutator_set_of_mutator_provider       bool
		Late_mutator_set_of_mutator_provider        bool
		Late_build_actions_set_of_mutator_provider  bool
		Early_mutator_set_of_build_actions_provider bool

		Early_mutator_get_of_mutator_provider       bool
		Early_module_get_of_mutator_provider        bool
		Early_mutator_get_of_build_actions_provider bool
		Early_module_get_of_build_actions_provider  bool

		Duplicate_set bool
	}
}

func invalidProviderUsageDepsMutator(ctx BottomUpMutatorContext) {
	if i, ok := ctx.Module().(*invalidProviderUsageTestModule); ok {
		ctx.AddDependency(ctx.Module(), nil, i.properties.Deps...)
	}
}

func invalidProviderUsageParentMutator(ctx TopDownMutatorContext) {
	if i, ok := ctx.Module().(*invalidProviderUsageTestModule); ok {
		ctx.VisitDirectDeps(func(module Module) {
			module.(*invalidProviderUsageTestModule).parent = i
		})
	}
}

func invalidProviderUsageBeforeMutator(ctx BottomUpMutatorContext) {
	if i, ok := ctx.Module().(*invalidProviderUsageTestModule); ok {
		if i.properties.Early_mutator_set_of_mutator_provider {
			// A mutator attempting to set the value of a provider associated with a later mutator.
			ctx.SetProvider(invalidProviderUsageMutatorInfoProvider, invalidProviderUsageMutatorInfo(""))
		}
		if i.properties.Early_mutator_get_of_mutator_provider {
			// A mutator attempting to get the value of a provider associated with a later mutator.
			_ = ctx.Provider(invalidProviderUsageMutatorInfoProvider)
		}
	}
}

func invalidProviderUsageMutatorUnderTest(ctx TopDownMutatorContext) {
	if i, ok := ctx.Module().(*invalidProviderUsageTestModule); ok {
		if i.properties.Early_mutator_set_of_build_actions_provider {
			// A mutator attempting to set the value of a non-mutator provider.
			ctx.SetProvider(invalidProviderUsageGenerateBuildActionsInfoProvider, invalidProviderUsageGenerateBuildActionsInfo(""))
		}
		if i.properties.Early_mutator_get_of_build_actions_provider {
			// A mutator attempting to get the value of a non-mutator provider.
			_ = ctx.Provider(invalidProviderUsageGenerateBuildActionsInfoProvider)
		}
		if i.properties.Early_module_get_of_mutator_provider {
			// A mutator attempting to get the value of a provider associated with this mutator on
			// a module for which this mutator hasn't run.  This is a top down mutator so
			// dependencies haven't run yet.
			ctx.VisitDirectDeps(func(module Module) {
				_ = ctx.OtherModuleProvider(module, invalidProviderUsageMutatorInfoProvider)
			})
		}
	}
}

func invalidProviderUsageAfterMutator(ctx BottomUpMutatorContext) {
	if i, ok := ctx.Module().(*invalidProviderUsageTestModule); ok {
		if i.properties.Late_mutator_set_of_mutator_provider {
			// A mutator trying to set the value of a provider associated with an earlier mutator.
			ctx.SetProvider(invalidProviderUsageMutatorInfoProvider, invalidProviderUsageMutatorInfo(""))
		}
		if i.properties.Late_mutator_set_of_mutator_provider {
			// A mutator trying to set the value of a provider associated with an earlier mutator.
			ctx.SetProvider(invalidProviderUsageMutatorInfoProvider, invalidProviderUsageMutatorInfo(""))
		}
	}
}

func (i *invalidProviderUsageTestModule) GenerateBuildActions(ctx ModuleContext) {
	if i.properties.Late_build_actions_set_of_mutator_provider {
		// A GenerateBuildActions trying to set the value of a provider associated with a mutator.
		ctx.SetProvider(invalidProviderUsageMutatorInfoProvider, invalidProviderUsageMutatorInfo(""))
	}
	if i.properties.Early_module_get_of_build_actions_provider {
		// A GenerateBuildActions trying to get the value of a provider on a module for which
		// GenerateBuildActions hasn't run.
		_ = ctx.OtherModuleProvider(i.parent, invalidProviderUsageGenerateBuildActionsInfoProvider)
	}
	if i.properties.Duplicate_set {
		ctx.SetProvider(invalidProviderUsageGenerateBuildActionsInfoProvider, invalidProviderUsageGenerateBuildActionsInfo(""))
		ctx.SetProvider(invalidProviderUsageGenerateBuildActionsInfoProvider, invalidProviderUsageGenerateBuildActionsInfo(""))
	}
}

func TestInvalidProvidersUsage(t *testing.T) {
	run := func(t *testing.T, module string, prop string, panicMsg string) {
		t.Helper()
		ctx := NewContext()
		ctx.RegisterModuleType("invalid_provider_usage_test_module", func() (Module, []interface{}) {
			m := &invalidProviderUsageTestModule{}
			return m, []interface{}{&m.properties, &m.SimpleName.Properties}
		})
		ctx.RegisterBottomUpMutator("deps", invalidProviderUsageDepsMutator)
		ctx.RegisterBottomUpMutator("before", invalidProviderUsageBeforeMutator)
		ctx.RegisterTopDownMutator("mutator_under_test", invalidProviderUsageMutatorUnderTest)
		ctx.RegisterBottomUpMutator("after", invalidProviderUsageAfterMutator)
		ctx.RegisterTopDownMutator("parent", invalidProviderUsageParentMutator)

		// Don't invalidate the parent pointer and before GenerateBuildActions.
		ctx.skipCloneModulesAfterMutators = true

		var parentBP, moduleUnderTestBP, childBP string

		prop += ": true,"

		switch module {
		case "parent":
			parentBP = prop
		case "module_under_test":
			moduleUnderTestBP = prop
		case "child":
			childBP = prop
		}

		bp := fmt.Sprintf(`
			invalid_provider_usage_test_module {
				name: "parent",
				deps: ["module_under_test"],
				%s
			}
	
			invalid_provider_usage_test_module {
				name: "module_under_test",
				deps: ["child"],
				%s
			}
	
			invalid_provider_usage_test_module {
				name: "child",
				%s
			}

		`,
			parentBP,
			moduleUnderTestBP,
			childBP)

		ctx.MockFileSystem(map[string][]byte{
			"Android.bp": []byte(bp),
		})

		_, errs := ctx.ParseBlueprintsFiles("Android.bp", nil)

		if len(errs) == 0 {
			_, errs = ctx.ResolveDependencies(nil)
		}

		if len(errs) == 0 {
			_, errs = ctx.PrepareBuildActions(nil)
		}

		if len(errs) == 0 {
			t.Fatal("expected an error")
		}

		if len(errs) > 1 {
			t.Errorf("expected a single error, got %d:", len(errs))
			for i, err := range errs {
				t.Errorf("%d:  %s", i, err)
			}
			t.FailNow()
		}

		if panicErr, ok := errs[0].(panicError); ok {
			if panicErr.panic != panicMsg {
				t.Fatalf("expected panic %q, got %q", panicMsg, panicErr.panic)
			}
		} else {
			t.Fatalf("expected a panicError, got %T: %s", errs[0], errs[0].Error())
		}

	}

	tests := []struct {
		prop   string
		module string

		panicMsg string
		skip     string
	}{
		{
			prop:     "early_mutator_set_of_mutator_provider",
			module:   "module_under_test",
			panicMsg: "Can't set value of provider blueprint.invalidProviderUsageMutatorInfo before mutator mutator_under_test started",
		},
		{
			prop:     "late_mutator_set_of_mutator_provider",
			module:   "module_under_test",
			panicMsg: "Can't set value of provider blueprint.invalidProviderUsageMutatorInfo after mutator mutator_under_test finished",
		},
		{
			prop:     "late_build_actions_set_of_mutator_provider",
			module:   "module_under_test",
			panicMsg: "Can't set value of provider blueprint.invalidProviderUsageMutatorInfo after mutator mutator_under_test finished",
		},
		{
			prop:     "early_mutator_set_of_build_actions_provider",
			module:   "module_under_test",
			panicMsg: "Can't set value of provider blueprint.invalidProviderUsageGenerateBuildActionsInfo before GenerateBuildActions started",
		},

		{
			prop:     "early_mutator_get_of_mutator_provider",
			module:   "module_under_test",
			panicMsg: "Can't get value of provider blueprint.invalidProviderUsageMutatorInfo before mutator mutator_under_test finished",
		},
		{
			prop:     "early_module_get_of_mutator_provider",
			module:   "module_under_test",
			panicMsg: "Can't get value of provider blueprint.invalidProviderUsageMutatorInfo before mutator mutator_under_test finished",
		},
		{
			prop:     "early_mutator_get_of_build_actions_provider",
			module:   "module_under_test",
			panicMsg: "Can't get value of provider blueprint.invalidProviderUsageGenerateBuildActionsInfo before GenerateBuildActions finished",
		},
		{
			prop:     "early_module_get_of_build_actions_provider",
			module:   "module_under_test",
			panicMsg: "Can't get value of provider blueprint.invalidProviderUsageGenerateBuildActionsInfo before GenerateBuildActions finished",
		},
		{
			prop:     "duplicate_set",
			module:   "module_under_test",
			panicMsg: "Value of provider blueprint.invalidProviderUsageGenerateBuildActionsInfo is already set",
		},
	}

	for _, tt := range tests {
		t.Run(tt.prop, func(t *testing.T) {
			run(t, tt.module, tt.prop, tt.panicMsg)
		})
	}
}
