// Copyright 2024 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 android

import (
	"fmt"
	"reflect"
	"slices"
	"strings"

	"github.com/google/blueprint"
)

// ----------------------------------------------------------------------------
// Start of the definitions of exception functions and the lookup table.
//
// Functions cannot be used as a value passed in providers, because functions are not
// hashable. As a workaround, the [exceptionHandleFuncLabel] enum values are passed using providers,
// and the corresponding functions are called from [exceptionHandleFunctionsTable] map.
// ----------------------------------------------------------------------------

type exceptionHandleFunc func(ModuleContext, Module, ModuleProxy) bool

type StubsAvailableModule interface {
	IsStubsModule() bool
}

// Returns true if the dependency module is a stubs module
var depIsStubsModule exceptionHandleFunc = func(mctx ModuleContext, _ Module, dep ModuleProxy) bool {
	return OtherModulePointerProviderOrDefault(mctx, dep, CommonModuleInfoProvider).IsStubsModule
}

// Returns true if the dependency module belongs to any of the apexes.
var depIsApexModule exceptionHandleFunc = func(mctx ModuleContext, _ Module, dep ModuleProxy) bool {
	depContainersInfo, _ := getContainerModuleInfo(mctx, dep)
	return InList(ApexContainer, depContainersInfo.belongingContainers)
}

// Returns true if the module and the dependent module belongs to common apexes.
var belongsToCommonApexes exceptionHandleFunc = func(mctx ModuleContext, m Module, dep ModuleProxy) bool {
	mContainersInfo, _ := getContainerModuleInfo(mctx, m)
	depContainersInfo, _ := getContainerModuleInfo(mctx, dep)

	return HasIntersection(mContainersInfo.ApexNames(), depContainersInfo.ApexNames())
}

// Returns true when all apexes that the module belongs to are non updatable.
// For an apex module to be allowed to depend on a non-apex partition module,
// all apexes that the module belong to must be non updatable.
var belongsToNonUpdatableApex exceptionHandleFunc = func(mctx ModuleContext, m Module, _ ModuleProxy) bool {
	mContainersInfo, _ := getContainerModuleInfo(mctx, m)

	return !mContainersInfo.UpdatableApex()
}

// Returns true if the dependency is added via dependency tags that are not used to tag dynamic
// dependency tags.
var depIsNotDynamicDepTag exceptionHandleFunc = func(ctx ModuleContext, m Module, dep ModuleProxy) bool {
	mInstallable, _ := m.(InstallableModule)
	depTag := ctx.OtherModuleDependencyTag(dep)
	return !InList(depTag, mInstallable.DynamicDependencyTags())
}

// Returns true if the dependency is added via dependency tags that are not used to tag static
// or dynamic dependency tags. These dependencies do not affect the module in compile time or in
// runtime, thus are not significant enough to raise an error.
var depIsNotStaticOrDynamicDepTag exceptionHandleFunc = func(ctx ModuleContext, m Module, dep ModuleProxy) bool {
	mInstallable, _ := m.(InstallableModule)
	depTag := ctx.OtherModuleDependencyTag(dep)
	return !InList(depTag, append(mInstallable.StaticDependencyTags(), mInstallable.DynamicDependencyTags()...))
}

var globallyAllowlistedDependencies = []string{
	// Modules that provide annotations used within the platform and apexes.
	"aconfig-annotations-lib",
	"framework-annotations-lib",
	"unsupportedappusage",

	// TODO(b/363016634): Remove from the allowlist when the module is converted
	// to java_sdk_library and the java_aconfig_library modules depend on the stub.
	"aconfig_storage_stub",

	// framework-res provides core resources essential for building apps and system UI.
	// This module is implicitly added as a dependency for java modules even when the
	// dependency specifies sdk_version.
	"framework-res",

	// jacocoagent is implicitly added as a dependency in coverage builds, and is not installed
	// on the device.
	"jacocoagent",
}

// Returns true when the dependency is globally allowlisted for inter-container dependency
var depIsGloballyAllowlisted exceptionHandleFunc = func(_ ModuleContext, _ Module, dep ModuleProxy) bool {
	return InList(dep.Name(), globallyAllowlistedDependencies)
}

// Labels of exception functions, which are used to determine special dependencies that allow
// otherwise restricted inter-container dependencies
type exceptionHandleFuncLabel int

const (
	checkStubs exceptionHandleFuncLabel = iota
	checkApexModule
	checkInCommonApexes
	checkApexIsNonUpdatable
	checkNotDynamicDepTag
	checkNotStaticOrDynamicDepTag
	checkGlobalAllowlistedDep
)

