// 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 := emptyTestFixtureFactory.
		RunTest(t,
			prepareForSingletonModuleTest,
			FixtureWithRootAndroidBp(bp),
		)

	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",
		}
	`

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

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

	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",
		}
	`

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