// Copyright 2015 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 cc

import (
	"path/filepath"
	"strings"

	"android/soong/aidl_library"
	"android/soong/bazel"

	"github.com/google/blueprint"

	"android/soong/android"
)

func init() {
	pctx.SourcePathVariable("lexCmd", "prebuilts/build-tools/${config.HostPrebuiltTag}/bin/flex")
	pctx.SourcePathVariable("m4Cmd", "prebuilts/build-tools/${config.HostPrebuiltTag}/bin/m4")

	pctx.HostBinToolVariable("aidlCmd", "aidl-cpp")
	pctx.HostBinToolVariable("syspropCmd", "sysprop_cpp")
}

var (
	lex = pctx.AndroidStaticRule("lex",
		blueprint.RuleParams{
			Command:     "M4=$m4Cmd $lexCmd $flags -o$out $in",
			CommandDeps: []string{"$lexCmd", "$m4Cmd"},
		}, "flags")

	sysprop = pctx.AndroidStaticRule("sysprop",
		blueprint.RuleParams{
			Command: "$syspropCmd --header-dir=$headerOutDir --public-header-dir=$publicOutDir " +
				"--source-dir=$srcOutDir --include-name=$includeName $in",
			CommandDeps: []string{"$syspropCmd"},
		},
		"headerOutDir", "publicOutDir", "srcOutDir", "includeName")
)

type YaccProperties struct {
	// list of module-specific flags that will be used for .y and .yy compiles
	Flags []string

	// whether the yacc files will produce a location.hh file
	Gen_location_hh *bool

	// whether the yacc files will product a position.hh file
	Gen_position_hh *bool
}

func genYacc(ctx android.ModuleContext, rule *android.RuleBuilder, yaccFile android.Path,
	outFile android.ModuleGenPath, props *YaccProperties) (headerFiles android.Paths) {

	outDir := android.PathForModuleGen(ctx, "yacc")
	headerFile := android.GenPathWithExt(ctx, "yacc", yaccFile, "h")
	ret := android.Paths{headerFile}

	cmd := rule.Command()

	// Fix up #line markers to not use the sbox temporary directory
	// android.sboxPathForOutput(outDir, outDir) returns the sbox placeholder for the out
	// directory itself, without any filename appended.
	sboxOutDir := cmd.PathForOutput(outDir)
	sedCmd := "sed -i.bak 's#" + sboxOutDir + "#" + outDir.String() + "#'"
	rule.Command().Text(sedCmd).Input(outFile)
	rule.Command().Text(sedCmd).Input(headerFile)

	var flags []string
	if props != nil {
		flags = props.Flags

		if Bool(props.Gen_location_hh) {
			locationHeader := outFile.InSameDir(ctx, "location.hh")
			ret = append(ret, locationHeader)
			cmd.ImplicitOutput(locationHeader)
			rule.Command().Text(sedCmd).Input(locationHeader)
		}
		if Bool(props.Gen_position_hh) {
			positionHeader := outFile.InSameDir(ctx, "position.hh")
			ret = append(ret, positionHeader)
			cmd.ImplicitOutput(positionHeader)
			rule.Command().Text(sedCmd).Input(positionHeader)
		}
	}

	cmd.Text("BISON_PKGDATADIR=prebuilts/build-tools/common/bison").
		FlagWithInput("M4=", ctx.Config().PrebuiltBuildTool(ctx, "m4")).
		PrebuiltBuildTool(ctx, "bison").
		Flag("-d").
		Flags(flags).
		FlagWithOutput("--defines=", headerFile).
		Flag("-o").Output(outFile).Input(yaccFile)

	return ret
}

