// Copyright 2019 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 sdk

import (
	"fmt"
	"path/filepath"
	"strings"
	"testing"

	"android/soong/android"
	"android/soong/apex"
	"android/soong/cc"
	"android/soong/genrule"
	"android/soong/java"

	"github.com/google/blueprint/proptools"
)

// Prepare for running an sdk test with an apex.
var prepareForSdkTestWithApex = android.GroupFixturePreparers(
	apex.PrepareForTestWithApexBuildComponents,
	android.FixtureAddTextFile("sdk/tests/Android.bp", `
		apex_key {
			name: "myapex.key",
			public_key: "myapex.avbpubkey",
			private_key: "myapex.pem",
		}

		android_app_certificate {
			name: "myapex.cert",
			certificate: "myapex",
		}
	`),

	android.FixtureMergeMockFs(map[string][]byte{
		"apex_manifest.json":                           nil,
		"system/sepolicy/apex/myapex-file_contexts":    nil,
		"system/sepolicy/apex/myapex2-file_contexts":   nil,
		"system/sepolicy/apex/mysdkapex-file_contexts": nil,
		"sdk/tests/myapex.avbpubkey":                   nil,
		"sdk/tests/myapex.pem":                         nil,
		"sdk/tests/myapex.x509.pem":                    nil,
		"sdk/tests/myapex.pk8":                         nil,
	}),
)

// Legacy preparer used for running tests within the sdk package.
//
// This includes everything that was needed to run any test in the sdk package prior to the
// introduction of the test fixtures. Tests that are being converted to use fixtures directly
// rather than through the testSdkError() and testSdkWithFs() methods should avoid using this and
// instead should use the various preparers directly using android.GroupFixturePreparers(...) to
// group them when necessary.
//
// deprecated
var prepareForSdkTest = android.GroupFixturePreparers(
	cc.PrepareForTestWithCcDefaultModules,
	genrule.PrepareForTestWithGenRuleBuildComponents,
	java.PrepareForTestWithJavaBuildComponents,
	PrepareForTestWithSdkBuildComponents,

	prepareForSdkTestWithApex,

	cc.PrepareForTestOnWindows,
	android.FixtureModifyConfig(func(config android.Config) {
		// Add windows as a default disable OS to test behavior when some OS variants
		// are disabled.
		config.Targets[android.Windows] = []android.Target{
			{android.Windows, android.Arch{ArchType: android.X86_64}, android.NativeBridgeDisabled, "", "", true},
		}
	}),

	// Add a build number file.
	android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) {
		variables.BuildNumberFile = proptools.StringPtr(BUILD_NUMBER_FILE)
	}),

	// Make sure that every test provides all the source files.
	android.PrepareForTestDisallowNonExistentPaths,
	android.MockFS{
		"Test.java": nil,
	}.AddToFixture(),
)

var PrepareForTestWithSdkBuildComponents = android.GroupFixturePreparers(
	android.FixtureRegisterWithContext(registerModuleExportsBuildComponents),
	android.FixtureRegisterWithContext(registerSdkBuildComponents),
)

func testSdkWithFs(t *testing.T, bp string, fs android.MockFS) *android.TestResult {
	t.Helper()
	return android.GroupFixturePreparers(
		prepareForSdkTest,
		fs.AddToFixture(),
	).RunTestWithBp(t, bp)
}

func testSdkError(t *testing.T, pattern, bp string) {
	t.Helper()
	prepareForSdkTest.
		ExtendWithErrorHandler(android.FixtureExpectsAtLeastOneErrorMatchingPattern(pattern)).
		RunTestWithBp(t, bp)
}

func ensureListContains(t *testing.T, result []string, expected string) {
	t.Helper()
	if !android.InList(expected, result) {
		t.Errorf("%q is not found in %v", expected, result)
	}
}

func pathsToStrings(paths android.Paths) []string {
	var ret []string
	for _, p := range paths {
		ret = append(ret, p.String())
	}
	return ret
}

