// 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"
	"io/ioutil"
	"os"
	"path/filepath"
	"strings"
	"testing"

	"android/soong/android"
	"android/soong/apex"
	"android/soong/cc"
	"android/soong/java"
)

func testSdkContext(bp string, fs map[string][]byte) (*android.TestContext, android.Config) {
	bp = bp + `
		apex_key {
			name: "myapex.key",
			public_key: "myapex.avbpubkey",
			private_key: "myapex.pem",
		}

		android_app_certificate {
			name: "myapex.cert",
			certificate: "myapex",
		}
	` + cc.GatherRequiredDepsForTest(android.Android)

	mockFS := map[string][]byte{
		"build/make/target/product/security":         nil,
		"apex_manifest.json":                         nil,
		"system/sepolicy/apex/myapex-file_contexts":  nil,
		"system/sepolicy/apex/myapex2-file_contexts": nil,
		"myapex.avbpubkey":                           nil,
		"myapex.pem":                                 nil,
		"myapex.x509.pem":                            nil,
		"myapex.pk8":                                 nil,
	}

	for k, v := range fs {
		mockFS[k] = v
	}

	config := android.TestArchConfig(buildDir, nil, bp, mockFS)

	ctx := android.NewTestArchContext()

	// from android package
	ctx.PreArchMutators(android.RegisterPackageRenamer)
	ctx.PreArchMutators(android.RegisterVisibilityRuleChecker)
	ctx.PreArchMutators(android.RegisterDefaultsPreArchMutators)
	ctx.PreArchMutators(android.RegisterVisibilityRuleGatherer)
	ctx.PostDepsMutators(android.RegisterVisibilityRuleEnforcer)

	ctx.RegisterModuleType("package", android.PackageFactory)

	// from java package
	java.RegisterJavaBuildComponents(ctx)
	java.RegisterAppBuildComponents(ctx)
	java.RegisterStubsBuildComponents(ctx)

	// from cc package
	cc.RegisterRequiredBuildComponentsForTest(ctx)

	// from apex package
	ctx.RegisterModuleType("apex", apex.BundleFactory)
	ctx.RegisterModuleType("apex_key", apex.ApexKeyFactory)
	ctx.PostDepsMutators(apex.RegisterPostDepsMutators)

	// from this package
	ctx.RegisterModuleType("sdk", ModuleFactory)
	ctx.RegisterModuleType("sdk_snapshot", SnapshotModuleFactory)
	ctx.PreDepsMutators(RegisterPreDepsMutators)
	ctx.PostDepsMutators(RegisterPostDepsMutators)

	ctx.Register(config)

	return ctx, config
}

func testSdkWithFs(t *testing.T, bp string, fs map[string][]byte) *testSdkResult {
	t.Helper()
	ctx, config := testSdkContext(bp, fs)
	_, errs := ctx.ParseBlueprintsFiles(".")
	android.FailIfErrored(t, errs)
	_, errs = ctx.PrepareBuildActions(config)
	android.FailIfErrored(t, errs)
	return &testSdkResult{
		TestHelper: TestHelper{t: t},
		ctx:        ctx,
		config:     config,
	}
}

func testSdkError(t *testing.T, pattern, bp string) {
	t.Helper()
	ctx, config := testSdkContext(bp, nil)
	_, errs := ctx.ParseFileList(".", []string{"Android.bp"})
	if len(errs) > 0 {
		android.FailIfNoMatchingErrors(t, pattern, errs)
		return
	}
	_, errs = ctx.PrepareBuildActions(config)
	if len(errs) > 0 {
		android.FailIfNoMatchingErrors(t, pattern, errs)
		return
	}

	t.Fatalf("missing expected error %q (0 errors are returned)", pattern)
}

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
}

// Provides general test support.
type TestHelper struct {
	t *testing.T
}

func (h *TestHelper) AssertStringEquals(message string, expected string, actual string) {
	h.t.Helper()
	if actual != expected {
		h.t.Errorf("%s: expected %s, actual %s", message, expected, actual)
	}
}