func genAidl(
	ctx android.ModuleContext,
	rule *android.RuleBuilder,
	outDirBase string,
	aidlFile android.Path,
	aidlHdrs android.Paths,
	aidlFlags string,
) (cppFile android.OutputPath, headerFiles android.Paths) {
	aidlPackage := strings.TrimSuffix(aidlFile.Rel(), aidlFile.Base())
	baseName := strings.TrimSuffix(aidlFile.Base(), aidlFile.Ext())
	shortName := baseName
	// TODO(b/111362593): aidl_to_cpp_common.cpp uses heuristics to figure out if
	//   an interface name has a leading I. Those same heuristics have been
	//   moved here.
	if len(baseName) >= 2 && baseName[0] == 'I' &&
		strings.ToUpper(baseName)[1] == baseName[1] {
		shortName = strings.TrimPrefix(baseName, "I")
	}

	outDir := android.PathForModuleGen(ctx, outDirBase)
	cppFile = outDir.Join(ctx, aidlPackage, baseName+".cpp")
	depFile := outDir.Join(ctx, aidlPackage, baseName+".cpp.d")
	headerI := outDir.Join(ctx, aidlPackage, baseName+".h")
	headerBn := outDir.Join(ctx, aidlPackage, "Bn"+shortName+".h")
	headerBp := outDir.Join(ctx, aidlPackage, "Bp"+shortName+".h")

	cmd := rule.Command()
	cmd.BuiltTool("aidl-cpp").
		// libc++ is default stl for aidl-cpp (a cc_binary_host module)
		ImplicitTool(ctx.Config().HostCcSharedLibPath(ctx, "libc++")).
		FlagWithDepFile("-d", depFile).
		Flag("--ninja").
		Flag(aidlFlags).
		Input(aidlFile).
		OutputDir().
		Output(cppFile).
		ImplicitOutputs(android.WritablePaths{
			headerI,
			headerBn,
			headerBp,
		})

	if aidlHdrs != nil {
		cmd.Implicits(aidlHdrs)
	}

	return cppFile, android.Paths{
		headerI,
		headerBn,
		headerBp,
	}
}

type LexProperties struct {
	// list of module-specific flags that will be used for .l and .ll compiles
	Flags []string
}

func genLex(ctx android.ModuleContext, lexFile android.Path, outFile android.ModuleGenPath, props *LexProperties) {
	var flags []string
	if props != nil {
		flags = props.Flags
	}
	flagsString := strings.Join(flags[:], " ")
	ctx.Build(pctx, android.BuildParams{
		Rule:        lex,
		Description: "lex " + lexFile.Rel(),
		Output:      outFile,
		Input:       lexFile,
		Args:        map[string]string{"flags": flagsString},
	})
}

type LexAttrs struct {
	Srcs    bazel.LabelListAttribute
	Lexopts bazel.StringListAttribute
}

type LexNames struct {
	cSrcName bazel.LabelAttribute
	srcName  bazel.LabelAttribute
}

func bp2BuildLex(ctx android.Bp2buildMutatorContext, moduleName string, ca compilerAttributes) LexNames {
	names := LexNames{}
	if !ca.lSrcs.IsEmpty() {
		names.cSrcName = createLexTargetModule(ctx, moduleName+"_genlex_l", ca.lSrcs, ca.lexopts)
	}
	if !ca.llSrcs.IsEmpty() {
		names.srcName = createLexTargetModule(ctx, moduleName+"_genlex_ll", ca.llSrcs, ca.lexopts)
	}
	return names
}

func createLexTargetModule(ctx android.Bp2buildMutatorContext, name string, srcs bazel.LabelListAttribute, opts bazel.StringListAttribute) bazel.LabelAttribute {
	ctx.CreateBazelTargetModule(
		bazel.BazelTargetModuleProperties{
			Rule_class:        "genlex",
			Bzl_load_location: "//build/bazel/rules/cc:flex.bzl",
		},
		android.CommonAttributes{Name: name},
		&LexAttrs{
			Srcs:    srcs,
			Lexopts: opts,
		})
	return bazel.LabelAttribute{Value: &bazel.Label{Label: ":" + name}}
}

func genSysprop(ctx android.ModuleContext, syspropFile android.Path) (android.Path, android.Paths) {
	headerFile := android.PathForModuleGen(ctx, "sysprop", "include", syspropFile.Rel()+".h")
	publicHeaderFile := android.PathForModuleGen(ctx, "sysprop/public", "include", syspropFile.Rel()+".h")
	cppFile := android.PathForModuleGen(ctx, "sysprop", syspropFile.Rel()+".cpp")

	headers := android.WritablePaths{headerFile, publicHeaderFile}

	ctx.Build(pctx, android.BuildParams{
		Rule:            sysprop,
		Description:     "sysprop " + syspropFile.Rel(),
		Output:          cppFile,
		ImplicitOutputs: headers,
		Input:           syspropFile,
		Args: map[string]string{
			"headerOutDir": filepath.Dir(headerFile.String()),
			"publicOutDir": filepath.Dir(publicHeaderFile.String()),
			"srcOutDir":    filepath.Dir(cppFile.String()),
			"includeName":  syspropFile.Rel() + ".h",
		},
	})

	return cppFile, headers.Paths()
}

