/*
 * Copyright (C) 2020 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 apex

import (
	"github.com/google/blueprint"

	"android/soong/android"
)

func init() {
	registerApexDepsInfoComponents(android.InitRegistrationContext)
}

func registerApexDepsInfoComponents(ctx android.RegistrationContext) {
	ctx.RegisterParallelSingletonType("apex_depsinfo_singleton", apexDepsInfoSingletonFactory)
}

type apexDepsInfoSingleton struct {
	allowedApexDepsInfoCheckResult android.OutputPath
}

func apexDepsInfoSingletonFactory() android.Singleton {
	return &apexDepsInfoSingleton{}
}

var (
	// Generate new apex allowed_deps.txt by merging all internal dependencies.
	generateApexDepsInfoFilesRule = pctx.AndroidStaticRule("generateApexDepsInfoFilesRule", blueprint.RuleParams{
		Command: "cat $out.rsp | xargs cat" +
			// Only track non-external dependencies, i.e. those that end up in the binary
			" | grep -v '(external)'" +
			// Ignore comments in any of the files
			" | grep -v '^#'" +
			" | sort -u -f >$out",
		Rspfile:        "$out.rsp",
		RspfileContent: "$in",
	})

	// Diff two given lists while ignoring comments in the allowed deps file.
	diffAllowedApexDepsInfoRule = pctx.AndroidStaticRule("diffAllowedApexDepsInfoRule", blueprint.RuleParams{
		Description: "Diff ${allowed_deps} and ${new_allowed_deps}",
		Command: `
			if grep -v '^#' ${allowed_deps} | diff -B - ${new_allowed_deps}; then
			   touch ${out};
			else
				echo -e "\n******************************";
				echo "ERROR: go/apex-allowed-deps-error contains more information";
				echo "******************************";
				echo "Detected changes to allowed dependencies in updatable modules.";
				echo "To fix and update packages/modules/common/build/allowed_deps.txt, please run:";
				echo -e "$$ (croot && packages/modules/common/build/update-apex-allowed-deps.sh)\n";
				echo "When submitting the generated CL, you must include the following information";
				echo "in the commit message if you are adding a new dependency:";
				echo "Apex-Size-Increase: Expected binary size increase for affected APEXes (or the size of the .jar / .so file of the new library)";
				echo "Previous-Platform-Support: Are the maintainers of the new dependency committed to supporting previous platform releases?";
				echo "Aosp-First: Is the new dependency being developed AOSP-first or internal?";
				echo "Test-Info: What’s the testing strategy for the new dependency? Does it have its own tests, and are you adding integration tests? How/when are the tests run?";
				echo "You do not need OWNERS approval to submit the change, but mainline-modularization@";
				echo "will periodically review additions and may require changes.";
				echo -e "******************************\n";
				exit 1;
			fi;
		`,
	}, "allowed_deps", "new_allowed_deps")
)

func (s *apexDepsInfoSingleton) GenerateBuildActions(ctx android.SingletonContext) {
	updatableFlatLists := android.Paths{}
	ctx.VisitAllModules(func(module android.Module) {
		if binaryInfo, ok := module.(android.ApexBundleDepsInfoIntf); ok {
			apexInfo := ctx.ModuleProvider(module, android.ApexInfoProvider).(android.ApexInfo)
			if path := binaryInfo.FlatListPath(); path != nil {
				if binaryInfo.Updatable() || apexInfo.Updatable {
					updatableFlatLists = append(updatableFlatLists, path)
				}
			}
		}
	})

	allowedDepsSource := android.ExistentPathForSource(ctx, "packages/modules/common/build/allowed_deps.txt")
	newAllowedDeps := android.PathForOutput(ctx, "apex", "depsinfo", "new-allowed-deps.txt")
	s.allowedApexDepsInfoCheckResult = android.PathForOutput(ctx, newAllowedDeps.Rel()+".check")

	if !allowedDepsSource.Valid() {
		// Unbundled projects may not have packages/modules/common/ checked out; ignore those.
		ctx.Build(pctx, android.BuildParams{
			Rule:   android.Touch,
			Output: s.allowedApexDepsInfoCheckResult,
		})
	} else {
		allowedDeps := allowedDepsSource.Path()

		ctx.Build(pctx, android.BuildParams{
			Rule:   generateApexDepsInfoFilesRule,
			Inputs: append(updatableFlatLists, allowedDeps),
			Output: newAllowedDeps,
		})

		ctx.Build(pctx, android.BuildParams{
			Rule:   diffAllowedApexDepsInfoRule,
			Input:  newAllowedDeps,
			Output: s.allowedApexDepsInfoCheckResult,
			Args: map[string]string{
				"allowed_deps":     allowedDeps.String(),
				"new_allowed_deps": newAllowedDeps.String(),
			},
		})
	}

	ctx.Phony("apex-allowed-deps-check", s.allowedApexDepsInfoCheckResult)
}

func (s *apexDepsInfoSingleton) MakeVars(ctx android.MakeVarsContext) {
	// Export check result to Make. The path is added to droidcore.
	ctx.Strict("APEX_ALLOWED_DEPS_CHECK", s.allowedApexDepsInfoCheckResult.String())
}
