// Copyright 2016 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 (
	"bytes"
	"fmt"
	"path/filepath"
	"runtime"
	"sort"
	"strings"

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

func init() {
	RegisterMakeVarsProvider(pctx, androidMakeVarsProvider)
}

func androidMakeVarsProvider(ctx MakeVarsContext) {
	ctx.Strict("MIN_SUPPORTED_SDK_VERSION", ctx.Config().MinSupportedSdkVersion().String())
}

// /////////////////////////////////////////////////////////////////////////////

// BaseMakeVarsContext contains the common functions for other packages to use
// to declare make variables
type BaseMakeVarsContext interface {
	Config() Config
	DeviceConfig() DeviceConfig
	AddNinjaFileDeps(deps ...string)

	Failed() bool

	// These are equivalent to Strict and Check, but do not attempt to
	// evaluate the values before writing them to the Makefile. They can
	// be used when all ninja variables have already been evaluated through
	// Eval().
	StrictRaw(name, value string)
	CheckRaw(name, value string)

	// GlobWithDeps returns a list of files that match the specified pattern but do not match any
	// of the patterns in excludes.  It also adds efficient dependencies to rerun the primary
	// builder whenever a file matching the pattern as added or removed, without rerunning if a
	// file that does not match the pattern is added to a searched directory.
	GlobWithDeps(pattern string, excludes []string) ([]string, error)

	// Phony creates a phony rule in Make, which will allow additional DistForGoal
	// dependencies to be added to it.  Phony can be called on the same name multiple
	// times to add additional dependencies.
	Phony(names string, deps ...Path)

	// DistForGoal creates a rule to copy one or more Paths to the artifacts
	// directory on the build server when the specified goal is built.
	DistForGoal(goal string, paths ...Path)

	// DistForGoalWithFilename creates a rule to copy a Path to the artifacts
	// directory on the build server with the given filename when the specified
	// goal is built.
	DistForGoalWithFilename(goal string, path Path, filename string)

	// DistForGoals creates a rule to copy one or more Paths to the artifacts
	// directory on the build server when any of the specified goals are built.
	DistForGoals(goals []string, paths ...Path)

	// DistForGoalsWithFilename creates a rule to copy a Path to the artifacts
	// directory on the build server with the given filename when any of the
	// specified goals are built.
	DistForGoalsWithFilename(goals []string, path Path, filename string)
}

// MakeVarsContext contains the set of functions available for MakeVarsProvider
// and SingletonMakeVarsProvider implementations.
type MakeVarsContext interface {
	BaseMakeVarsContext

	ModuleName(module blueprint.Module) string
	ModuleDir(module blueprint.Module) string
	ModuleSubDir(module blueprint.Module) string
	ModuleType(module blueprint.Module) string
	ModuleProvider(module blueprint.Module, key blueprint.ProviderKey) interface{}
	BlueprintFile(module blueprint.Module) string

	ModuleErrorf(module blueprint.Module, format string, args ...interface{})
	Errorf(format string, args ...interface{})

	VisitAllModules(visit func(Module))
	VisitAllModulesIf(pred func(Module) bool, visit func(Module))

	// Verify the make variable matches the Soong version, fail the build
	// if it does not. If the make variable is empty, just set it.
	Strict(name, ninjaStr string)
	// Check to see if the make variable matches the Soong version, warn if
	// it does not. If the make variable is empty, just set it.
	Check(name, ninjaStr string)

	// These are equivalent to the above, but sort the make and soong
	// variables before comparing them. They also show the unique entries
	// in each list when displaying the difference, instead of the entire
	// string.
	StrictSorted(name, ninjaStr string)
	CheckSorted(name, ninjaStr string)

	// Evaluates a ninja string and returns the result. Used if more
	// complicated modification needs to happen before giving it to Make.
	Eval(ninjaStr string) (string, error)
}

// MakeVarsModuleContext contains the set of functions available for modules
// implementing the ModuleMakeVarsProvider interface.
type MakeVarsModuleContext interface {
	BaseMakeVarsContext
}

var _ PathContext = MakeVarsContext(nil)

type MakeVarsProvider func(ctx MakeVarsContext)

