// Copyright 2017 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 (
	"encoding/json"
	"fmt"
	"strconv"

	"android/soong/bazel"
	"android/soong/starlark_fmt"
)

func init() {
	RegisterSingletonType("api_levels", ApiLevelsSingleton)
}

const previewAPILevelBase = 9000

// An API level, which may be a finalized (numbered) API, a preview (codenamed)
// API, or the future API level (10000). Can be parsed from a string with
// ApiLevelFromUser or ApiLevelOrPanic.
//
// The different *types* of API levels are handled separately. Currently only
// Java has these, and they're managed with the SdkKind enum of the SdkSpec. A
// future cleanup should be to migrate SdkSpec to using ApiLevel instead of its
// SdkVersion int, and to move SdkSpec into this package.
type ApiLevel struct {
	// The string representation of the API level.
	value string

	// A number associated with the API level. The exact value depends on
	// whether this API level is a preview or final API.
	//
	// For final API levels, this is the assigned version number.
	//
	// For preview API levels, this value has no meaning except to index known
	// previews to determine ordering.
	number int

	// Identifies this API level as either a preview or final API level.
	isPreview bool
}

func (this ApiLevel) FinalOrFutureInt() int {
	if this.IsPreview() {
		return FutureApiLevelInt
	} else {
		return this.number
	}
}

// FinalOrPreviewInt distinguishes preview versions from "current" (future).
// This is for "native" stubs and should be in sync with ndkstubgen/getApiLevelsMap().
// - "current" -> future (10000)
// - preview codenames -> preview base (9000) + index
// - otherwise -> cast to int
func (this ApiLevel) FinalOrPreviewInt() int {
	if this.IsCurrent() {
		return this.number
	}
	if this.IsPreview() {
		return previewAPILevelBase + this.number
	}
	return this.number
}

// Returns the canonical name for this API level. For a finalized API level
// this will be the API number as a string. For a preview API level this
// will be the codename, or "current".
func (this ApiLevel) String() string {
	return this.value
}

// Returns true if this is a non-final API level.
func (this ApiLevel) IsPreview() bool {
	return this.isPreview
}

// Returns true if this is the unfinalized "current" API level. This means
// different things across Java and native. Java APIs do not use explicit
// codenames, so all non-final codenames are grouped into "current". For native
// explicit codenames are typically used, and current is the union of all
// non-final APIs, including those that may not yet be in any codename.
//
// Note that in a build where the platform is final, "current" will not be a
// preview API level but will instead be canonicalized to the final API level.
func (this ApiLevel) IsCurrent() bool {
	return this.value == "current"
}

func (this ApiLevel) IsNone() bool {
	return this.number == -1
}

// Returns -1 if the current API level is less than the argument, 0 if they
// are equal, and 1 if it is greater than the argument.
func (this ApiLevel) CompareTo(other ApiLevel) int {
	if this.IsPreview() && !other.IsPreview() {
		return 1
	} else if !this.IsPreview() && other.IsPreview() {
		return -1
	}

	if this.number < other.number {
		return -1
	} else if this.number == other.number {
		return 0
	} else {
		return 1
	}
}

func (this ApiLevel) EqualTo(other ApiLevel) bool {
	return this.CompareTo(other) == 0
}

func (this ApiLevel) GreaterThan(other ApiLevel) bool {
	return this.CompareTo(other) > 0
}

func (this ApiLevel) GreaterThanOrEqualTo(other ApiLevel) bool {
	return this.CompareTo(other) >= 0
}

func (this ApiLevel) LessThan(other ApiLevel) bool {
	return this.CompareTo(other) < 0
}

func (this ApiLevel) LessThanOrEqualTo(other ApiLevel) bool {
	return this.CompareTo(other) <= 0
}

func uncheckedFinalApiLevel(num int) ApiLevel {
	return ApiLevel{
		value:     strconv.Itoa(num),
		number:    num,
		isPreview: false,
	}
}

var NoneApiLevel = ApiLevel{
	value: "(no version)",
	// Not 0 because we don't want this to compare equal with the first preview.
	number:    -1,
	isPreview: true,
}