// Map of [exceptionHandleFuncLabel] to the [exceptionHandleFunc]
var exceptionHandleFunctionsTable = map[exceptionHandleFuncLabel]exceptionHandleFunc{
	checkStubs:                    depIsStubsModule,
	checkApexModule:               depIsApexModule,
	checkInCommonApexes:           belongsToCommonApexes,
	checkApexIsNonUpdatable:       belongsToNonUpdatableApex,
	checkNotDynamicDepTag:         depIsNotDynamicDepTag,
	checkNotStaticOrDynamicDepTag: depIsNotStaticOrDynamicDepTag,
	checkGlobalAllowlistedDep:     depIsGloballyAllowlisted,
}

// ----------------------------------------------------------------------------
// Start of the definitions of container determination functions.
//
// Similar to the above section, below defines the functions used to determine
// the container of each modules.
// ----------------------------------------------------------------------------

type containerBoundaryFunc func(mctx ModuleContext) bool

var vendorContainerBoundaryFunc containerBoundaryFunc = func(mctx ModuleContext) bool {
	m, ok := mctx.Module().(ImageInterface)
	return mctx.Module().InstallInVendor() || (ok && m.VendorVariantNeeded(mctx))
}

var systemContainerBoundaryFunc containerBoundaryFunc = func(mctx ModuleContext) bool {
	module := mctx.Module()

	return !module.InstallInTestcases() &&
		!module.InstallInData() &&
		!module.InstallInRamdisk() &&
		!module.InstallInVendorRamdisk() &&
		!module.InstallInDebugRamdisk() &&
		!module.InstallInRecovery() &&
		!module.InstallInVendor() &&
		!module.InstallInOdm() &&
		!module.InstallInProduct() &&
		determineModuleKind(module.base(), mctx.blueprintBaseModuleContext()) == platformModule
}

var productContainerBoundaryFunc containerBoundaryFunc = func(mctx ModuleContext) bool {
	m, ok := mctx.Module().(ImageInterface)
	return mctx.Module().InstallInProduct() || (ok && m.ProductVariantNeeded(mctx))
}

var apexContainerBoundaryFunc containerBoundaryFunc = func(mctx ModuleContext) bool {
	// TODO(b/394955484): a module can't determine the apexes it belongs to any more
	return false
}

var ctsContainerBoundaryFunc containerBoundaryFunc = func(mctx ModuleContext) bool {
	props := mctx.Module().GetProperties()
	for _, prop := range props {
		val := reflect.ValueOf(prop).Elem()
		if val.Kind() == reflect.Struct {
			testSuites := val.FieldByName("Test_suites")
			if testSuites.IsValid() && testSuites.Kind() == reflect.Slice && slices.Contains(testSuites.Interface().([]string), "cts") {
				return true
			}
		}
	}
	return false
}

type unstableInfo struct {
	// Determines if the module contains the private APIs of the platform.
	ContainsPlatformPrivateApis bool
}

var unstableInfoProvider = blueprint.NewProvider[unstableInfo]()

func determineUnstableModule(mctx ModuleContext) bool {
	module := mctx.Module()

	unstableModule := module.Name() == "framework-minus-apex"
	if installable, ok := module.(InstallableModule); ok {
		for _, staticDepTag := range installable.StaticDependencyTags() {
			mctx.VisitDirectDepsProxyWithTag(staticDepTag, func(dep ModuleProxy) {
				if unstableInfo, ok := OtherModuleProvider(mctx, dep, unstableInfoProvider); ok {
					unstableModule = unstableModule || unstableInfo.ContainsPlatformPrivateApis
				}
			})
		}
	}
	return unstableModule
}

var unstableContainerBoundaryFunc containerBoundaryFunc = func(mctx ModuleContext) bool {
	return determineUnstableModule(mctx)
}

// Map of [*container] to the [containerBoundaryFunc]
var containerBoundaryFunctionsTable = map[*container]containerBoundaryFunc{
	VendorContainer:   vendorContainerBoundaryFunc,
	SystemContainer:   systemContainerBoundaryFunc,
	ProductContainer:  productContainerBoundaryFunc,
	ApexContainer:     apexContainerBoundaryFunc,
	CtsContainer:      ctsContainerBoundaryFunc,
	UnstableContainer: unstableContainerBoundaryFunc,
}

// ----------------------------------------------------------------------------
// End of the definitions of container determination functions.
// ----------------------------------------------------------------------------

