// Copyright (C) 2019 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 (
	"fmt"
	"io"
	"os"

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

	"android/soong/android"
	"android/soong/sysprop"
)

type selinuxContextsProperties struct {
	// Filenames under sepolicy directories, which will be used to generate contexts file.
	Srcs []string `android:"path"`

	// Output file name. Defaults to module name
	Stem *string

	Product_variables struct {
		Address_sanitize struct {
			Srcs []string `android:"path"`
		}
	}

	// Whether the comments in generated contexts file will be removed or not.
	Remove_comment *bool

	// Whether the result context file is sorted with fc_sort or not.
	Fc_sort *bool

	// Make this module available when building for recovery
	Recovery_available *bool
}

type seappProperties struct {
	// Files containing neverallow rules.
	Neverallow_files []string `android:"path"`

	// Precompiled sepolicy binary file which will be fed to checkseapp.
	Sepolicy *string `android:"path"`
}

type selinuxContextsModule struct {
	android.ModuleBase

	properties      selinuxContextsProperties
	seappProperties seappProperties
	build           func(ctx android.ModuleContext, inputs android.Paths) android.Path
	deps            func(ctx android.BottomUpMutatorContext)
	outputPath      android.Path
	installPath     android.InstallPath
}

var (
	reuseContextsDepTag  = dependencyTag{name: "reuseContexts"}
	syspropLibraryDepTag = dependencyTag{name: "sysprop_library"}
)

func init() {
	pctx.HostBinToolVariable("fc_sort", "fc_sort")

	android.RegisterModuleType("file_contexts", fileFactory)
	android.RegisterModuleType("hwservice_contexts", hwServiceFactory)
	android.RegisterModuleType("property_contexts", propertyFactory)
	android.RegisterModuleType("service_contexts", serviceFactory)
	android.RegisterModuleType("keystore2_key_contexts", keystoreKeyFactory)
	android.RegisterModuleType("seapp_contexts", seappFactory)
	android.RegisterModuleType("vndservice_contexts", vndServiceFactory)

	android.RegisterModuleType("file_contexts_test", fileContextsTestFactory)
	android.RegisterModuleType("property_contexts_test", propertyContextsTestFactory)
	android.RegisterModuleType("hwservice_contexts_test", hwserviceContextsTestFactory)
	android.RegisterModuleType("service_contexts_test", serviceContextsTestFactory)
	android.RegisterModuleType("vndservice_contexts_test", vndServiceContextsTestFactory)
}

func (m *selinuxContextsModule) InstallInRoot() bool {
	return m.InRecovery()
}

func (m *selinuxContextsModule) InstallInRecovery() bool {
	// ModuleBase.InRecovery() checks the image variant
	return m.InRecovery()
}

func (m *selinuxContextsModule) onlyInRecovery() bool {
	// ModuleBase.InstallInRecovery() checks commonProperties.Recovery property
	return m.ModuleBase.InstallInRecovery()
}

func (m *selinuxContextsModule) DepsMutator(ctx android.BottomUpMutatorContext) {
	if m.deps != nil {
		m.deps(ctx)
	}

	if m.InRecovery() && !m.onlyInRecovery() {
		ctx.AddFarVariationDependencies([]blueprint.Variation{
			{Mutator: "image", Variation: android.CoreVariation},
		}, reuseContextsDepTag, ctx.ModuleName())
	}
}

func (m *selinuxContextsModule) propertyContextsDeps(ctx android.BottomUpMutatorContext) {
	for _, lib := range sysprop.SyspropLibraries(ctx.Config()) {
		ctx.AddFarVariationDependencies([]blueprint.Variation{}, syspropLibraryDepTag, lib)
	}
}

func (m *selinuxContextsModule) stem() string {
	return proptools.StringDefault(m.properties.Stem, m.Name())
}

func (m *selinuxContextsModule) GenerateAndroidBuildActions(ctx android.ModuleContext) {
	if m.InRecovery() {
		// Installing context files at the root of the recovery partition
		m.installPath = android.PathForModuleInstall(ctx)
	} else {
		m.installPath = android.PathForModuleInstall(ctx, "etc", "selinux")
	}

	if m.InRecovery() && !m.onlyInRecovery() {
		dep := ctx.GetDirectDepWithTag(m.Name(), reuseContextsDepTag)

		if reuseDeps, ok := dep.(*selinuxContextsModule); ok {
			m.outputPath = reuseDeps.outputPath
			ctx.InstallFile(m.installPath, m.stem(), m.outputPath)
			return
		}
	}

	m.outputPath = m.build(ctx, android.PathsForModuleSrc(ctx, m.properties.Srcs))
	ctx.InstallFile(m.installPath, m.stem(), m.outputPath)
}