// Analyse the sdk build rules to extract information about what it is doing.
//
// e.g. find the src/dest pairs from each cp command, the various zip files
// generated, etc.
func getSdkSnapshotBuildInfo(t *testing.T, result *android.TestResult, sdk *sdk) *snapshotBuildInfo {
	info := &snapshotBuildInfo{
		t:                            t,
		r:                            result,
		version:                      sdk.builderForTests.version,
		androidBpContents:            sdk.GetAndroidBpContentsForTests(),
		androidUnversionedBpContents: sdk.GetUnversionedAndroidBpContentsForTests(),
		androidVersionedBpContents:   sdk.GetVersionedAndroidBpContentsForTests(),
		snapshotTestCustomizations:   map[snapshotTest]*snapshotTestCustomization{},
		targetBuildRelease:           sdk.builderForTests.targetBuildRelease,
	}

	buildParams := sdk.BuildParamsForTests()
	copyRules := &strings.Builder{}
	otherCopyRules := &strings.Builder{}
	snapshotDirPrefix := sdk.builderForTests.snapshotDir.String() + "/"

	seenBuildNumberFile := false
	for _, bp := range buildParams {
		switch bp.Rule.String() {
		case android.Cp.String():
			output := bp.Output
			// Get destination relative to the snapshot root
			dest := output.Rel()
			src := android.NormalizePathForTesting(bp.Input)
			// We differentiate between copy rules for the snapshot, and copy rules for the install file.
			if strings.HasPrefix(output.String(), snapshotDirPrefix) {
				// Don't include the build-number.txt file in the copy rules as that would break lots of
				// tests, just verify that it is copied here as it should appear in every snapshot.
				if output.Base() == BUILD_NUMBER_FILE {
					seenBuildNumberFile = true
				} else {
					// Get source relative to build directory.
					_, _ = fmt.Fprintf(copyRules, "%s -> %s\n", src, dest)
				}
				info.snapshotContents = append(info.snapshotContents, dest)
			} else {
				_, _ = fmt.Fprintf(otherCopyRules, "%s -> %s\n", src, dest)
			}

		case repackageZip.String():
			// Add the destdir to the snapshot contents as that is effectively where
			// the content of the repackaged zip is copied.
			dest := bp.Args["destdir"]
			info.snapshotContents = append(info.snapshotContents, dest)

		case zipFiles.String():
			// This could be an intermediate zip file and not the actual output zip.
			// In that case this will be overridden when the rule to merge the zips
			// is processed.
			info.outputZip = android.NormalizePathForTesting(bp.Output)

		case mergeZips.String():
			// Copy the current outputZip to the intermediateZip.
			info.intermediateZip = info.outputZip
			mergeInput := android.NormalizePathForTesting(bp.Input)
			if info.intermediateZip != mergeInput {
				t.Errorf("Expected intermediate zip %s to be an input to merge zips but found %s instead",
					info.intermediateZip, mergeInput)
			}

			// Override output zip (which was actually the intermediate zip file) with the actual
			// output zip.
			info.outputZip = android.NormalizePathForTesting(bp.Output)

			// Save the zips to be merged into the intermediate zip.
			info.mergeZips = android.NormalizePathsForTesting(bp.Inputs)
		}
	}

	if !seenBuildNumberFile {
		panic(fmt.Sprintf("Every snapshot must include the %s file", BUILD_NUMBER_FILE))
	}

	info.copyRules = copyRules.String()
	info.otherCopyRules = otherCopyRules.String()

	return info
}

// The enum of different sdk snapshot tests performed by CheckSnapshot.
type snapshotTest int

const (
	// The enumeration of the different test configurations.
	// A test with the snapshot/Android.bp file but without the original Android.bp file.
	checkSnapshotWithoutSource snapshotTest = iota

	// A test with both the original source and the snapshot, with the source preferred.
	checkSnapshotWithSourcePreferred

	// A test with both the original source and the snapshot, with the snapshot preferred.
	checkSnapshotPreferredWithSource

	// The directory into which the snapshot will be 'unpacked'.
	snapshotSubDir = "snapshot"
)