func RegisterMakeVarsProvider(pctx PackageContext, provider MakeVarsProvider) {
	makeVarsInitProviders = append(makeVarsInitProviders, makeVarsProvider{pctx, provider})
}

// SingletonMakeVarsProvider is a Singleton with an extra method to provide extra values to be exported to Make.
type SingletonMakeVarsProvider interface {
	// MakeVars uses a MakeVarsContext to provide extra values to be exported to Make.
	MakeVars(ctx MakeVarsContext)
}

var singletonMakeVarsProvidersKey = NewOnceKey("singletonMakeVarsProvidersKey")

func getSingletonMakevarsProviders(config Config) *[]makeVarsProvider {
	return config.Once(singletonMakeVarsProvidersKey, func() interface{} {
		return &[]makeVarsProvider{}
	}).(*[]makeVarsProvider)
}

// registerSingletonMakeVarsProvider adds a singleton that implements SingletonMakeVarsProvider to
// the list of MakeVarsProviders to run.
func registerSingletonMakeVarsProvider(config Config, singleton SingletonMakeVarsProvider) {
	// Singletons are registered on the Context and may be different between different Contexts,
	// for example when running multiple tests.  Store the SingletonMakeVarsProviders in the
	// Config so they are attached to the Context.
	singletonMakeVarsProviders := getSingletonMakevarsProviders(config)

	*singletonMakeVarsProviders = append(*singletonMakeVarsProviders,
		makeVarsProvider{pctx, singletonMakeVarsProviderAdapter(singleton)})
}

// singletonMakeVarsProviderAdapter converts a SingletonMakeVarsProvider to a MakeVarsProvider.
func singletonMakeVarsProviderAdapter(singleton SingletonMakeVarsProvider) MakeVarsProvider {
	return func(ctx MakeVarsContext) { singleton.MakeVars(ctx) }
}

// ModuleMakeVarsProvider is a Module with an extra method to provide extra values to be exported to Make.
type ModuleMakeVarsProvider interface {
	Module

	// MakeVars uses a MakeVarsModuleContext to provide extra values to be exported to Make.
	MakeVars(ctx MakeVarsModuleContext)
}

// /////////////////////////////////////////////////////////////////////////////

func makeVarsSingletonFunc() Singleton {
	return &makeVarsSingleton{}
}

type makeVarsSingleton struct {
	varsForTesting     []makeVarsVariable
	installsForTesting []byte
}

type makeVarsProvider struct {
	pctx PackageContext
	call MakeVarsProvider
}

// Collection of makevars providers that are registered in init() methods.
var makeVarsInitProviders []makeVarsProvider

type makeVarsContext struct {
	SingletonContext
	config  Config
	pctx    PackageContext
	vars    []makeVarsVariable
	phonies []phony
	dists   []dist
}

var _ MakeVarsContext = &makeVarsContext{}

type makeVarsVariable struct {
	name   string
	value  string
	sort   bool
	strict bool
}

type phony struct {
	name string
	deps []string
}

type dist struct {
	goals []string
	paths []string
}