func newModule() *selinuxContextsModule {
	m := &selinuxContextsModule{}
	m.AddProperties(
		&m.properties,
		&m.seappProperties,
	)
	android.InitAndroidArchModule(m, android.DeviceSupported, android.MultilibCommon)
	android.AddLoadHook(m, func(ctx android.LoadHookContext) {
		m.selinuxContextsHook(ctx)
	})
	return m
}

func (m *selinuxContextsModule) selinuxContextsHook(ctx android.LoadHookContext) {
	// TODO: clean this up to use build/soong/android/variable.go after b/79249983
	var srcs []string

	for _, sanitize := range ctx.Config().SanitizeDevice() {
		if sanitize == "address" {
			srcs = append(srcs, m.properties.Product_variables.Address_sanitize.Srcs...)
			break
		}
	}

	m.properties.Srcs = append(m.properties.Srcs, srcs...)
}

func (m *selinuxContextsModule) AndroidMk() android.AndroidMkData {
	nameSuffix := ""
	if m.InRecovery() && !m.onlyInRecovery() {
		nameSuffix = ".recovery"
	}
	return android.AndroidMkData{
		Class:      "ETC",
		OutputFile: android.OptionalPathForPath(m.outputPath),
		SubName:    nameSuffix,
		Extra: []android.AndroidMkExtraFunc{
			func(w io.Writer, outputFile android.Path) {
				fmt.Fprintln(w, "LOCAL_MODULE_PATH :=", m.installPath.String())
				fmt.Fprintln(w, "LOCAL_INSTALLED_MODULE_STEM :=", m.stem())
			},
		},
	}
}

func (m *selinuxContextsModule) ImageMutatorBegin(ctx android.BaseModuleContext) {
	if proptools.Bool(m.properties.Recovery_available) && m.ModuleBase.InstallInRecovery() {
		ctx.PropertyErrorf("recovery_available",
			"doesn't make sense at the same time as `recovery: true`")
	}
}

func (m *selinuxContextsModule) CoreVariantNeeded(ctx android.BaseModuleContext) bool {
	return !m.ModuleBase.InstallInRecovery()
}

func (m *selinuxContextsModule) RamdiskVariantNeeded(ctx android.BaseModuleContext) bool {
	return false
}

func (m *selinuxContextsModule) VendorRamdiskVariantNeeded(ctx android.BaseModuleContext) bool {
	return false
}

func (m *selinuxContextsModule) DebugRamdiskVariantNeeded(ctx android.BaseModuleContext) bool {
	return false
}

func (m *selinuxContextsModule) RecoveryVariantNeeded(ctx android.BaseModuleContext) bool {
	return m.ModuleBase.InstallInRecovery() || proptools.Bool(m.properties.Recovery_available)
}

func (m *selinuxContextsModule) ExtraImageVariations(ctx android.BaseModuleContext) []string {
	return nil
}

func (m *selinuxContextsModule) SetImageVariation(ctx android.BaseModuleContext, variation string, module android.Module) {
}

var _ android.ImageInterface = (*selinuxContextsModule)(nil)

func (m *selinuxContextsModule) buildGeneralContexts(ctx android.ModuleContext, inputs android.Paths) android.Path {
	builtContext := pathForModuleOut(ctx, ctx.ModuleName()+"_m4out")

	rule := android.NewRuleBuilder(pctx, ctx)

	newlineFile := pathForModuleOut(ctx, "newline")

	rule.Command().Text("echo").FlagWithOutput("> ", newlineFile)
	rule.Temporary(newlineFile)

	var inputsWithNewline android.Paths
	for _, input := range inputs {
		inputsWithNewline = append(inputsWithNewline, input, newlineFile)
	}

	rule.Command().
		Tool(ctx.Config().PrebuiltBuildTool(ctx, "m4")).
		Text("--fatal-warnings -s").
		FlagForEachArg("-D", ctx.DeviceConfig().SepolicyM4Defs()).
		Inputs(inputsWithNewline).
		FlagWithOutput("> ", builtContext)

	if proptools.Bool(m.properties.Remove_comment) {
		rule.Temporary(builtContext)

		remove_comment_output := pathForModuleOut(ctx, ctx.ModuleName()+"_remove_comment")

		rule.Command().
			Text("sed -e 's/#.*$//' -e '/^$/d'").
			Input(builtContext).
			FlagWithOutput("> ", remove_comment_output)

		builtContext = remove_comment_output
	}

	if proptools.Bool(m.properties.Fc_sort) {
		rule.Temporary(builtContext)

		sorted_output := pathForModuleOut(ctx, ctx.ModuleName()+"_sorted")

		rule.Command().
			Tool(ctx.Config().HostToolPath(ctx, "fc_sort")).
			FlagWithInput("-i ", builtContext).
			FlagWithOutput("-o ", sorted_output)

		builtContext = sorted_output
	}

	ret := pathForModuleOut(ctx, m.stem())
	rule.Temporary(builtContext)
	rule.Command().Text("cp").Input(builtContext).Output(ret)

	rule.DeleteTemporaryFiles()
	rule.Build("selinux_contexts", "building contexts: "+m.Name())

	return ret
}