// The first version that introduced 64-bit ABIs.
var FirstLp64Version = uncheckedFinalApiLevel(21)

// Android has had various kinds of packed relocations over the years
// (http://b/187907243).
//
// API level 30 is where the now-standard SHT_RELR is available.
var FirstShtRelrVersion = uncheckedFinalApiLevel(30)

// API level 28 introduced SHT_RELR when it was still Android-only, and used an
// Android-specific relocation.
var FirstAndroidRelrVersion = uncheckedFinalApiLevel(28)

// API level 23 was when we first had the Chrome relocation packer, which is
// obsolete and has been removed, but lld can now generate compatible packed
// relocations itself.
var FirstPackedRelocationsVersion = uncheckedFinalApiLevel(23)

// The first API level that does not require NDK code to link
// libandroid_support.
var FirstNonLibAndroidSupportVersion = uncheckedFinalApiLevel(21)

// LastWithoutModuleLibCoreSystemModules is the last API level where prebuilts/sdk does not contain
// a core-for-system-modules.jar for the module-lib API scope.
var LastWithoutModuleLibCoreSystemModules = uncheckedFinalApiLevel(31)

// If the `raw` input is the codename of an API level has been finalized, this
// function returns the API level number associated with that API level. If the
// input is *not* a finalized codename, the input is returned unmodified.
//
// For example, at the time of writing, R has been finalized as API level 30,
// but S is in development so it has no number assigned. For the following
// inputs:
//
// * "30" -> "30"
// * "R" -> "30"
// * "S" -> "S"
func ReplaceFinalizedCodenames(config Config, raw string) string {
	num, ok := getFinalCodenamesMap(config)[raw]
	if !ok {
		return raw
	}

	return strconv.Itoa(num)
}

// ApiLevelFromUser converts the given string `raw` to an ApiLevel, possibly returning an error.
//
// `raw` must be non-empty. Passing an empty string results in a panic.
//
// "current" will return CurrentApiLevel, which is the ApiLevel associated with
// an arbitrary future release (often referred to as API level 10000).
//
// Finalized codenames will be interpreted as their final API levels, not the
// preview of the associated releases. R is now API 30, not the R preview.
//
// Future codenames return a preview API level that has no associated integer.
//
// Inputs that are not "current", known previews, or convertible to an integer
// will return an error.
func ApiLevelFromUser(ctx PathContext, raw string) (ApiLevel, error) {
	return ApiLevelFromUserWithConfig(ctx.Config(), raw)
}

// ApiLevelFromUserWithConfig implements ApiLevelFromUser, see comments for
// ApiLevelFromUser for more details.
func ApiLevelFromUserWithConfig(config Config, raw string) (ApiLevel, error) {
	if raw == "" {
		panic("API level string must be non-empty")
	}

	if raw == "current" {
		return FutureApiLevel, nil
	}

	for _, preview := range config.PreviewApiLevels() {
		if raw == preview.String() {
			return preview, nil
		}
	}

	canonical := ReplaceFinalizedCodenames(config, raw)
	asInt, err := strconv.Atoi(canonical)
	if err != nil {
		return NoneApiLevel, fmt.Errorf("%q could not be parsed as an integer and is not a recognized codename", canonical)
	}

	apiLevel := uncheckedFinalApiLevel(asInt)
	return apiLevel, nil
}

// ApiLevelForTest returns an ApiLevel constructed from the supplied raw string.
//
// This only supports "current" and numeric levels, code names are not supported.
func ApiLevelForTest(raw string) ApiLevel {
	if raw == "" {
		panic("API level string must be non-empty")
	}

	if raw == "current" {
		return FutureApiLevel
	}

	asInt, err := strconv.Atoi(raw)
	if err != nil {
		panic(fmt.Errorf("%q could not be parsed as an integer and is not a recognized codename", raw))
	}

	apiLevel := uncheckedFinalApiLevel(asInt)
	return apiLevel
}

