// 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"
)

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(ctx PathContext, raw string) string {
	num, ok := getFinalCodenamesMap(ctx.Config())[raw]
	if !ok {
		return raw
	}

	return strconv.Itoa(num)
}

// 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) {
	if raw == "" {
		panic("API level string must be non-empty")
	}

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

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

	canonical := ReplaceFinalizedCodenames(ctx, 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,
		}

		// 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,
		}
		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)
}