func (m *selinuxContextsModule) buildFileContexts(ctx android.ModuleContext, inputs android.Paths) android.Path {
	if m.properties.Fc_sort == nil {
		m.properties.Fc_sort = proptools.BoolPtr(true)
	}
	return m.buildGeneralContexts(ctx, inputs)
}

func fileFactory() android.Module {
	m := newModule()
	m.build = m.buildFileContexts
	return m
}

func (m *selinuxContextsModule) buildServiceContexts(ctx android.ModuleContext, inputs android.Paths) android.Path {
	if m.properties.Remove_comment == nil {
		m.properties.Remove_comment = proptools.BoolPtr(true)
	}

	return m.buildGeneralContexts(ctx, inputs)
}

func (m *selinuxContextsModule) checkVendorPropertyNamespace(ctx android.ModuleContext, inputs android.Paths) android.Paths {
	shippingApiLevel := ctx.DeviceConfig().ShippingApiLevel()
	ApiLevelR := android.ApiLevelOrPanic(ctx, "R")

	rule := android.NewRuleBuilder(pctx, ctx)

	// This list is from vts_treble_sys_prop_test.
	allowedPropertyPrefixes := []string{
		"ctl.odm.",
		"ctl.vendor.",
		"ctl.start$odm.",
		"ctl.start$vendor.",
		"ctl.stop$odm.",
		"ctl.stop$vendor.",
		"init.svc.odm.",
		"init.svc.vendor.",
		"ro.boot.",
		"ro.hardware.",
		"ro.odm.",
		"ro.vendor.",
		"odm.",
		"persist.odm.",
		"persist.vendor.",
		"vendor.",
	}

	// persist.camera is also allowed for devices launching with R or eariler
	if shippingApiLevel.LessThanOrEqualTo(ApiLevelR) {
		allowedPropertyPrefixes = append(allowedPropertyPrefixes, "persist.camera.")
	}

	var allowedContextPrefixes []string

	if shippingApiLevel.GreaterThanOrEqualTo(ApiLevelR) {
		// This list is from vts_treble_sys_prop_test.
		allowedContextPrefixes = []string{
			"vendor_",
			"odm_",
		}
	}

	var ret android.Paths
	for _, input := range inputs {
		cmd := rule.Command().
			BuiltTool("check_prop_prefix").
			FlagWithInput("--property-contexts ", input).
			FlagForEachArg("--allowed-property-prefix ", proptools.ShellEscapeList(allowedPropertyPrefixes)). // contains shell special character '$'
			FlagForEachArg("--allowed-context-prefix ", allowedContextPrefixes)

		if !ctx.DeviceConfig().BuildBrokenVendorPropertyNamespace() {
			cmd.Flag("--strict")
		}

		out := pathForModuleOut(ctx, "namespace_checked").Join(ctx, input.String())
		rule.Command().Text("cp -f").Input(input).Output(out)
		ret = append(ret, out)
	}
	rule.Build("check_namespace", "checking namespace of "+ctx.ModuleName())
	return ret
}