func (s *makeVarsSingleton) GenerateBuildActions(ctx SingletonContext) {
	if !ctx.Config().KatiEnabled() {
		return
	}

	outFile := absolutePath(PathForOutput(ctx,
		"make_vars"+proptools.String(ctx.Config().productVariables.Make_suffix)+".mk").String())

	lateOutFile := absolutePath(PathForOutput(ctx,
		"late"+proptools.String(ctx.Config().productVariables.Make_suffix)+".mk").String())

	installsFile := absolutePath(PathForOutput(ctx,
		"installs"+proptools.String(ctx.Config().productVariables.Make_suffix)+".mk").String())

	if ctx.Failed() {
		return
	}

	var vars []makeVarsVariable
	var dists []dist
	var phonies []phony
	var katiInstalls []katiInstall
	var katiSymlinks []katiInstall

	providers := append([]makeVarsProvider(nil), makeVarsInitProviders...)
	providers = append(providers, *getSingletonMakevarsProviders(ctx.Config())...)

	for _, provider := range providers {
		mctx := &makeVarsContext{
			SingletonContext: ctx,
			pctx:             provider.pctx,
		}

		provider.call(mctx)

		vars = append(vars, mctx.vars...)
		phonies = append(phonies, mctx.phonies...)
		dists = append(dists, mctx.dists...)
	}

	ctx.VisitAllModules(func(m Module) {
		if provider, ok := m.(ModuleMakeVarsProvider); ok && m.Enabled() {
			mctx := &makeVarsContext{
				SingletonContext: ctx,
			}

			provider.MakeVars(mctx)

			vars = append(vars, mctx.vars...)
			phonies = append(phonies, mctx.phonies...)
			dists = append(dists, mctx.dists...)
		}

		if m.ExportedToMake() {
			katiInstalls = append(katiInstalls, m.base().katiInstalls...)
			katiSymlinks = append(katiSymlinks, m.base().katiSymlinks...)
		}
	})

	if ctx.Failed() {
		return
	}

	sort.Slice(vars, func(i, j int) bool {
		return vars[i].name < vars[j].name
	})
	sort.Slice(phonies, func(i, j int) bool {
		return phonies[i].name < phonies[j].name
	})
	lessArr := func(a, b []string) bool {
		if len(a) == len(b) {
			for i := range a {
				if a[i] < b[i] {
					return true
				}
			}
			return false
		}
		return len(a) < len(b)
	}
	sort.Slice(dists, func(i, j int) bool {
		return lessArr(dists[i].goals, dists[j].goals) || lessArr(dists[i].paths, dists[j].paths)
	})

	outBytes := s.writeVars(vars)

	if err := pathtools.WriteFileIfChanged(outFile, outBytes, 0666); err != nil {
		ctx.Errorf(err.Error())
	}

	lateOutBytes := s.writeLate(phonies, dists)

	if err := pathtools.WriteFileIfChanged(lateOutFile, lateOutBytes, 0666); err != nil {
		ctx.Errorf(err.Error())
	}

	installsBytes := s.writeInstalls(katiInstalls, katiSymlinks)
	if err := pathtools.WriteFileIfChanged(installsFile, installsBytes, 0666); err != nil {
		ctx.Errorf(err.Error())
	}

	// Only save state for tests when testing.
	if ctx.Config().RunningInsideUnitTest() {
		s.varsForTesting = vars
		s.installsForTesting = installsBytes
	}
}

func (s *makeVarsSingleton) writeVars(vars []makeVarsVariable) []byte {
	buf := &bytes.Buffer{}

	fmt.Fprint(buf, `# Autogenerated file

# Compares SOONG_$(1) against $(1), and warns if they are not equal.
#
# If the original variable is empty, then just set it to the SOONG_ version.
#
# $(1): Name of the variable to check
# $(2): If not-empty, sort the values before comparing
# $(3): Extra snippet to run if it does not match
define soong-compare-var
ifneq ($$($(1)),)
  my_val_make := $$(strip $(if $(2),$$(sort $$($(1))),$$($(1))))
  my_val_soong := $(if $(2),$$(sort $$(SOONG_$(1))),$$(SOONG_$(1)))
  ifneq ($$(my_val_make),$$(my_val_soong))
    $$(warning $(1) does not match between Make and Soong:)
    $(if $(2),$$(warning Make  adds: $$(filter-out $$(my_val_soong),$$(my_val_make))),$$(warning Make : $$(my_val_make)))
    $(if $(2),$$(warning Soong adds: $$(filter-out $$(my_val_make),$$(my_val_soong))),$$(warning Soong: $$(my_val_soong)))
    $(3)
  endif
  my_val_make :=
  my_val_soong :=
else
  $(1) := $$(SOONG_$(1))
endif
.KATI_READONLY := $(1) SOONG_$(1)
endef

my_check_failed := false

`)

	// Write all the strict checks out first so that if one of them errors,
	// we get all of the strict errors printed, but not the non-strict
	// warnings.
	for _, v := range vars {
		if !v.strict {
			continue
		}

		sort := ""
		if v.sort {
			sort = "true"
		}

		fmt.Fprintf(buf, "SOONG_%s := %s\n", v.name, v.value)
		fmt.Fprintf(buf, "$(eval $(call soong-compare-var,%s,%s,my_check_failed := true))\n\n", v.name, sort)
	}

	fmt.Fprint(buf, `
ifneq ($(my_check_failed),false)
  $(error Soong variable check failed)
endif
my_check_failed :=


`)

	for _, v := range vars {
		if v.strict {
			continue
		}

		sort := ""
		if v.sort {
			sort = "true"
		}

		fmt.Fprintf(buf, "SOONG_%s := %s\n", v.name, v.value)
		fmt.Fprintf(buf, "$(eval $(call soong-compare-var,%s,%s))\n\n", v.name, sort)
	}

	fmt.Fprintln(buf, "\nsoong-compare-var :=")

	fmt.Fprintln(buf)

	return buf.Bytes()
}

