// Copyright 2021 The Android Open Source Project
//
// 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 selinux

import (
	"path/filepath"
	"sort"

	"android/soong/android"
)

func init() {
	ctx := android.InitRegistrationContext
	ctx.RegisterParallelSingletonModuleType("se_freeze_test", freezeTestFactory)
}

// se_freeze_test compares the plat sepolicy with the prebuilt sepolicy.  Additional directories can
// be specified via Makefile variables: SEPOLICY_FREEZE_TEST_EXTRA_DIRS and
// SEPOLICY_FREEZE_TEST_EXTRA_PREBUILT_DIRS.
func freezeTestFactory() android.SingletonModule {
	f := &freezeTestModule{}
	android.InitAndroidModule(f)
	return f
}

type freezeTestModule struct {
	android.SingletonModuleBase
	freezeTestTimestamp android.ModuleOutPath
}

func (f *freezeTestModule) GenerateSingletonBuildActions(ctx android.SingletonContext) {
	// does nothing; se_freeze_test is a singeton because two freeze test modules don't make sense.
}

func (f *freezeTestModule) GenerateAndroidBuildActions(ctx android.ModuleContext) {
	platformVersion := ctx.DeviceConfig().PlatformSepolicyVersion()
	totVersion := ctx.DeviceConfig().TotSepolicyVersion()

	extraDirs := ctx.DeviceConfig().SepolicyFreezeTestExtraDirs()
	extraPrebuiltDirs := ctx.DeviceConfig().SepolicyFreezeTestExtraPrebuiltDirs()
	f.freezeTestTimestamp = android.PathForModuleOut(ctx, "freeze_test")

	if platformVersion == totVersion {
		if len(extraDirs) > 0 || len(extraPrebuiltDirs) > 0 {
			ctx.ModuleErrorf("SEPOLICY_FREEZE_TEST_EXTRA_DIRS or SEPOLICY_FREEZE_TEST_EXTRA_PREBUILT_DIRS cannot be set before system/sepolicy freezes.")
			return
		}

		// we still build a rule to prevent possible regression
		android.WriteFileRule(ctx, f.freezeTestTimestamp, ";; no freeze tests needed before system/sepolicy freezes")
		return
	}

	if len(extraDirs) != len(extraPrebuiltDirs) {
		ctx.ModuleErrorf("SEPOLICY_FREEZE_TEST_EXTRA_DIRS and SEPOLICY_FREEZE_TEST_EXTRA_PREBUILT_DIRS must have the same number of directories.")
		return
	}

	platPublic := filepath.Join(ctx.ModuleDir(), "public")
	platPrivate := filepath.Join(ctx.ModuleDir(), "private")
	prebuiltPublic := filepath.Join(ctx.ModuleDir(), "prebuilts", "api", platformVersion, "public")
	prebuiltPrivate := filepath.Join(ctx.ModuleDir(), "prebuilts", "api", platformVersion, "private")

	sourceDirs := append(extraDirs, platPublic, platPrivate)
	prebuiltDirs := append(extraPrebuiltDirs, prebuiltPublic, prebuiltPrivate)

	var implicits []string
	for _, dir := range append(sourceDirs, prebuiltDirs...) {
		glob, err := ctx.GlobWithDeps(dir+"/**/*", []string{"bug_map"} /* exclude */)
		if err != nil {
			ctx.ModuleErrorf("failed to glob sepolicy dir %q: %s", dir, err.Error())
			return
		}
		implicits = append(implicits, glob...)
	}
	sort.Strings(implicits)

	rule := android.NewRuleBuilder(pctx, ctx)

	for idx, _ := range sourceDirs {
		rule.Command().Text("diff").
			Flag("-r").
			Flag("-q").
			FlagWithArg("-x ", "bug_map"). // exclude
			Text(sourceDirs[idx]).
			Text(prebuiltDirs[idx])
	}

	rule.Command().Text("touch").
		Output(f.freezeTestTimestamp).
		Implicits(android.PathsForSource(ctx, implicits))

	rule.Build("sepolicy_freeze_test", "sepolicy_freeze_test")
}

func (f *freezeTestModule) AndroidMkEntries() []android.AndroidMkEntries {
	return []android.AndroidMkEntries{android.AndroidMkEntries{
		Class: "FAKE",
		// OutputFile is needed, even though BUILD_PHONY_PACKAGE doesn't use it.
		// Without OutputFile this module won't be exported to Makefile.
		OutputFile: android.OptionalPathForPath(f.freezeTestTimestamp),
		Include:    "$(BUILD_PHONY_PACKAGE)",
		ExtraEntries: []android.AndroidMkExtraEntriesFunc{
			func(ctx android.AndroidMkExtraEntriesContext, entries *android.AndroidMkEntries) {
				entries.SetString("LOCAL_ADDITIONAL_DEPENDENCIES", f.freezeTestTimestamp.String())
			},
		},
	}}
}