func (m *selinuxContextsModule) buildPropertyContexts(ctx android.ModuleContext, inputs android.Paths) android.Path {
	// vendor/odm properties are enforced for devices launching with Android Q or later. So, if
	// vendor/odm, make sure that only vendor/odm properties exist.
	shippingApiLevel := ctx.DeviceConfig().ShippingApiLevel()
	ApiLevelQ := android.ApiLevelOrPanic(ctx, "Q")
	if (ctx.SocSpecific() || ctx.DeviceSpecific()) && shippingApiLevel.GreaterThanOrEqualTo(ApiLevelQ) {
		inputs = m.checkVendorPropertyNamespace(ctx, inputs)
	}

	builtCtxFile := m.buildGeneralContexts(ctx, inputs)

	var apiFiles android.Paths
	ctx.VisitDirectDepsWithTag(syspropLibraryDepTag, func(c android.Module) {
		i, ok := c.(interface{ CurrentSyspropApiFile() android.OptionalPath })
		if !ok {
			panic(fmt.Errorf("unknown dependency %q for %q", ctx.OtherModuleName(c), ctx.ModuleName()))
		}
		if api := i.CurrentSyspropApiFile(); api.Valid() {
			apiFiles = append(apiFiles, api.Path())
		}
	})

	// check compatibility with sysprop_library
	if len(apiFiles) > 0 {
		out := pathForModuleOut(ctx, ctx.ModuleName()+"_api_checked")
		rule := android.NewRuleBuilder(pctx, ctx)

		msg := `\n******************************\n` +
			`API of sysprop_library doesn't match with property_contexts\n` +
			`Please fix the breakage and rebuild.\n` +
			`******************************\n`

		rule.Command().
			Text("( ").
			BuiltTool("sysprop_type_checker").
			FlagForEachInput("--api ", apiFiles).
			FlagWithInput("--context ", builtCtxFile).
			Text(" || ( echo").Flag("-e").
			Flag(`"` + msg + `"`).
			Text("; exit 38) )")

		rule.Command().Text("cp -f").Input(builtCtxFile).Output(out)
		rule.Build("property_contexts_check_api", "checking API: "+m.Name())
		builtCtxFile = out
	}

	return builtCtxFile
}

func (m *selinuxContextsModule) buildSeappContexts(ctx android.ModuleContext, inputs android.Paths) android.Path {
	neverallowFile := pathForModuleOut(ctx, "neverallow")
	ret := pathForModuleOut(ctx, m.stem())

	rule := android.NewRuleBuilder(pctx, ctx)
	rule.Command().Text("(grep").
		Flag("-ihe").
		Text("'^neverallow'").
		Inputs(android.PathsForModuleSrc(ctx, m.seappProperties.Neverallow_files)).
		Text(os.DevNull). // to make grep happy even when Neverallow_files is empty
		Text(">").
		Output(neverallowFile).
		Text("|| true)") // to make ninja happy even when result is empty

	rule.Temporary(neverallowFile)
	rule.Command().BuiltTool("checkseapp").
		FlagWithInput("-p ", android.PathForModuleSrc(ctx, proptools.String(m.seappProperties.Sepolicy))).
		FlagWithOutput("-o ", ret).
		Inputs(inputs).
		Input(neverallowFile)

	rule.Build("seapp_contexts", "Building seapp_contexts: "+m.Name())
	return ret
}

func hwServiceFactory() android.Module {
	m := newModule()
	m.build = m.buildServiceContexts
	return m
}

func propertyFactory() android.Module {
	m := newModule()
	m.build = m.buildPropertyContexts
	m.deps = m.propertyContextsDeps
	return m
}

func serviceFactory() android.Module {
	m := newModule()
	m.build = m.buildServiceContexts
	return m
}

func keystoreKeyFactory() android.Module {
	m := newModule()
	m.build = m.buildGeneralContexts
	return m
}

func seappFactory() android.Module {
	m := newModule()
	m.build = m.buildSeappContexts
	return m
}

func vndServiceFactory() android.Module {
	m := newModule()
	m.build = m.buildGeneralContexts
	android.AddLoadHook(m, func(ctx android.LoadHookContext) {
		if !ctx.SocSpecific() {
			ctx.ModuleErrorf(m.Name(), "must set vendor: true")
			return
		}
	})
	return m
}

var _ android.OutputFileProducer = (*selinuxContextsModule)(nil)

// Implements android.OutputFileProducer
func (m *selinuxContextsModule) OutputFiles(tag string) (android.Paths, error) {
	if tag == "" {
		return []android.Path{m.outputPath}, nil
	}
	return nil, fmt.Errorf("unsupported module reference tag %q", tag)
}

type contextsTestProperties struct {
	// Contexts files to be tested.
	Srcs []string `android:"path"`

	// Precompiled sepolicy binary to be tesed together.
	Sepolicy *string `android:"path"`
}

type contextsTestModule struct {
	android.ModuleBase

	// Name of the test tool. "checkfc" or "property_info_checker"
	tool string

	// Additional flags to be passed to the tool.
	flags []string

	properties    contextsTestProperties
	testTimestamp android.OutputPath
}

// checkfc parses a context file and checks for syntax errors.
// If -s is specified, the service backend is used to verify binder services.
// If -l is specified, the service backend is used to verify hwbinder services.
// Otherwise, context_file is assumed to be a file_contexts file
// If -e is specified, then the context_file is allowed to be empty.

