// Copyright 2019 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 java

import (
	"fmt"
	"path/filepath"
	"sort"
	"strconv"
	"strings"

	"android/soong/android"
	"android/soong/java/config"

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

func init() {
	android.RegisterPreSingletonType("sdk_versions", sdkPreSingletonFactory)
	android.RegisterSingletonType("sdk", sdkSingletonFactory)
	android.RegisterMakeVarsProvider(pctx, sdkMakeVars)
}

var sdkVersionsKey = android.NewOnceKey("sdkVersionsKey")
var sdkFrameworkAidlPathKey = android.NewOnceKey("sdkFrameworkAidlPathKey")
var nonUpdatableFrameworkAidlPathKey = android.NewOnceKey("nonUpdatableFrameworkAidlPathKey")
var apiFingerprintPathKey = android.NewOnceKey("apiFingerprintPathKey")

type sdkContext interface {
	// sdkVersion returns sdkSpec that corresponds to the sdk_version property of the current module
	sdkVersion() sdkSpec
	// systemModules returns the system_modules property of the current module, or an empty string if it is not set.
	systemModules() string
	// minSdkVersion returns sdkSpec that corresponds to the min_sdk_version property of the current module,
	// or from sdk_version if it is not set.
	minSdkVersion() sdkSpec
	// targetSdkVersion returns the sdkSpec that corresponds to the target_sdk_version property of the current module,
	// or from sdk_version if it is not set.
	targetSdkVersion() sdkSpec
}

func UseApiFingerprint(ctx android.BaseModuleContext) bool {
	if ctx.Config().UnbundledBuild() &&
		!ctx.Config().UnbundledBuildUsePrebuiltSdks() &&
		ctx.Config().IsEnvTrue("UNBUNDLED_BUILD_TARGET_SDK_WITH_API_FINGERPRINT") {
		return true
	}
	return false
}

// sdkKind represents a particular category of an SDK spec like public, system, test, etc.
type sdkKind int

const (
	sdkInvalid sdkKind = iota
	sdkNone
	sdkCore
	sdkCorePlatform
	sdkPublic
	sdkSystem
	sdkTest
	sdkModule
	sdkSystemServer
	sdkPrivate
)

// String returns the string representation of this sdkKind
func (k sdkKind) String() string {
	switch k {
	case sdkPrivate:
		return "private"
	case sdkNone:
		return "none"
	case sdkPublic:
		return "public"
	case sdkSystem:
		return "system"
	case sdkTest:
		return "test"
	case sdkCore:
		return "core"
	case sdkCorePlatform:
		return "core_platform"
	case sdkModule:
		return "module-lib"
	case sdkSystemServer:
		return "system-server"
	default:
		return "invalid"
	}
}

// sdkVersion represents a specific version number of an SDK spec of a particular kind
type sdkVersion int

const (
	// special version number for a not-yet-frozen SDK
	sdkVersionCurrent sdkVersion = sdkVersion(android.FutureApiLevel)
	// special version number to be used for SDK specs where version number doesn't
	// make sense, e.g. "none", "", etc.
	sdkVersionNone sdkVersion = sdkVersion(0)
)

// isCurrent checks if the sdkVersion refers to the not-yet-published version of an sdkKind
func (v sdkVersion) isCurrent() bool {
	return v == sdkVersionCurrent
}

// isNumbered checks if the sdkVersion refers to the published (a.k.a numbered) version of an sdkKind
func (v sdkVersion) isNumbered() bool {
	return !v.isCurrent() && v != sdkVersionNone
}

// String returns the string representation of this sdkVersion.
func (v sdkVersion) String() string {
	if v.isCurrent() {
		return "current"
	} else if v.isNumbered() {
		return strconv.Itoa(int(v))
	}
	return "(no version)"
}

// asNumberString directly converts the numeric value of this sdk version as a string.
// When isNumbered() is true, this method is the same as String(). However, for sdkVersionCurrent
// and sdkVersionNone, this returns 10000 and 0 while String() returns "current" and "(no version"),
// respectively.
func (v sdkVersion) asNumberString() string {
	return strconv.Itoa(int(v))
}

// sdkSpec represents the kind and the version of an SDK for a module to build against
type sdkSpec struct {
	kind    sdkKind
	version sdkVersion
	raw     string
}

func (s sdkSpec) String() string {
	return fmt.Sprintf("%s_%s", s.kind, s.version)
}

// valid checks if this sdkSpec is well-formed. Note however that true doesn't mean that the
// specified SDK actually exists.
func (s sdkSpec) valid() bool {
	return s.kind != sdkInvalid
}

// specified checks if this sdkSpec is well-formed and is not "".
func (s sdkSpec) specified() bool {
	return s.valid() && s.kind != sdkPrivate
}

// whether the API surface is managed and versioned, i.e. has .txt file that
// get frozen on SDK freeze and changes get reviewed by API council.
func (s sdkSpec) stable() bool {
	if !s.specified() {
		return false
	}
	switch s.kind {
	case sdkNone:
		// there is nothing to manage and version in this case; de facto stable API.
		return true
	case sdkCore, sdkPublic, sdkSystem, sdkModule, sdkSystemServer:
		return true
	case sdkCorePlatform, sdkTest, sdkPrivate:
		return false
	default:
		panic(fmt.Errorf("unknown sdkKind=%v", s.kind))
	}
	return false
}

// prebuiltSdkAvailableForUnbundledBuilt tells whether this sdkSpec can have a prebuilt SDK
// that can be used for unbundled builds.
func (s sdkSpec) prebuiltSdkAvailableForUnbundledBuild() bool {
	// "", "none", and "core_platform" are not available for unbundled build
	// as we don't/can't have prebuilt stub for the versions
	return s.kind != sdkPrivate && s.kind != sdkNone && s.kind != sdkCorePlatform
}

// forPdkBuild converts this sdkSpec into another sdkSpec that is for the PDK builds.
func (s sdkSpec) forPdkBuild(ctx android.EarlyModuleContext) sdkSpec {
	// For PDK builds, use the latest SDK version instead of "current" or ""
	if s.kind == sdkPrivate || s.kind == sdkPublic {
		kind := s.kind
		if kind == sdkPrivate {
			// We don't have prebuilt SDK for private APIs, so use the public SDK
			// instead. This looks odd, but that's how it has been done.
			// TODO(b/148271073): investigate the need for this.
			kind = sdkPublic
		}
		version := sdkVersion(LatestSdkVersionInt(ctx))
		return sdkSpec{kind, version, s.raw}
	}
	return s
}

// usePrebuilt determines whether prebuilt SDK should be used for this sdkSpec with the given context.
func (s sdkSpec) usePrebuilt(ctx android.EarlyModuleContext) bool {
	if s.version.isCurrent() {
		// "current" can be built from source and be from prebuilt SDK
		return ctx.Config().UnbundledBuildUsePrebuiltSdks()
	} else if s.version.isNumbered() {
		// validation check
		if s.kind != sdkPublic && s.kind != sdkSystem && s.kind != sdkTest {
			panic(fmt.Errorf("prebuilt SDK is not not available for sdkKind=%q", s.kind))
			return false
		}
		// numbered SDKs are always from prebuilt
		return true
	}
	// "", "none", "core_platform" fall here
	return false
}

// effectiveVersion converts an sdkSpec into the concrete sdkVersion that the module
// should use. For modules targeting an unreleased SDK (meaning it does not yet have a number)
// it returns android.FutureApiLevel(10000).
func (s sdkSpec) effectiveVersion(ctx android.EarlyModuleContext) (sdkVersion, error) {
	if !s.valid() {
		return s.version, fmt.Errorf("invalid sdk version %q", s.raw)
	}
	if ctx.Config().IsPdkBuild() {
		s = s.forPdkBuild(ctx)
	}
	if s.version.isNumbered() {
		return s.version, nil
	}
	return sdkVersion(ctx.Config().DefaultAppTargetSdkInt()), nil
}

// effectiveVersionString converts an sdkSpec into the concrete version string that the module
// should use. For modules targeting an unreleased SDK (meaning it does not yet have a number)
// it returns the codename (P, Q, R, etc.)
func (s sdkSpec) effectiveVersionString(ctx android.EarlyModuleContext) (string, error) {
	ver, err := s.effectiveVersion(ctx)
	if err == nil && int(ver) == ctx.Config().DefaultAppTargetSdkInt() {
		return ctx.Config().DefaultAppTargetSdk(), nil
	}
	return ver.String(), err
}

func (s sdkSpec) defaultJavaLanguageVersion(ctx android.EarlyModuleContext) javaVersion {
	sdk, err := s.effectiveVersion(ctx)
	if err != nil {
		ctx.PropertyErrorf("sdk_version", "%s", err)
	}
	if sdk <= 23 {
		return JAVA_VERSION_7
	} else if sdk <= 29 {
		return JAVA_VERSION_8
	} else {
		return JAVA_VERSION_9
	}
}

func sdkSpecFrom(str string) sdkSpec {
	switch str {
	// special cases first
	case "":
		return sdkSpec{sdkPrivate, sdkVersionNone, str}
	case "none":
		return sdkSpec{sdkNone, sdkVersionNone, str}
	case "core_platform":
		return sdkSpec{sdkCorePlatform, sdkVersionNone, str}
	default:
		// the syntax is [kind_]version
		sep := strings.LastIndex(str, "_")

		var kindString string
		if sep == 0 {
			return sdkSpec{sdkInvalid, sdkVersionNone, str}
		} else if sep == -1 {
			kindString = ""
		} else {
			kindString = str[0:sep]
		}
		versionString := str[sep+1 : len(str)]

		var kind sdkKind
		switch kindString {
		case "":
			kind = sdkPublic
		case "core":
			kind = sdkCore
		case "system":
			kind = sdkSystem
		case "test":
			kind = sdkTest
		case "module":
			kind = sdkModule
		case "system_server":
			kind = sdkSystemServer
		default:
			return sdkSpec{sdkInvalid, sdkVersionNone, str}
		}

		var version sdkVersion
		if versionString == "current" {
			version = sdkVersionCurrent
		} else if i, err := strconv.Atoi(versionString); err == nil {
			version = sdkVersion(i)
		} else {
			return sdkSpec{sdkInvalid, sdkVersionNone, str}
		}

		return sdkSpec{kind, version, str}
	}
}

func (s sdkSpec) validateSystemSdk(ctx android.EarlyModuleContext) bool {
	// Ensures that the specified system SDK version is one of BOARD_SYSTEMSDK_VERSIONS (for vendor/product Java module)
	// Assuming that BOARD_SYSTEMSDK_VERSIONS := 28 29,
	// sdk_version of the modules in vendor/product that use system sdk must be either system_28, system_29 or system_current
	if s.kind != sdkSystem || !s.version.isNumbered() {
		return true
	}
	allowedVersions := ctx.DeviceConfig().PlatformSystemSdkVersions()
	if ctx.DeviceSpecific() || ctx.SocSpecific() || (ctx.ProductSpecific() && ctx.Config().EnforceProductPartitionInterface()) {
		systemSdkVersions := ctx.DeviceConfig().SystemSdkVersions()
		if len(systemSdkVersions) > 0 {
			allowedVersions = systemSdkVersions
		}
	}
	if len(allowedVersions) > 0 && !android.InList(s.version.String(), allowedVersions) {
		ctx.PropertyErrorf("sdk_version", "incompatible sdk version %q. System SDK version should be one of %q",
			s.raw, allowedVersions)
		return false
	}
	return true
}

func decodeSdkDep(ctx android.EarlyModuleContext, sdkContext sdkContext) sdkDep {
	sdkVersion := sdkContext.sdkVersion()
	if !sdkVersion.valid() {
		ctx.PropertyErrorf("sdk_version", "invalid version %q", sdkVersion.raw)
		return sdkDep{}
	}

	if ctx.Config().IsPdkBuild() {
		sdkVersion = sdkVersion.forPdkBuild(ctx)
	}
	if !sdkVersion.validateSystemSdk(ctx) {
		return sdkDep{}
	}

	if sdkVersion.usePrebuilt(ctx) {
		dir := filepath.Join("prebuilts", "sdk", sdkVersion.version.String(), sdkVersion.kind.String())
		jar := filepath.Join(dir, "android.jar")
		// There's no aidl for other SDKs yet.
		// TODO(77525052): Add aidl files for other SDKs too.
		public_dir := filepath.Join("prebuilts", "sdk", sdkVersion.version.String(), "public")
		aidl := filepath.Join(public_dir, "framework.aidl")
		jarPath := android.ExistentPathForSource(ctx, jar)
		aidlPath := android.ExistentPathForSource(ctx, aidl)
		lambdaStubsPath := android.PathForSource(ctx, config.SdkLambdaStubsPath)

		if (!jarPath.Valid() || !aidlPath.Valid()) && ctx.Config().AllowMissingDependencies() {
			return sdkDep{
				invalidVersion: true,
				bootclasspath:  []string{fmt.Sprintf("sdk_%s_%s_android", sdkVersion.kind, sdkVersion.version.String())},
			}
		}

		if !jarPath.Valid() {
			ctx.PropertyErrorf("sdk_version", "invalid sdk version %q, %q does not exist", sdkVersion.raw, jar)
			return sdkDep{}
		}

		if !aidlPath.Valid() {
			ctx.PropertyErrorf("sdk_version", "invalid sdk version %q, %q does not exist", sdkVersion.raw, aidl)
			return sdkDep{}
		}

		var systemModules string
		if sdkVersion.defaultJavaLanguageVersion(ctx).usesJavaModules() {
			systemModules = "sdk_public_" + sdkVersion.version.String() + "_system_modules"
		}

		return sdkDep{
			useFiles:      true,
			jars:          android.Paths{jarPath.Path(), lambdaStubsPath},
			aidl:          android.OptionalPathForPath(aidlPath.Path()),
			systemModules: systemModules,
		}
	}

	toModule := func(modules []string, res string, aidl android.Path) sdkDep {
		return sdkDep{
			useModule:          true,
			bootclasspath:      append(modules, config.DefaultLambdaStubsLibrary),
			systemModules:      "core-current-stubs-system-modules",
			java9Classpath:     modules,
			frameworkResModule: res,
			aidl:               android.OptionalPathForPath(aidl),
		}
	}

	switch sdkVersion.kind {
	case sdkPrivate:
		return sdkDep{
			useModule:          true,
			systemModules:      corePlatformSystemModules(ctx),
			bootclasspath:      corePlatformBootclasspathLibraries(ctx),
			classpath:          config.FrameworkLibraries,
			frameworkResModule: "framework-res",
		}
	case sdkNone:
		systemModules := sdkContext.systemModules()
		if systemModules == "" {
			ctx.PropertyErrorf("sdk_version",
				`system_modules is required to be set to a non-empty value when sdk_version is "none", did you mean sdk_version: "core_platform"?`)
		} else if systemModules == "none" {
			return sdkDep{
				noStandardLibs: true,
			}
		}

		return sdkDep{
			useModule:      true,
			noStandardLibs: true,
			systemModules:  systemModules,
			bootclasspath:  []string{systemModules},
		}
	case sdkCorePlatform:
		return sdkDep{
			useModule:        true,
			systemModules:    corePlatformSystemModules(ctx),
			bootclasspath:    corePlatformBootclasspathLibraries(ctx),
			noFrameworksLibs: true,
		}
	case sdkPublic:
		return toModule([]string{"android_stubs_current"}, "framework-res", sdkFrameworkAidlPath(ctx))
	case sdkSystem:
		return toModule([]string{"android_system_stubs_current"}, "framework-res", sdkFrameworkAidlPath(ctx))
	case sdkTest:
		return toModule([]string{"android_test_stubs_current"}, "framework-res", sdkFrameworkAidlPath(ctx))
	case sdkCore:
		return sdkDep{
			useModule:        true,
			bootclasspath:    []string{"core.current.stubs", config.DefaultLambdaStubsLibrary},
			systemModules:    "core-current-stubs-system-modules",
			noFrameworksLibs: true,
		}
	case sdkModule:
		// TODO(146757305): provide .apk and .aidl that have more APIs for modules
		return toModule([]string{"android_module_lib_stubs_current"}, "framework-res", nonUpdatableFrameworkAidlPath(ctx))
	case sdkSystemServer:
		// TODO(146757305): provide .apk and .aidl that have more APIs for modules
		return toModule([]string{"android_system_server_stubs_current"}, "framework-res", sdkFrameworkAidlPath(ctx))
	default:
		panic(fmt.Errorf("invalid sdk %q", sdkVersion.raw))
	}
}

func sdkPreSingletonFactory() android.Singleton {
	return sdkPreSingleton{}
}

type sdkPreSingleton struct{}

func (sdkPreSingleton) GenerateBuildActions(ctx android.SingletonContext) {
	sdkJars, err := ctx.GlobWithDeps("prebuilts/sdk/*/public/android.jar", nil)
	if err != nil {
		ctx.Errorf("failed to glob prebuilts/sdk/*/public/android.jar: %s", err.Error())
	}

	var sdkVersions []int
	for _, sdkJar := range sdkJars {
		dir := filepath.Base(filepath.Dir(filepath.Dir(sdkJar)))
		v, err := strconv.Atoi(dir)
		if scerr, ok := err.(*strconv.NumError); ok && scerr.Err == strconv.ErrSyntax {
			continue
		} else if err != nil {
			ctx.Errorf("invalid sdk jar %q, %s, %v", sdkJar, err.Error())
		}
		sdkVersions = append(sdkVersions, v)
	}

	sort.Ints(sdkVersions)

	ctx.Config().Once(sdkVersionsKey, func() interface{} { return sdkVersions })
}

func LatestSdkVersionInt(ctx android.EarlyModuleContext) int {
	sdkVersions := ctx.Config().Get(sdkVersionsKey).([]int)
	latestSdkVersion := 0
	if len(sdkVersions) > 0 {
		latestSdkVersion = sdkVersions[len(sdkVersions)-1]
	}
	return latestSdkVersion
}

func sdkSingletonFactory() android.Singleton {
	return sdkSingleton{}
}

type sdkSingleton struct{}

func (sdkSingleton) GenerateBuildActions(ctx android.SingletonContext) {
	if ctx.Config().UnbundledBuildUsePrebuiltSdks() || ctx.Config().IsPdkBuild() {
		return
	}

	createSdkFrameworkAidl(ctx)
	createNonUpdatableFrameworkAidl(ctx)
	createAPIFingerprint(ctx)
}

// Create framework.aidl by extracting anything that implements android.os.Parcelable from the SDK stubs modules.
func createSdkFrameworkAidl(ctx android.SingletonContext) {
	stubsModules := []string{
		"android_stubs_current",
		"android_test_stubs_current",
		"android_system_stubs_current",
	}

	combinedAidl := sdkFrameworkAidlPath(ctx)
	tempPath := combinedAidl.ReplaceExtension(ctx, "aidl.tmp")

	rule := createFrameworkAidl(stubsModules, tempPath, ctx)

	commitChangeForRestat(rule, tempPath, combinedAidl)

	rule.Build(pctx, ctx, "framework_aidl", "generate framework.aidl")
}

// Creates a version of framework.aidl for the non-updatable part of the platform.
func createNonUpdatableFrameworkAidl(ctx android.SingletonContext) {
	stubsModules := []string{"android_module_lib_stubs_current"}

	combinedAidl := nonUpdatableFrameworkAidlPath(ctx)
	tempPath := combinedAidl.ReplaceExtension(ctx, "aidl.tmp")

	rule := createFrameworkAidl(stubsModules, tempPath, ctx)

	commitChangeForRestat(rule, tempPath, combinedAidl)

	rule.Build(pctx, ctx, "framework_non_updatable_aidl", "generate framework_non_updatable.aidl")
}

func createFrameworkAidl(stubsModules []string, path android.OutputPath, ctx android.SingletonContext) *android.RuleBuilder {
	stubsJars := make([]android.Paths, len(stubsModules))

	ctx.VisitAllModules(func(module android.Module) {
		// Collect dex jar paths for the modules listed above.
		if j, ok := module.(Dependency); ok {
			name := ctx.ModuleName(module)
			if i := android.IndexList(name, stubsModules); i != -1 {
				stubsJars[i] = j.HeaderJars()
			}
		}
	})

	var missingDeps []string

	for i := range stubsJars {
		if stubsJars[i] == nil {
			if ctx.Config().AllowMissingDependencies() {
				missingDeps = append(missingDeps, stubsModules[i])
			} else {
				ctx.Errorf("failed to find dex jar path for module %q", stubsModules[i])
			}
		}
	}

	rule := android.NewRuleBuilder()
	rule.MissingDeps(missingDeps)

	var aidls android.Paths
	for _, jars := range stubsJars {
		for _, jar := range jars {
			aidl := android.PathForOutput(ctx, "aidl", pathtools.ReplaceExtension(jar.Base(), "aidl"))

			rule.Command().
				Text("rm -f").Output(aidl)
			rule.Command().
				BuiltTool(ctx, "sdkparcelables").
				Input(jar).
				Output(aidl)

			aidls = append(aidls, aidl)
		}
	}

	rule.Command().
		Text("rm -f").Output(path)
	rule.Command().
		Text("cat").
		Inputs(aidls).
		Text("| sort -u >").
		Output(path)

	return rule
}

func sdkFrameworkAidlPath(ctx android.PathContext) android.OutputPath {
	return ctx.Config().Once(sdkFrameworkAidlPathKey, func() interface{} {
		return android.PathForOutput(ctx, "framework.aidl")
	}).(android.OutputPath)
}

func nonUpdatableFrameworkAidlPath(ctx android.PathContext) android.OutputPath {
	return ctx.Config().Once(nonUpdatableFrameworkAidlPathKey, func() interface{} {
		return android.PathForOutput(ctx, "framework_non_updatable.aidl")
	}).(android.OutputPath)
}

// Create api_fingerprint.txt
func createAPIFingerprint(ctx android.SingletonContext) {
	out := ApiFingerprintPath(ctx)

	rule := android.NewRuleBuilder()

	rule.Command().
		Text("rm -f").Output(out)
	cmd := rule.Command()

	if ctx.Config().PlatformSdkCodename() == "REL" {
		cmd.Text("echo REL >").Output(out)
	} else if ctx.Config().IsPdkBuild() {
		// TODO: get this from the PDK artifacts?
		cmd.Text("echo PDK >").Output(out)
	} else if !ctx.Config().UnbundledBuildUsePrebuiltSdks() {
		in, err := ctx.GlobWithDeps("frameworks/base/api/*current.txt", nil)
		if err != nil {
			ctx.Errorf("error globbing API files: %s", err)
		}

		cmd.Text("cat").
			Inputs(android.PathsForSource(ctx, in)).
			Text("| md5sum | cut -d' ' -f1 >").
			Output(out)
	} else {
		// Unbundled build
		// TODO: use a prebuilt api_fingerprint.txt from prebuilts/sdk/current.txt once we have one
		cmd.Text("echo").
			Flag(ctx.Config().PlatformPreviewSdkVersion()).
			Text(">").
			Output(out)
	}

	rule.Build(pctx, ctx, "api_fingerprint", "generate api_fingerprint.txt")
}

func ApiFingerprintPath(ctx android.PathContext) android.OutputPath {
	return ctx.Config().Once(apiFingerprintPathKey, func() interface{} {
		return android.PathForOutput(ctx, "api_fingerprint.txt")
	}).(android.OutputPath)
}

func sdkMakeVars(ctx android.MakeVarsContext) {
	if ctx.Config().UnbundledBuildUsePrebuiltSdks() || ctx.Config().IsPdkBuild() {
		return
	}

	ctx.Strict("FRAMEWORK_AIDL", sdkFrameworkAidlPath(ctx).String())
	ctx.Strict("API_FINGERPRINT", ApiFingerprintPath(ctx).String())
}