func (s *makeVarsSingleton) writeLate(phonies []phony, dists []dist) []byte {
	buf := &bytes.Buffer{}

	fmt.Fprint(buf, `# Autogenerated file

# Values written by Soong read after parsing all Android.mk files.


`)

	for _, phony := range phonies {
		fmt.Fprintf(buf, ".PHONY: %s\n", phony.name)
		fmt.Fprintf(buf, "%s: %s\n", phony.name, strings.Join(phony.deps, "\\\n  "))
	}

	fmt.Fprintln(buf)

	for _, dist := range dists {
		fmt.Fprintf(buf, ".PHONY: %s\n", strings.Join(dist.goals, " "))
		fmt.Fprintf(buf, "$(call dist-for-goals,%s,%s)\n",
			strings.Join(dist.goals, " "), strings.Join(dist.paths, " "))
	}

	return buf.Bytes()
}

// writeInstalls writes the list of install rules generated by Soong to a makefile.  The rules
// are exported to Make instead of written directly to the ninja file so that main.mk can add
// the dependencies from the `required` property that are hard to resolve in Soong.
func (s *makeVarsSingleton) writeInstalls(installs, symlinks []katiInstall) []byte {
	buf := &bytes.Buffer{}

	fmt.Fprint(buf, `# Autogenerated file

# Values written by Soong to generate install rules that can be amended by Kati.


`)

	preserveSymlinksFlag := "-d"
	if runtime.GOOS == "darwin" {
		preserveSymlinksFlag = "-R"
	}

	for _, install := range installs {
		// Write a rule for each install request in the form:
		//  to: from [ deps ] [ | order only deps ]
		//       cp -f -d $< $@ [ && chmod +x $@ ]
		fmt.Fprintf(buf, "%s: %s", install.to.String(), install.from.String())
		for _, dep := range install.implicitDeps {
			fmt.Fprintf(buf, " %s", dep.String())
		}
		if extraFiles := install.extraFiles; extraFiles != nil {
			fmt.Fprintf(buf, " %s", extraFiles.zip.String())
		}
		if len(install.orderOnlyDeps) > 0 {
			fmt.Fprintf(buf, " |")
		}
		for _, dep := range install.orderOnlyDeps {
			fmt.Fprintf(buf, " %s", dep.String())
		}
		fmt.Fprintln(buf)
		fmt.Fprintln(buf, "\t@echo \"Install: $@\"")
		fmt.Fprintf(buf, "\trm -f $@ && cp -f %s $< $@\n", preserveSymlinksFlag)
		if install.executable {
			fmt.Fprintf(buf, "\tchmod +x $@\n")
		}
		if extraFiles := install.extraFiles; extraFiles != nil {
			fmt.Fprintf(buf, "\t( unzip -qDD -d '%s' '%s' 2>&1 | grep -v \"zipfile is empty\"; exit $${PIPESTATUS[0]} ) || \\\n", extraFiles.dir.String(), extraFiles.zip.String())
			fmt.Fprintf(buf, "\t  ( code=$$?; if [ $$code -ne 0 -a $$code -ne 1 ]; then exit $$code; fi )\n")
		}
		fmt.Fprintln(buf)
	}

	for _, symlink := range symlinks {
		fmt.Fprintf(buf, "%s:", symlink.to.String())
		if symlink.from != nil {
			// The symlink doesn't need updating when the target is modified, but we sometimes
			// have a dependency on a symlink to a binary instead of to the binary directly, and
			// the mtime of the symlink must be updated when the binary is modified, so use a
			// normal dependency here instead of an order-only dependency.
			fmt.Fprintf(buf, " %s", symlink.from.String())
		}
		for _, dep := range symlink.implicitDeps {
			fmt.Fprintf(buf, " %s", dep.String())
		}
		if len(symlink.orderOnlyDeps) > 0 {
			fmt.Fprintf(buf, " |")
		}
		for _, dep := range symlink.orderOnlyDeps {
			fmt.Fprintf(buf, " %s", dep.String())
		}
		fmt.Fprintln(buf)

		fromStr := ""
		if symlink.from != nil {
			rel, err := filepath.Rel(filepath.Dir(symlink.to.String()), symlink.from.String())
			if err != nil {
				panic(fmt.Errorf("failed to find relative path for symlink from %q to %q: %w",
					symlink.from.String(), symlink.to.String(), err))
			}
			fromStr = rel
		} else {
			fromStr = symlink.absFrom
		}

		fmt.Fprintln(buf, "\t@echo \"Symlink: $@\"")
		fmt.Fprintf(buf, "\trm -f $@ && ln -sfn %s $@", fromStr)
		fmt.Fprintln(buf)
		fmt.Fprintln(buf)
	}

	return buf.Bytes()
}