// file_contexts_test tests given file_contexts files with checkfc.
func fileContextsTestFactory() android.Module {
	m := &contextsTestModule{tool: "checkfc" /* no flags: file_contexts file check */}
	m.AddProperties(&m.properties)
	android.InitAndroidArchModule(m, android.DeviceSupported, android.MultilibCommon)
	return m
}

// property_contexts_test tests given property_contexts files with property_info_checker.
func propertyContextsTestFactory() android.Module {
	m := &contextsTestModule{tool: "property_info_checker"}
	m.AddProperties(&m.properties)
	android.InitAndroidArchModule(m, android.DeviceSupported, android.MultilibCommon)
	return m
}

// hwservice_contexts_test tests given hwservice_contexts files with checkfc.
func hwserviceContextsTestFactory() android.Module {
	m := &contextsTestModule{tool: "checkfc", flags: []string{"-e" /* allow empty */, "-l" /* hwbinder services */}}
	m.AddProperties(&m.properties)
	android.InitAndroidArchModule(m, android.DeviceSupported, android.MultilibCommon)
	return m
}

// service_contexts_test tests given service_contexts files with checkfc.
func serviceContextsTestFactory() android.Module {
	// checkfc -s: service_contexts test
	m := &contextsTestModule{tool: "checkfc", flags: []string{"-s" /* binder services */}}
	m.AddProperties(&m.properties)
	android.InitAndroidArchModule(m, android.DeviceSupported, android.MultilibCommon)
	return m
}

// vndservice_contexts_test tests given vndservice_contexts files with checkfc.
func vndServiceContextsTestFactory() android.Module {
	m := &contextsTestModule{tool: "checkfc", flags: []string{"-e" /* allow empty */, "-v" /* vnd service */}}
	m.AddProperties(&m.properties)
	android.InitAndroidArchModule(m, android.DeviceSupported, android.MultilibCommon)
	return m
}

func (m *contextsTestModule) GenerateAndroidBuildActions(ctx android.ModuleContext) {
	tool := m.tool
	if tool != "checkfc" && tool != "property_info_checker" {
		panic(fmt.Errorf("%q: unknown tool name: %q", ctx.ModuleName(), tool))
	}

	if len(m.properties.Srcs) == 0 {
		ctx.PropertyErrorf("srcs", "can't be empty")
		return
	}

	if proptools.String(m.properties.Sepolicy) == "" {
		ctx.PropertyErrorf("sepolicy", "can't be empty")
		return
	}

	srcs := android.PathsForModuleSrc(ctx, m.properties.Srcs)
	sepolicy := android.PathForModuleSrc(ctx, proptools.String(m.properties.Sepolicy))

	rule := android.NewRuleBuilder(pctx, ctx)
	rule.Command().BuiltTool(tool).
		Flags(m.flags).
		Input(sepolicy).
		Inputs(srcs)

	m.testTimestamp = pathForModuleOut(ctx, "timestamp")
	rule.Command().Text("touch").Output(m.testTimestamp)
	rule.Build("contexts_test", "running contexts test: "+ctx.ModuleName())
}

func (m *contextsTestModule) 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(m.testTimestamp),
		Include:    "$(BUILD_PHONY_PACKAGE)",
		ExtraEntries: []android.AndroidMkExtraEntriesFunc{
			func(ctx android.AndroidMkExtraEntriesContext, entries *android.AndroidMkEntries) {
				entries.SetString("LOCAL_ADDITIONAL_DEPENDENCIES", m.testTimestamp.String())
			},
		},
	}}
}

// contextsTestModule implements ImageInterface to be able to include recovery_available contexts
// modules as its sources.
func (m *contextsTestModule) ImageMutatorBegin(ctx android.BaseModuleContext) {
}

func (m *contextsTestModule) CoreVariantNeeded(ctx android.BaseModuleContext) bool {
	return true
}

func (m *contextsTestModule) RamdiskVariantNeeded(ctx android.BaseModuleContext) bool {
	return false
}

func (m *contextsTestModule) VendorRamdiskVariantNeeded(ctx android.BaseModuleContext) bool {
	return false
}

func (m *contextsTestModule) DebugRamdiskVariantNeeded(ctx android.BaseModuleContext) bool {
	return false
}

func (m *contextsTestModule) RecoveryVariantNeeded(ctx android.BaseModuleContext) bool {
	return false
}

func (m *contextsTestModule) ExtraImageVariations(ctx android.BaseModuleContext) []string {
	return nil
}

func (m *contextsTestModule) SetImageVariation(ctx android.BaseModuleContext, variation string, module android.Module) {
}

var _ android.ImageInterface = (*contextsTestModule)(nil)
