// Copyright 2021 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 testSingletonModule struct {
	SingletonModuleBase
	ops []string
}

func (tsm *testSingletonModule) GenerateAndroidBuildActions(ctx ModuleContext) {
	tsm.ops = append(tsm.ops, "GenerateAndroidBuildActions")
}

func (tsm *testSingletonModule) GenerateSingletonBuildActions(ctx SingletonContext) {
	tsm.ops = append(tsm.ops, "GenerateSingletonBuildActions")
}

func (tsm *testSingletonModule) MakeVars(ctx MakeVarsContext) {
	tsm.ops = append(tsm.ops, "MakeVars")
}

func testSingletonModuleFactory() SingletonModule {
	tsm := &testSingletonModule{}
	InitAndroidSingletonModule(tsm)
	return tsm
}

var prepareForSingletonModuleTest = GroupFixturePreparers(
	// Enable Kati output to test SingletonModules with MakeVars.
	PrepareForTestWithAndroidMk,
	FixtureRegisterWithContext(func(ctx RegistrationContext) {
		ctx.RegisterSingletonModuleType("test_singleton_module", testSingletonModuleFactory)
		ctx.RegisterSingletonType("makevars", makeVarsSingletonFunc)
	}),
)

func TestSingletonModule(t *testing.T) {
	bp := `
		test_singleton_module {
			name: "test_singleton_module",
		}
	`
	result := GroupFixturePreparers(
		prepareForSingletonModuleTest,
		FixtureWithRootAndroidBp(bp),
	).RunTest(t)

	ops := result.ModuleForTests("test_singleton_module", "").Module().(*testSingletonModule).ops
	wantOps := []string{"GenerateAndroidBuildActions", "GenerateSingletonBuildActions", "MakeVars"}
	AssertDeepEquals(t, "operations", wantOps, ops)
}

func TestDuplicateSingletonModule(t *testing.T) {
	bp := `
		test_singleton_module {
			name: "test_singleton_module",
		}

		test_singleton_module {
			name: "test_singleton_module2",
		}
	`

	prepareForSingletonModuleTest.
		ExtendWithErrorHandler(FixtureExpectsAllErrorsToMatchAPattern([]string{
			`\QDuplicate SingletonModule "test_singleton_module", previously used in\E`,
		})).RunTestWithBp(t, bp)
}

func TestUnusedSingletonModule(t *testing.T) {
	result := GroupFixturePreparers(
		prepareForSingletonModuleTest,
	).RunTest(t)

	singleton := result.SingletonForTests("test_singleton_module").Singleton()
	sm := singleton.(*singletonModuleSingletonAdaptor).sm
	ops := sm.(*testSingletonModule).ops
	if ops != nil {
		t.Errorf("Expected no operations, got %q", ops)
	}
}

func testVariantSingletonModuleMutator(ctx BottomUpMutatorContext) {
	if _, ok := ctx.Module().(*testSingletonModule); ok {
		ctx.CreateVariations("a", "b")
	}
}

func TestVariantSingletonModule(t *testing.T) {
	bp := `
		test_singleton_module {
			name: "test_singleton_module",
		}
	`

	GroupFixturePreparers(
		prepareForSingletonModuleTest,
		FixtureRegisterWithContext(func(ctx RegistrationContext) {
			ctx.PreDepsMutators(func(ctx RegisterMutatorsContext) {
				ctx.BottomUp("test_singleton_module_mutator", testVariantSingletonModuleMutator)
			})
		}),
	).
		ExtendWithErrorHandler(FixtureExpectsAllErrorsToMatchAPattern([]string{
			`\QGenerateAndroidBuildActions already called for variant\E`,
		})).
		RunTestWithBp(t, bp)
}