func (h *TestHelper) AssertTrimmedStringEquals(message string, expected string, actual string) {
	h.t.Helper()
	h.AssertStringEquals(message, strings.TrimSpace(expected), strings.TrimSpace(actual))
}

// Encapsulates result of processing an SDK definition. Provides support for
// checking the state of the build structures.
type testSdkResult struct {
	TestHelper
	ctx    *android.TestContext
	config android.Config
}

// 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 (r *testSdkResult) getSdkSnapshotBuildInfo(sdk *sdk) *snapshotBuildInfo {
	androidBpContents := strings.NewReplacer("\\n", "\n").Replace(sdk.GetAndroidBpContentsForTests())

	info := &snapshotBuildInfo{
		r:                 r,
		androidBpContents: androidBpContents,
	}

	buildParams := sdk.BuildParamsForTests()
	copyRules := &strings.Builder{}
	for _, bp := range buildParams {
		switch bp.Rule.String() {
		case android.Cp.String():
			// Get source relative to build directory.
			src := android.NormalizePathForTesting(bp.Input)
			// Get destination relative to the snapshot root
			dest := bp.Output.Rel()
			_, _ = fmt.Fprintf(copyRules, "%s -> %s\n", src, dest)
			info.snapshotContents = append(info.snapshotContents, 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 {
				r.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)
		}
	}

	info.copyRules = copyRules.String()

	return info
}

func (r *testSdkResult) Module(name string, variant string) android.Module {
	return r.ctx.ModuleForTests(name, variant).Module()
}

func (r *testSdkResult) ModuleForTests(name string, variant string) android.TestingModule {
	return r.ctx.ModuleForTests(name, variant)
}

// 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 (r *testSdkResult) CheckSnapshot(name string, variant string, dir string, checkers ...snapshotBuildInfoChecker) {
	r.t.Helper()

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

	snapshotBuildInfo := r.getSdkSnapshotBuildInfo(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) + "/"
	}
	r.AssertStringEquals("Snapshot zip file in wrong place",
		fmt.Sprintf(".intermediates/%s%s/%s/%s-current.zip", dir, name, variant, name), actual)

	// Populate a mock filesystem with the files that would have been copied by
	// the rules.
	fs := make(map[string][]byte)
	for _, dest := range snapshotBuildInfo.snapshotContents {
		fs[dest] = nil
	}

	// Process the generated bp file to make sure it is valid.
	testSdkWithFs(r.t, snapshotBuildInfo.androidBpContents, fs)
}

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.r.t.Helper()
		info.r.AssertTrimmedStringEquals("Android.bp contents do not match", expected, info.androidBpContents)
	}
}

// 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.r.t.Helper()
		info.r.AssertTrimmedStringEquals("Incorrect copy rules", expected, info.copyRules)
	}
}

// Check that the specified path is in the list of zips to merge with the intermediate zip.
func checkMergeZip(expected string) snapshotBuildInfoChecker {
	return func(info *snapshotBuildInfo) {
		info.r.t.Helper()
		if info.intermediateZip == "" {
			info.r.t.Errorf("No intermediate zip file was created")
		}
		ensureListContains(info.r.t, info.mergeZips, expected)
	}
}

// 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 {
	r *testSdkResult

	// The contents of the generated Android.bp file
	androidBpContents 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, one pair per line, of the format
	// src -> dest
	copyRules 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
}

var buildDir string

func setUp() {
	var err error
	buildDir, err = ioutil.TempDir("", "soong_sdk_test")
	if err != nil {
		panic(err)
	}
}

func tearDown() {
	_ = os.RemoveAll(buildDir)
}

func runTestWithBuildDir(m *testing.M) {
	run := func() int {
		setUp()
		defer tearDown()

		return m.Run()
	}

	os.Exit(run())
}

func SkipIfNotLinux(t *testing.T) {
	t.Helper()
	if android.BuildOs != android.Linux {
		t.Skipf("Skipping as sdk snapshot generation is only supported on %s not %s", android.Linux, android.BuildOs)
	}
}