func bp2buildCcSysprop(ctx android.Bp2buildMutatorContext, moduleName string, minSdkVersion *string, srcs bazel.LabelListAttribute) *bazel.LabelAttribute {
	labels := SyspropLibraryLabels{
		SyspropLibraryLabel: moduleName + "_sysprop_library",
		StaticLibraryLabel:  moduleName + "_cc_sysprop_library_static",
	}
	Bp2buildSysprop(ctx, labels, srcs, minSdkVersion)
	return createLabelAttributeCorrespondingToSrcs(":"+labels.StaticLibraryLabel, srcs)
}

// Creates a LabelAttribute for a given label where the value is only set for
// the same config values that have values in a given LabelListAttribute
func createLabelAttributeCorrespondingToSrcs(baseLabelName string, srcs bazel.LabelListAttribute) *bazel.LabelAttribute {
	baseLabel := bazel.Label{Label: baseLabelName}
	label := bazel.LabelAttribute{}
	if !srcs.Value.IsNil() && !srcs.Value.IsEmpty() {
		label.Value = &baseLabel
		return &label
	}
	for axis, configToSrcs := range srcs.ConfigurableValues {
		for config, val := range configToSrcs {
			if !val.IsNil() && !val.IsEmpty() {
				label.SetSelectValue(axis, config, baseLabel)
			}
		}
	}
	return &label
}

// Used to communicate information from the genSources method back to the library code that uses
// it.
type generatedSourceInfo struct {
	// The headers created from .proto files
	protoHeaders android.Paths

	// The files that can be used as order only dependencies in order to ensure that the proto header
	// files are up to date.
	protoOrderOnlyDeps android.Paths

	// The headers created from .aidl files
	aidlHeaders android.Paths

	// The files that can be used as order only dependencies in order to ensure that the aidl header
	// files are up to date.
	aidlOrderOnlyDeps android.Paths

	// The headers created from .sysprop files
	syspropHeaders android.Paths

	// The files that can be used as order only dependencies in order to ensure that the sysprop
	// header files are up to date.
	syspropOrderOnlyDeps android.Paths
}

