// Copyright 2018 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 (
	"android/soong/android"
	"sort"
	"strings"

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

// prebuilt_apis is a meta-module that generates filegroup modules for all
// API txt files found under the directory where the Android.bp is located.
// Specificaly, an API file located at ./<ver>/<scope>/api/<module>.txt
// generates a filegroup module named <module>-api.<scope>.<ver>.
//
// It also creates <module>-api.<scope>.latest for the lastest <ver>.
//
func init() {
	android.RegisterModuleType("prebuilt_apis", prebuiltApisFactory)

	android.PreArchMutators(func(ctx android.RegisterMutatorsContext) {
		ctx.TopDown("prebuilt_apis", prebuiltApisMutator).Parallel()
	})
}

type prebuiltApisProperties struct {
	// list of api version directories
	Api_dirs []string
}

type prebuiltApis struct {
	android.ModuleBase
	properties prebuiltApisProperties
}

func (module *prebuiltApis) DepsMutator(ctx android.BottomUpMutatorContext) {
	// no need to implement
}

func (module *prebuiltApis) GenerateAndroidBuildActions(ctx android.ModuleContext) {
	// no need to implement
}

func parseJarPath(ctx android.BaseModuleContext, path string) (module string, apiver string, scope string) {
	elements := strings.Split(path, "/")

	apiver = elements[0]
	scope = elements[1]

	module = strings.TrimSuffix(elements[2], ".jar")
	return
}

func parseApiFilePath(ctx android.BaseModuleContext, path string) (module string, apiver string, scope string) {
	elements := strings.Split(path, "/")
	apiver = elements[0]

	scope = elements[1]
	if scope != "public" && scope != "system" && scope != "test" {
		ctx.ModuleErrorf("invalid scope %q found in path: %q", scope, path)
		return
	}

	// elements[2] is string literal "api". skipping.
	module = strings.TrimSuffix(elements[3], ".txt")
	return
}

func createImport(mctx android.TopDownMutatorContext, module string, scope string, apiver string, path string) {
	props := struct {
		Name        *string
		Jars        []string
		Sdk_version *string
		Installable *bool
	}{}
	props.Name = proptools.StringPtr(mctx.ModuleName() + "_" + scope + "_" + apiver + "_" + module)
	props.Jars = append(props.Jars, path)
	// TODO(hansson): change to scope after migration is done.
	props.Sdk_version = proptools.StringPtr("current")
	props.Installable = proptools.BoolPtr(false)

	mctx.CreateModule(android.ModuleFactoryAdaptor(ImportFactory), &props)
}

func createFilegroup(mctx android.TopDownMutatorContext, module string, scope string, apiver string, path string) {
	fgName := module + ".api." + scope + "." + apiver
	filegroupProps := struct {
		Name *string
		Srcs []string
	}{}
	filegroupProps.Name = proptools.StringPtr(fgName)
	filegroupProps.Srcs = []string{path}
	mctx.CreateModule(android.ModuleFactoryAdaptor(android.FileGroupFactory), &filegroupProps)
}

func prebuiltSdkStubs(mctx android.TopDownMutatorContext) {
	mydir := mctx.ModuleDir() + "/"
	// <apiver>/<scope>/<module>.jar
	var files []string
	for _, apiver := range mctx.Module().(*prebuiltApis).properties.Api_dirs {
		for _, scope := range []string{"public", "system", "test", "core"} {
			vfiles, err := mctx.GlobWithDeps(mydir+apiver+"/"+scope+"*/*.jar", nil)
			if err != nil {
				mctx.ModuleErrorf("failed to glob jar files under %q: %s", mydir+apiver+"/"+scope, err)
			}
			files = append(files, vfiles...)
		}
	}

	for _, f := range files {
		// create a Import module for each jar file
		localPath := strings.TrimPrefix(f, mydir)
		module, apiver, scope := parseJarPath(mctx, localPath)
		createImport(mctx, module, scope, apiver, localPath)
	}
}

func prebuiltApiFiles(mctx android.TopDownMutatorContext) {
	mydir := mctx.ModuleDir() + "/"
	// <apiver>/<scope>/api/<module>.txt
	files, err := mctx.GlobWithDeps(mydir+"*/*/api/*.txt", nil)
	if err != nil {
		mctx.ModuleErrorf("failed to glob api txt files under %q: %s", mydir, err)
	}
	if len(files) == 0 {
		mctx.ModuleErrorf("no api file found under %q", mydir)
	}

	// construct a map to find out the latest api file path
	// for each (<module>, <scope>) pair.
	type latestApiInfo struct {
		module string
		scope  string
		apiver string
		path   string
	}
	m := make(map[string]latestApiInfo)

	for _, f := range files {
		// create a filegroup for each api txt file
		localPath := strings.TrimPrefix(f, mydir)
		module, apiver, scope := parseApiFilePath(mctx, localPath)
		createFilegroup(mctx, module, scope, apiver, localPath)

		// find the latest apiver
		key := module + "." + scope
		info, ok := m[key]
		if !ok {
			m[key] = latestApiInfo{module, scope, apiver, localPath}
		} else if len(apiver) > len(info.apiver) || (len(apiver) == len(info.apiver) &&
			strings.Compare(apiver, info.apiver) > 0) {
			info.apiver = apiver
			info.path = localPath
		}
	}
	// create filegroups for the latest version of (<module>, <scope>) pairs
	// sort the keys in order to make build.ninja stable
	keys := make([]string, 0, len(m))
	for k := range m {
		keys = append(keys, k)
	}
	sort.Strings(keys)
	for _, k := range keys {
		info := m[k]
		createFilegroup(mctx, info.module, info.scope, "latest", info.path)
	}
}

func prebuiltApisMutator(mctx android.TopDownMutatorContext) {
	if _, ok := mctx.Module().(*prebuiltApis); ok {
		prebuiltApiFiles(mctx)
		prebuiltSdkStubs(mctx)
	}
}

func prebuiltApisFactory() android.Module {
	module := &prebuiltApis{}
	module.AddProperties(&module.properties)
	android.InitAndroidModule(module)
	return module
}