// Converts an API level string `raw` into an ApiLevel in the same method as
// `ApiLevelFromUser`, but the input is assumed to have no errors and any errors
// will panic instead of returning an error.
func ApiLevelOrPanic(ctx PathContext, raw string) ApiLevel {
	value, err := ApiLevelFromUser(ctx, raw)
	if err != nil {
		panic(err.Error())
	}
	return value
}

func ApiLevelsSingleton() Singleton {
	return &apiLevelsSingleton{}
}

type apiLevelsSingleton struct{}

func createApiLevelsJson(ctx SingletonContext, file WritablePath,
	apiLevelsMap map[string]int) {

	jsonStr, err := json.Marshal(apiLevelsMap)
	if err != nil {
		ctx.Errorf(err.Error())
	}

	WriteFileRule(ctx, file, string(jsonStr))
}

func GetApiLevelsJson(ctx PathContext) WritablePath {
	return PathForOutput(ctx, "api_levels.json")
}

var finalCodenamesMapKey = NewOnceKey("FinalCodenamesMap")

func getFinalCodenamesMap(config Config) map[string]int {
	return config.Once(finalCodenamesMapKey, func() interface{} {
		apiLevelsMap := map[string]int{
			"G":        9,
			"I":        14,
			"J":        16,
			"J-MR1":    17,
			"J-MR2":    18,
			"K":        19,
			"L":        21,
			"L-MR1":    22,
			"M":        23,
			"N":        24,
			"N-MR1":    25,
			"O":        26,
			"O-MR1":    27,
			"P":        28,
			"Q":        29,
			"R":        30,
			"S":        31,
			"S-V2":     32,
			"Tiramisu": 33,
		}

		// TODO: Differentiate "current" and "future".
		// The code base calls it FutureApiLevel, but the spelling is "current",
		// and these are really two different things. When defining APIs it
		// means the API has not yet been added to a specific release. When
		// choosing an API level to build for it means that the future API level
		// should be used, except in the case where the build is finalized in
		// which case the platform version should be used. This is *weird*,
		// because in the circumstance where API foo was added in R and bar was
		// added in S, both of these are usable when building for "current" when
		// neither R nor S are final, but the S APIs stop being available in a
		// final R build.
		if Bool(config.productVariables.Platform_sdk_final) {
			apiLevelsMap["current"] = config.PlatformSdkVersion().FinalOrFutureInt()
		}

		return apiLevelsMap
	}).(map[string]int)
}

var apiLevelsMapKey = NewOnceKey("ApiLevelsMap")

func GetApiLevelsMap(config Config) map[string]int {
	return config.Once(apiLevelsMapKey, func() interface{} {
		apiLevelsMap := map[string]int{
			"G":        9,
			"I":        14,
			"J":        16,
			"J-MR1":    17,
			"J-MR2":    18,
			"K":        19,
			"L":        21,
			"L-MR1":    22,
			"M":        23,
			"N":        24,
			"N-MR1":    25,
			"O":        26,
			"O-MR1":    27,
			"P":        28,
			"Q":        29,
			"R":        30,
			"S":        31,
			"S-V2":     32,
			"Tiramisu": 33,
		}
		for i, codename := range config.PlatformVersionActiveCodenames() {
			apiLevelsMap[codename] = previewAPILevelBase + i
		}

		return apiLevelsMap
	}).(map[string]int)
}

func (a *apiLevelsSingleton) GenerateBuildActions(ctx SingletonContext) {
	apiLevelsMap := GetApiLevelsMap(ctx.Config())
	apiLevelsJson := GetApiLevelsJson(ctx)
	createApiLevelsJson(ctx, apiLevelsJson, apiLevelsMap)
}

func printApiLevelsStarlarkDict(config Config) string {
	apiLevelsMap := GetApiLevelsMap(config)
	valDict := make(map[string]string, len(apiLevelsMap))
	for k, v := range apiLevelsMap {
		valDict[k] = strconv.Itoa(v)
	}
	return starlark_fmt.PrintDict(valDict, 0)
}

func StarlarkApiLevelConfigs(config Config) string {
	return fmt.Sprintf(bazel.GeneratedBazelFileWarning+`
_api_levels = %s

api_levels = _api_levels
`, printApiLevelsStarlarkDict(config),
	)
}