func genSources(
	ctx android.ModuleContext,
	aidlLibraryInfos []aidl_library.AidlLibraryInfo,
	srcFiles android.Paths,
	buildFlags builderFlags,
) (android.Paths, android.Paths, generatedSourceInfo) {

	var info generatedSourceInfo

	var deps android.Paths
	var rsFiles android.Paths

	// aidlRule supports compiling aidl files from srcs prop while aidlLibraryRule supports
	// compiling aidl files from aidl_library modules specified in aidl.libs prop.
	// The rules are separated so that they don't wipe out the other's outputDir
	var aidlRule *android.RuleBuilder
	var aidlLibraryRule *android.RuleBuilder

	var yaccRule_ *android.RuleBuilder
	yaccRule := func() *android.RuleBuilder {
		if yaccRule_ == nil {
			yaccRule_ = android.NewRuleBuilder(pctx, ctx).Sbox(android.PathForModuleGen(ctx, "yacc"),
				android.PathForModuleGen(ctx, "yacc.sbox.textproto"))
		}
		return yaccRule_
	}

	for i, srcFile := range srcFiles {
		switch srcFile.Ext() {
		case ".y":
			cFile := android.GenPathWithExt(ctx, "yacc", srcFile, "c")
			srcFiles[i] = cFile
			deps = append(deps, genYacc(ctx, yaccRule(), srcFile, cFile, buildFlags.yacc)...)
		case ".yy":
			cppFile := android.GenPathWithExt(ctx, "yacc", srcFile, "cpp")
			srcFiles[i] = cppFile
			deps = append(deps, genYacc(ctx, yaccRule(), srcFile, cppFile, buildFlags.yacc)...)
		case ".l":
			cFile := android.GenPathWithExt(ctx, "lex", srcFile, "c")
			srcFiles[i] = cFile
			genLex(ctx, srcFile, cFile, buildFlags.lex)
		case ".ll":
			cppFile := android.GenPathWithExt(ctx, "lex", srcFile, "cpp")
			srcFiles[i] = cppFile
			genLex(ctx, srcFile, cppFile, buildFlags.lex)
		case ".proto":
			ccFile, headerFile := genProto(ctx, srcFile, buildFlags)
			srcFiles[i] = ccFile
			info.protoHeaders = append(info.protoHeaders, headerFile)
			// Use the generated header as an order only dep to ensure that it is up to date when needed.
			info.protoOrderOnlyDeps = append(info.protoOrderOnlyDeps, headerFile)
		case ".aidl":
			if aidlRule == nil {
				aidlRule = android.NewRuleBuilder(pctx, ctx).Sbox(android.PathForModuleGen(ctx, "aidl"),
					android.PathForModuleGen(ctx, "aidl.sbox.textproto"))
			}
			baseDir := strings.TrimSuffix(srcFile.String(), srcFile.Rel())
			cppFile, aidlHeaders := genAidl(
				ctx,
				aidlRule,
				"aidl",
				srcFile,
				nil,
				buildFlags.aidlFlags+" -I"+baseDir,
			)
			srcFiles[i] = cppFile

			info.aidlHeaders = append(info.aidlHeaders, aidlHeaders...)
			// Use the generated headers as order only deps to ensure that they are up to date when
			// needed.
			// TODO: Reduce the size of the ninja file by using one order only dep for the whole rule
			info.aidlOrderOnlyDeps = append(info.aidlOrderOnlyDeps, aidlHeaders...)
		case ".rscript", ".fs":
			cppFile := rsGeneratedCppFile(ctx, srcFile)
			rsFiles = append(rsFiles, srcFiles[i])
			srcFiles[i] = cppFile
		case ".sysprop":
			cppFile, headerFiles := genSysprop(ctx, srcFile)
			srcFiles[i] = cppFile
			info.syspropHeaders = append(info.syspropHeaders, headerFiles...)
			// Use the generated headers as order only deps to ensure that they are up to date when
			// needed.
			info.syspropOrderOnlyDeps = append(info.syspropOrderOnlyDeps, headerFiles...)
		}
	}

	for _, aidlLibraryInfo := range aidlLibraryInfos {
		if aidlLibraryRule == nil {
			aidlLibraryRule = android.NewRuleBuilder(pctx, ctx).Sbox(
				android.PathForModuleGen(ctx, "aidl_library"),
				android.PathForModuleGen(ctx, "aidl_library.sbox.textproto"),
			).SandboxInputs()
		}
		for _, aidlSrc := range aidlLibraryInfo.Srcs {
			cppFile, aidlHeaders := genAidl(
				ctx,
				aidlLibraryRule,
				"aidl_library",
				aidlSrc,
				aidlLibraryInfo.Hdrs.ToList(),
				buildFlags.aidlFlags,
			)

			srcFiles = append(srcFiles, cppFile)
			info.aidlHeaders = append(info.aidlHeaders, aidlHeaders...)
			// Use the generated headers as order only deps to ensure that they are up to date when
			// needed.
			// TODO: Reduce the size of the ninja file by using one order only dep for the whole rule
			info.aidlOrderOnlyDeps = append(info.aidlOrderOnlyDeps, aidlHeaders...)
		}
	}

	if aidlRule != nil {
		aidlRule.Build("aidl", "gen aidl")
	}

	if aidlLibraryRule != nil {
		aidlLibraryRule.Build("aidl_library", "gen aidl_library")
	}

	if yaccRule_ != nil {
		yaccRule_.Build("yacc", "gen yacc")
	}

	deps = append(deps, info.protoOrderOnlyDeps...)
	deps = append(deps, info.aidlOrderOnlyDeps...)
	deps = append(deps, info.syspropOrderOnlyDeps...)

	if len(rsFiles) > 0 {
		deps = append(deps, rsGenerateCpp(ctx, rsFiles, buildFlags.rsFlags)...)
	}

	return srcFiles, deps, info
}