func (c *makeVarsContext) DeviceConfig() DeviceConfig {
	return DeviceConfig{c.Config().deviceConfig}
}

var ninjaDescaper = strings.NewReplacer("$$", "$")

func (c *makeVarsContext) Eval(ninjaStr string) (string, error) {
	s, err := c.SingletonContext.Eval(c.pctx, ninjaStr)
	if err != nil {
		return "", err
	}
	// SingletonContext.Eval returns an exapnded string that is valid for a ninja file, de-escape $$ to $ for use
	// in a Makefile
	return ninjaDescaper.Replace(s), nil
}

func (c *makeVarsContext) addVariableRaw(name, value string, strict, sort bool) {
	c.vars = append(c.vars, makeVarsVariable{
		name:   name,
		value:  value,
		strict: strict,
		sort:   sort,
	})
}

func (c *makeVarsContext) addVariable(name, ninjaStr string, strict, sort bool) {
	value, err := c.Eval(ninjaStr)
	if err != nil {
		c.SingletonContext.Errorf(err.Error())
	}
	c.addVariableRaw(name, value, strict, sort)
}

func (c *makeVarsContext) addPhony(name string, deps []string) {
	c.phonies = append(c.phonies, phony{name, deps})
}

func (c *makeVarsContext) addDist(goals []string, paths []string) {
	c.dists = append(c.dists, dist{
		goals: goals,
		paths: paths,
	})
}

func (c *makeVarsContext) Strict(name, ninjaStr string) {
	c.addVariable(name, ninjaStr, true, false)
}
func (c *makeVarsContext) StrictSorted(name, ninjaStr string) {
	c.addVariable(name, ninjaStr, true, true)
}
func (c *makeVarsContext) StrictRaw(name, value string) {
	c.addVariableRaw(name, value, true, false)
}

func (c *makeVarsContext) Check(name, ninjaStr string) {
	c.addVariable(name, ninjaStr, false, false)
}
func (c *makeVarsContext) CheckSorted(name, ninjaStr string) {
	c.addVariable(name, ninjaStr, false, true)
}
func (c *makeVarsContext) CheckRaw(name, value string) {
	c.addVariableRaw(name, value, false, false)
}

func (c *makeVarsContext) Phony(name string, deps ...Path) {
	c.addPhony(name, Paths(deps).Strings())
}

func (c *makeVarsContext) DistForGoal(goal string, paths ...Path) {
	c.DistForGoals([]string{goal}, paths...)
}

func (c *makeVarsContext) DistForGoalWithFilename(goal string, path Path, filename string) {
	c.DistForGoalsWithFilename([]string{goal}, path, filename)
}

func (c *makeVarsContext) DistForGoals(goals []string, paths ...Path) {
	c.addDist(goals, Paths(paths).Strings())
}

func (c *makeVarsContext) DistForGoalsWithFilename(goals []string, path Path, filename string) {
	c.addDist(goals, []string{path.String() + ":" + filename})
}