type InstallableModule interface {
	StaticDependencyTags() []blueprint.DependencyTag
	DynamicDependencyTags() []blueprint.DependencyTag
}

type restriction struct {
	// container of the dependency
	dependency *container

	// Error message to be emitted to the user when the dependency meets this restriction
	errorMessage string

	// List of labels of allowed exception functions that allows bypassing this restriction.
	// If any of the functions mapped to each labels returns true, this dependency would be
	// considered allowed and an error will not be thrown.
	allowedExceptions []exceptionHandleFuncLabel
}
type container struct {
	// The name of the container i.e. partition, api domain
	name string

	// Map of dependency restricted containers.
	restricted []restriction
}

var (
	VendorContainer = &container{
		name:       VendorVariation,
		restricted: nil,
	}

	SystemContainer = &container{
		name: "system",
		restricted: []restriction{
			{
				dependency: VendorContainer,
				errorMessage: "Module belonging to the system partition other than HALs is " +
					"not allowed to depend on the vendor partition module, in order to support " +
					"independent development/update cycles and to support the Generic System " +
					"Image. Try depending on HALs, VNDK or AIDL instead.",
				allowedExceptions: []exceptionHandleFuncLabel{
					checkStubs,
					checkNotDynamicDepTag,
					checkGlobalAllowlistedDep,
				},
			},
		},
	}

	ProductContainer = &container{
		name: ProductVariation,
		restricted: []restriction{
			{
				dependency: VendorContainer,
				errorMessage: "Module belonging to the product partition is not allowed to " +
					"depend on the vendor partition module, as this may lead to security " +
					"vulnerabilities. Try depending on the HALs or utilize AIDL instead.",
				allowedExceptions: []exceptionHandleFuncLabel{
					checkStubs,
					checkNotDynamicDepTag,
					checkGlobalAllowlistedDep,
				},
			},
		},
	}

	ApexContainer = initializeApexContainer()

	CtsContainer = &container{
		name: "cts",
		restricted: []restriction{
			{
				dependency: UnstableContainer,
				errorMessage: "CTS module should not depend on the modules that contain the " +
					"platform implementation details, including \"framework\". Depending on these " +
					"modules may lead to disclosure of implementation details and regression " +
					"due to API changes across platform versions. Try depending on the stubs instead " +
					"and ensure that the module sets an appropriate 'sdk_version'.",
				allowedExceptions: []exceptionHandleFuncLabel{
					checkStubs,
					checkNotStaticOrDynamicDepTag,
					checkGlobalAllowlistedDep,
				},
			},
		},
	}

	// Container signifying that the module contains unstable platform private APIs
	UnstableContainer = &container{
		name:       "unstable",
		restricted: nil,
	}

	allContainers = []*container{
		VendorContainer,
		SystemContainer,
		ProductContainer,
		ApexContainer,
		CtsContainer,
		UnstableContainer,
	}
)

func initializeApexContainer() *container {
	apexContainer := &container{
		name: "apex",
		restricted: []restriction{
			{
				dependency: SystemContainer,
				errorMessage: "Module belonging to Apex(es) is not allowed to depend on the " +
					"modules belonging to the system partition. Either statically depend on the " +
					"module or convert the depending module to java_sdk_library and depend on " +
					"the stubs.",
				allowedExceptions: []exceptionHandleFuncLabel{
					checkStubs,
					checkApexModule,
					checkInCommonApexes,
					checkApexIsNonUpdatable,
					checkNotStaticOrDynamicDepTag,
					checkGlobalAllowlistedDep,
				},
			},
		},
	}

	apexContainer.restricted = append(apexContainer.restricted, restriction{
		dependency: apexContainer,
		errorMessage: "Module belonging to Apex(es) is not allowed to depend on the " +
			"modules belonging to other Apex(es). Either include the depending " +
			"module in the Apex or convert the depending module to java_sdk_library " +
			"and depend on its stubs.",
		allowedExceptions: []exceptionHandleFuncLabel{
			checkStubs,
			checkInCommonApexes,
			checkNotStaticOrDynamicDepTag,
			checkGlobalAllowlistedDep,
		},
	})

	return apexContainer
}

type ContainersInfo struct {
	belongingContainers []*container

	belongingApexes []ApexInfo
}

func (c *ContainersInfo) BelongingContainers() []*container {
	return c.belongingContainers
}

func (c *ContainersInfo) ApexNames() (ret []string) {
	for _, apex := range c.belongingApexes {
		ret = append(ret, apex.BaseApexName)
	}
	slices.Sort(ret)
	return ret
}

