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

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

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

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