// Check the snapshot build rules.
//
// Takes a list of functions which check different facets of the snapshot build rules.
// Allows each test to customize what is checked without duplicating lots of code
// or proliferating check methods of different flavors.
func CheckSnapshot(t *testing.T, result *android.TestResult, name string, dir string, checkers ...snapshotBuildInfoChecker) {
	t.Helper()

	// The sdk CommonOS variant is always responsible for generating the snapshot.
	variant := android.CommonOS.Name

	sdk := result.Module(name, variant).(*sdk)

	snapshotBuildInfo := getSdkSnapshotBuildInfo(t, result, sdk)

	// Check state of the snapshot build.
	for _, checker := range checkers {
		checker(snapshotBuildInfo)
	}

	// Make sure that the generated zip file is in the correct place.
	actual := snapshotBuildInfo.outputZip
	if dir != "" {
		dir = filepath.Clean(dir) + "/"
	}
	suffix := ""
	if snapshotBuildInfo.version != soongSdkSnapshotVersionUnversioned {
		suffix = "-" + snapshotBuildInfo.version
	}

	expectedZipPath := fmt.Sprintf(".intermediates/%s%s/%s/%s%s.zip", dir, name, variant, name, suffix)
	android.AssertStringEquals(t, "Snapshot zip file in wrong place", expectedZipPath, actual)

	// Populate a mock filesystem with the files that would have been copied by
	// the rules.
	fs := android.MockFS{}
	for _, dest := range snapshotBuildInfo.snapshotContents {
		fs[filepath.Join(snapshotSubDir, dest)] = nil
	}
	fs[filepath.Join(snapshotSubDir, "Android.bp")] = []byte(snapshotBuildInfo.androidBpContents)

	// If the generated snapshot builders not for the current release then it cannot be loaded by
	// the current release.
	currentBuildRelease := latestBuildRelease()
	if snapshotBuildInfo.targetBuildRelease != currentBuildRelease {
		return
	}

	// The preparers from the original source fixture.
	sourcePreparers := result.Preparer()

	// Preparer to combine the snapshot and the source.
	snapshotPreparer := android.GroupFixturePreparers(sourcePreparers, fs.AddToFixture())

	var runSnapshotTestWithCheckers = func(t *testing.T, testConfig snapshotTest, extraPreparer android.FixturePreparer) {
		t.Helper()
		customization := snapshotBuildInfo.snapshotTestCustomization(testConfig)
		customizedPreparers := android.GroupFixturePreparers(customization.preparers...)

		// TODO(b/183184375): Set Config.TestAllowNonExistentPaths = false to verify that all the
		//  files the snapshot needs are actually copied into the snapshot.

		// Run the snapshot with the snapshot preparer and the extra preparer, which must come after as
		// it may need to modify parts of the MockFS populated by the snapshot preparer.
		result := android.GroupFixturePreparers(snapshotPreparer, extraPreparer, customizedPreparers).
			ExtendWithErrorHandler(customization.errorHandler).
			RunTest(t)

		// Perform any additional checks the test need on the result of processing the snapshot.
		for _, checker := range customization.checkers {
			checker(t, result)
		}
	}

	t.Run("snapshot without source", func(t *testing.T) {
		// Remove the source Android.bp file to make sure it works without.
		removeSourceAndroidBp := android.FixtureModifyMockFS(func(fs android.MockFS) {
			delete(fs, "Android.bp")
		})

		runSnapshotTestWithCheckers(t, checkSnapshotWithoutSource, removeSourceAndroidBp)
	})

	t.Run("snapshot with source preferred", func(t *testing.T) {
		runSnapshotTestWithCheckers(t, checkSnapshotWithSourcePreferred, android.NullFixturePreparer)
	})

	t.Run("snapshot preferred with source", func(t *testing.T) {
		// Replace the snapshot/Android.bp file with one where "prefer: false," has been replaced with
		// "prefer: true,"
		preferPrebuilts := android.FixtureModifyMockFS(func(fs android.MockFS) {
			snapshotBpFile := filepath.Join(snapshotSubDir, "Android.bp")
			unpreferred := string(fs[snapshotBpFile])
			fs[snapshotBpFile] = []byte(strings.ReplaceAll(unpreferred, "prefer: false,", "prefer: true,"))
		})

		runSnapshotTestWithCheckers(t, checkSnapshotPreferredWithSource, preferPrebuilts)
	})
}