// Returns true if any of the apex the module belongs to is updatable.
func (c *ContainersInfo) UpdatableApex() bool {
	for _, apex := range c.belongingApexes {
		if apex.Updatable {
			return true
		}
	}
	return false
}

var ContainersInfoProvider = blueprint.NewProvider[ContainersInfo]()

func satisfyAllowedExceptions(ctx ModuleContext, allowedExceptionLabels []exceptionHandleFuncLabel, m Module, dep ModuleProxy) bool {
	for _, label := range allowedExceptionLabels {
		if exceptionHandleFunctionsTable[label](ctx, m, dep) {
			return true
		}
	}
	return false
}

func (c *ContainersInfo) GetViolations(mctx ModuleContext, m Module, dep ModuleProxy, depInfo ContainersInfo) []string {
	var violations []string

	// Any containers that the module belongs to but the dependency does not belong to must be examined.
	_, containersUniqueToModule, _ := ListSetDifference(c.belongingContainers, depInfo.belongingContainers)

	// Apex container should be examined even if both the module and the dependency belong to
	// the apex container to check that the two modules belong to the same apex.
	if InList(ApexContainer, c.belongingContainers) && !InList(ApexContainer, containersUniqueToModule) {
		containersUniqueToModule = append(containersUniqueToModule, ApexContainer)
	}

	for _, containerUniqueToModule := range containersUniqueToModule {
		for _, restriction := range containerUniqueToModule.restricted {
			if InList(restriction.dependency, depInfo.belongingContainers) {
				if !satisfyAllowedExceptions(mctx, restriction.allowedExceptions, m, dep) {
					violations = append(violations, restriction.errorMessage)
				}
			}
		}
	}

	return violations
}

func generateContainerInfo(ctx ModuleContext) ContainersInfo {
	var containers []*container

	for _, cnt := range allContainers {
		if containerBoundaryFunctionsTable[cnt](ctx) {
			containers = append(containers, cnt)
		}
	}

	return ContainersInfo{
		belongingContainers: containers,
		// TODO(b/394955484): a module can't determine the apexes it belongs to any more
		belongingApexes: nil,
	}
}

func getContainerModuleInfo(ctx ModuleContext, module Module) (ContainersInfo, bool) {
	if EqualModules(ctx.Module(), module) {
		return ctx.getContainersInfo(), true
	}

	return OtherModuleProvider(ctx, module, ContainersInfoProvider)
}

func setContainerInfo(ctx ModuleContext) {
	// Required to determine the unstable container. This provider is set here instead of the
	// unstableContainerBoundaryFunc in order to prevent setting the provider multiple times.
	SetProvider(ctx, unstableInfoProvider, unstableInfo{
		ContainsPlatformPrivateApis: determineUnstableModule(ctx),
	})

	if _, ok := ctx.Module().(InstallableModule); ok {
		containersInfo := generateContainerInfo(ctx)
		ctx.setContainersInfo(containersInfo)
		SetProvider(ctx, ContainersInfoProvider, containersInfo)
	}
}

func checkContainerViolations(ctx ModuleContext) {
	if _, ok := ctx.Module().(InstallableModule); ok {
		containersInfo, _ := getContainerModuleInfo(ctx, ctx.Module())
		ctx.VisitDirectDepsProxy(func(dep ModuleProxy) {
			if !OtherModuleProviderOrDefault(ctx, dep, CommonModuleInfoProvider).Enabled {
				return
			}

			// Pre-existing violating dependencies are tracked in containerDependencyViolationAllowlist.
			// If this dependency is allowlisted, do not check for violation.
			// If not, check if this dependency matches any restricted dependency and
			// satisfies any exception functions, which allows bypassing the
			// restriction. If all of the exceptions are not satisfied, throw an error.
			if depContainersInfo, ok := getContainerModuleInfo(ctx, dep); ok {
				if allowedViolations, ok := ContainerDependencyViolationAllowlist[ctx.ModuleName()]; ok && InList(dep.Name(), allowedViolations) {
					return
				} else {
					violations := containersInfo.GetViolations(ctx, ctx.Module(), dep, depContainersInfo)
					if len(violations) > 0 {
						errorMessage := fmt.Sprintf("%s cannot depend on %s. ", ctx.ModuleName(), dep.Name())
						errorMessage += strings.Join(violations, " ")
						ctx.ModuleErrorf(errorMessage)
					}
				}
			}
		})
	}
}
