// Copyright (C) 2018 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

// This file contains "se_cil_compat_map" module type used to build and install
// sepolicy backwards compatibility mapping files.

import (
	"android/soong/android"
	"fmt"

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

var (
	combine_maps    = pctx.HostBinToolVariable("combine_maps", "combine_maps")
	combineMapsCmd  = "${combine_maps} -t ${topHalf} -b ${bottomHalf} -o $out"
	combineMapsRule = pctx.StaticRule(
		"combineMapsRule",
		blueprint.RuleParams{
			Command:     combineMapsCmd,
			CommandDeps: []string{"${combine_maps}"},
		},
		"topHalf",
		"bottomHalf",
	)

	String        = proptools.String
	TopHalfDepTag = dependencyTag{name: "top"}
)

func init() {
	android.RegisterModuleType("se_cil_compat_map", cilCompatMapFactory)
	pctx.Import("android/soong/android")
}

func cilCompatMapFactory() android.Module {
	c := &cilCompatMap{}
	c.AddProperties(&c.properties)
	android.InitAndroidArchModule(c, android.DeviceSupported, android.MultilibCommon)
	return c
}

type cilCompatMapProperties struct {
	// se_cil_compat_map module representing a compatibility mapping file for
	// platform versions (x->y). Bottom half represents a mapping (y->z).
	// Together the halves are used to generate a (x->z) mapping.
	Top_half *string `android:"path"`
	// list of source (.cil) files used to build an the bottom half of sepolicy
	// compatibility mapping file. bottom_half may reference the outputs of
	// other modules that produce source files like genrule or filegroup using
	// the syntax ":module". srcs has to be non-empty.
	Bottom_half []string `android:"path"`
	// name of the output
	Stem *string
	// Target version that this module supports. This module will be ignored if platform sepolicy
	// version is same as this module's version.
	Version *string
}

type cilCompatMap struct {
	android.ModuleBase
	properties cilCompatMapProperties
	// (.intermediate) module output path as installation source.
	installSource android.OptionalPath
	installPath   android.InstallPath
}

type CilCompatMapGenerator interface {
	GeneratedMapFile() android.OptionalPath
}

func expandTopHalf(ctx android.ModuleContext) android.OptionalPath {
	var topHalf android.OptionalPath
	ctx.VisitDirectDeps(func(dep android.Module) {
		depTag := ctx.OtherModuleDependencyTag(dep)
		switch depTag {
		case TopHalfDepTag:
			topHalf = dep.(CilCompatMapGenerator).GeneratedMapFile()
		}
	})
	return topHalf
}

func expandSeSources(ctx android.ModuleContext, srcFiles []string) android.Paths {
	return android.PathsForModuleSrc(ctx, srcFiles)
}

func (c *cilCompatMap) shouldSkipBuild(ctx android.ModuleContext) bool {
	return proptools.String(c.properties.Version) == ctx.DeviceConfig().PlatformSepolicyVersion()
}

func (c *cilCompatMap) GenerateAndroidBuildActions(ctx android.ModuleContext) {
	if c.shouldSkipBuild(ctx) {
		return
	}

	c.installPath = android.PathForModuleInstall(ctx, "etc", "selinux", "mapping")

	srcFiles := expandSeSources(ctx, c.properties.Bottom_half)

	for _, src := range srcFiles {
		if src.Ext() != ".cil" {
			ctx.PropertyErrorf("bottom_half", "%s has to be a .cil file.", src.String())
		}
	}

	bottomHalf := android.PathForModuleGen(ctx, "bottom_half")
	ctx.Build(pctx, android.BuildParams{
		Rule:   android.Cat,
		Output: bottomHalf,
		Inputs: srcFiles,
	})

	topHalf := expandTopHalf(ctx)
	if topHalf.Valid() {
		out := android.PathForModuleGen(ctx, c.Name())
		ctx.ModuleBuild(pctx, android.ModuleBuildParams{
			Rule:   combineMapsRule,
			Output: out,
			Implicits: []android.Path{
				topHalf.Path(),
				bottomHalf,
			},
			Args: map[string]string{
				"topHalf":    topHalf.String(),
				"bottomHalf": bottomHalf.String(),
			},
		})
		c.installSource = android.OptionalPathForPath(out)
	} else {
		c.installSource = android.OptionalPathForPath(bottomHalf)
	}
}

func (c *cilCompatMap) DepsMutator(ctx android.BottomUpMutatorContext) {
	if c.properties.Top_half != nil {
		ctx.AddDependency(c, TopHalfDepTag, String(c.properties.Top_half))
	}
}

func (c *cilCompatMap) AndroidMkEntries() []android.AndroidMkEntries {
	if !c.installSource.Valid() {
		return nil
	}
	return []android.AndroidMkEntries{android.AndroidMkEntries{
		Class:      "ETC",
		OutputFile: c.installSource,
		ExtraEntries: []android.AndroidMkExtraEntriesFunc{
			func(ctx android.AndroidMkExtraEntriesContext, entries *android.AndroidMkEntries) {
				entries.SetPath("LOCAL_MODULE_PATH", c.installPath)
				if c.properties.Stem != nil {
					entries.SetString("LOCAL_INSTALLED_MODULE_STEM", String(c.properties.Stem))
				}
			},
		},
	}}
}

var _ CilCompatMapGenerator = (*cilCompatMap)(nil)
var _ android.OutputFileProducer = (*cilCompatMap)(nil)

func (c *cilCompatMap) GeneratedMapFile() android.OptionalPath {
	return c.installSource
}

func (c *cilCompatMap) OutputFiles(tag string) (android.Paths, error) {
	if tag == "" {
		if c.installSource.Valid() {
			return android.Paths{c.installSource.Path()}, nil
		} else {
			return nil, nil
		}
	}
	return nil, fmt.Errorf("Unknown tag %q", tag)
}