type snapshotBuildInfoChecker func(info *snapshotBuildInfo)

// Check that the snapshot's generated Android.bp is correct.
//
// Both the expected and actual string are both trimmed before comparing.
func checkAndroidBpContents(expected string) snapshotBuildInfoChecker {
	return func(info *snapshotBuildInfo) {
		info.t.Helper()
		android.AssertTrimmedStringEquals(info.t, "Android.bp contents do not match", expected, info.androidBpContents)
	}
}

// Check that the snapshot's unversioned generated Android.bp is correct.
//
// This func should be used to check the general snapshot generation code.
//
// Both the expected and actual string are both trimmed before comparing.
func checkUnversionedAndroidBpContents(expected string) snapshotBuildInfoChecker {
	return func(info *snapshotBuildInfo) {
		info.t.Helper()
		android.AssertTrimmedStringEquals(info.t, "unversioned Android.bp contents do not match", expected, info.androidUnversionedBpContents)
	}
}

// Check that the snapshot's versioned generated Android.bp is correct.
//
// This func should only be used to check the version specific snapshot generation code,
// i.e. the encoding of version into module names and the generation of the _snapshot module. The
// general snapshot generation code should be checked using the checkUnversionedAndroidBpContents()
// func.
//
// Both the expected and actual string are both trimmed before comparing.
func checkVersionedAndroidBpContents(expected string) snapshotBuildInfoChecker {
	return func(info *snapshotBuildInfo) {
		info.t.Helper()
		android.AssertTrimmedStringEquals(info.t, "versioned Android.bp contents do not match", expected, info.androidVersionedBpContents)
	}
}

// Check that the snapshot's copy rules are correct.
//
// The copy rules are formatted as <src> -> <dest>, one per line and then compared
// to the supplied expected string. Both the expected and actual string are trimmed
// before comparing.
func checkAllCopyRules(expected string) snapshotBuildInfoChecker {
	return func(info *snapshotBuildInfo) {
		info.t.Helper()
		android.AssertTrimmedStringEquals(info.t, "Incorrect copy rules", expected, info.copyRules)
	}
}

func checkAllOtherCopyRules(expected string) snapshotBuildInfoChecker {
	return func(info *snapshotBuildInfo) {
		info.t.Helper()
		android.AssertTrimmedStringEquals(info.t, "Incorrect copy rules", expected, info.otherCopyRules)
	}
}

// Check that the specified paths match the list of zips to merge with the intermediate zip.
func checkMergeZips(expected ...string) snapshotBuildInfoChecker {
	return func(info *snapshotBuildInfo) {
		info.t.Helper()
		if info.intermediateZip == "" {
			info.t.Errorf("No intermediate zip file was created")
		}

		android.AssertDeepEquals(info.t, "mismatching merge zip files", expected, info.mergeZips)
	}
}

type resultChecker func(t *testing.T, result *android.TestResult)

// snapshotTestPreparer registers a preparer that will be used to customize the specified
// snapshotTest.
func snapshotTestPreparer(snapshotTest snapshotTest, preparer android.FixturePreparer) snapshotBuildInfoChecker {
	return func(info *snapshotBuildInfo) {
		customization := info.snapshotTestCustomization(snapshotTest)
		customization.preparers = append(customization.preparers, preparer)
	}
}

