// 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, ok := ModuleProvider(ctx, providerTestUnsetInfoProvider)
	if ok {
		panic(fmt.Errorf("expected false return value for providerTestGenerateBuildActionsInfoProvider before it was set"))
	}
	if unset != "" {
		panic(fmt.Errorf("expected zero value for providerTestGenerateBuildActionsInfoProvider before it was set, got %q",
			unset))
	}

	// Verify reading providerTestUnusedMutatorProvider doesn't panic
	_, _ = ModuleProvider(ctx, providerTestUnusedMutatorProvider)

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

	mp, ok := ModuleProvider(ctx, providerTestMutatorInfoProvider)
	if ok {
		p.mutatorProviderValues = mp.Values
	}

	ctx.VisitDirectDeps(func(module Module) {
		gbap, _ := OtherModuleProvider(ctx, module, providerTestGenerateBuildActionsInfoProvider)
		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, _ := OtherModuleProvider(ctx, module, providerTestMutatorInfoProvider)
		if mp != nil {
			values = append(values, mp.Values...)
		}
	})

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

func providerTestAfterMutator(ctx BottomUpMutatorContext) {
	// Verify reading providerTestUnusedMutatorProvider doesn't panic
	_, _ = ModuleProvider(ctx, 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.
			SetProvider(ctx, 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.
			_, _ = ModuleProvider(ctx, 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.
			SetProvider(ctx, invalidProviderUsageGenerateBuildActionsInfoProvider, invalidProviderUsageGenerateBuildActionsInfo(""))
		}
		if i.properties.Early_mutator_get_of_build_actions_provider {
			// A mutator attempting to get the value of a non-mutator provider.
			_, _ = ModuleProvider(ctx, 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) {
				_, _ = OtherModuleProvider(ctx, 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.
			SetProvider(ctx, 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.
			SetProvider(ctx, 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.
		SetProvider(ctx, 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.
		_, _ = OtherModuleProvider(ctx, i.parent, invalidProviderUsageGenerateBuildActionsInfoProvider)
	}
	if i.properties.Duplicate_set {
		SetProvider(ctx, invalidProviderUsageGenerateBuildActionsInfoProvider, invalidProviderUsageGenerateBuildActionsInfo(""))
		SetProvider(ctx, 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)
		})
	}
}