// snapshotTestChecker registers a checker that will be run against the result of processing the
// generated snapshot for the specified snapshotTest.
func snapshotTestChecker(snapshotTest snapshotTest, checker resultChecker) snapshotBuildInfoChecker {
	return func(info *snapshotBuildInfo) {
		customization := info.snapshotTestCustomization(snapshotTest)
		customization.checkers = append(customization.checkers, checker)
	}
}

// snapshotTestErrorHandler registers an error handler to use when processing the snapshot
// in the specific test case.
//
// Generally, the snapshot should work with all the test cases but some do not and just in case
// there are a lot of issues to resolve, or it will take a lot of time this is a
// get-out-of-jail-free card that allows progress to be made.
//
// deprecated: should only be used as a temporary workaround with an attached to do and bug.
func snapshotTestErrorHandler(snapshotTest snapshotTest, handler android.FixtureErrorHandler) snapshotBuildInfoChecker {
	return func(info *snapshotBuildInfo) {
		customization := info.snapshotTestCustomization(snapshotTest)
		customization.errorHandler = handler
	}
}

// Encapsulates information provided by each test to customize a specific snapshotTest.
type snapshotTestCustomization struct {
	// Preparers that are used to customize the test fixture before running the test.
	preparers []android.FixturePreparer

	// Checkers that are run on the result of processing the preferred snapshot in a specific test
	// case.
	checkers []resultChecker

	// Specify an error handler for when processing a specific test case.
	//
	// In some cases the generated snapshot cannot be used in a test configuration. Those cases are
	// invariably bugs that need to be resolved but sometimes that can take a while. This provides a
	// mechanism to temporarily ignore that error.
	errorHandler android.FixtureErrorHandler
}

// Encapsulates information about the snapshot build structure in order to insulate tests from
// knowing too much about internal structures.
//
// All source/input paths are relative either the build directory. All dest/output paths are
// relative to the snapshot root directory.
type snapshotBuildInfo struct {
	t *testing.T

	// The result from RunTest()
	r *android.TestResult

	// The version of the generated snapshot.
	//
	// See snapshotBuilder.version for more information about this field.
	version string

	// The contents of the generated Android.bp file
	androidBpContents string

	// The contents of the unversioned Android.bp file
	androidUnversionedBpContents string

	// The contents of the versioned Android.bp file
	androidVersionedBpContents string

	// The paths, relative to the snapshot root, of all files and directories copied into the
	// snapshot.
	snapshotContents []string

	// A formatted representation of the src/dest pairs for a snapshot, one pair per line,
	// of the format src -> dest
	copyRules string

	// A formatted representation of the src/dest pairs for files not in a snapshot, one pair
	// per line, of the format src -> dest
	otherCopyRules string

	// The path to the intermediate zip, which is a zip created from the source files copied
	// into the snapshot directory and which will be merged with other zips to form the final output.
	// Is am empty string if there is no intermediate zip because there are no zips to merge in.
	intermediateZip string

	// The paths to the zips to merge into the output zip, does not include the intermediate
	// zip.
	mergeZips []string

	// The final output zip.
	outputZip string

	// The target build release.
	targetBuildRelease *buildRelease

	// The test specific customizations for each snapshot test.
	snapshotTestCustomizations map[snapshotTest]*snapshotTestCustomization
}

// snapshotTestCustomization gets the test specific customization for the specified snapshotTest.
//
// If no customization was created previously then it creates a default customization.
func (i *snapshotBuildInfo) snapshotTestCustomization(snapshotTest snapshotTest) *snapshotTestCustomization {
	customization := i.snapshotTestCustomizations[snapshotTest]
	if customization == nil {
		customization = &snapshotTestCustomization{
			errorHandler: android.FixtureExpectsNoErrors,
		}
		i.snapshotTestCustomizations[snapshotTest] = customization
	}
	return customization
}
