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

import (
	"github.com/google/blueprint"

	"android/soong"
	"android/soong/common"
)

func init() {
	soong.RegisterModuleType("gensrcs", GenSrcsFactory)
	soong.RegisterModuleType("genrule", GenRuleFactory)

	common.RegisterBottomUpMutator("genrule_deps", genruleDepsMutator)
}

var (
	pctx = common.NewPackageContext("android/soong/genrule")
)

func init() {
	pctx.SourcePathVariable("srcDir", "")
	pctx.HostBinToolVariable("hostBin", "")
}

type SourceFileGenerator interface {
	GeneratedSourceFiles() common.Paths
	GeneratedHeaderDir() common.Path
}

type HostToolProvider interface {
	HostToolPath() common.OptionalPath
}

type generatorProperties struct {
	// command to run on one or more input files.  Available variables for substitution:
	// $tool: the path to the `tool` or `tool_file`
	// $in: one or more input files
	// $out: a single output file
	// $srcDir: the root directory of the source tree
	// The host bin directory will be in the path
	Cmd string

	// name of the module (if any) that produces the host executable.   Leave empty for
	// prebuilts or scripts that do not need a module to build them.
	Tool string

	// Local file that is used as the tool
	Tool_file string
}

type generator struct {
	common.AndroidModuleBase

	properties generatorProperties

	tasks taskFunc

	deps common.Paths
	rule blueprint.Rule

	genPath common.Path

	outputFiles common.Paths
}

type taskFunc func(ctx common.AndroidModuleContext) []generateTask

type generateTask struct {
	in  common.Paths
	out common.ModuleGenPath
}

func (g *generator) GeneratedSourceFiles() common.Paths {
	return g.outputFiles
}

func (g *generator) GeneratedHeaderDir() common.Path {
	return g.genPath
}

func genruleDepsMutator(ctx common.AndroidBottomUpMutatorContext) {
	if g, ok := ctx.Module().(*generator); ok {
		if g.properties.Tool != "" {
			ctx.AddFarVariationDependencies([]blueprint.Variation{
				{"host_or_device", common.Host.String()},
				{"host_type", common.CurrentHostType().String()},
			}, nil, g.properties.Tool)
		}
	}
}

func (g *generator) GenerateAndroidBuildActions(ctx common.AndroidModuleContext) {
	if g.properties.Tool != "" && g.properties.Tool_file != "" {
		ctx.ModuleErrorf("`tool` and `tool_file` may not be specified at the same time")
		return
	}

	g.rule = ctx.Rule(pctx, "generator", blueprint.RuleParams{
		Command: "PATH=$$PATH:$hostBin " + g.properties.Cmd,
	}, "tool")

	var tool string
	if g.properties.Tool_file != "" {
		toolpath := common.PathForModuleSrc(ctx, g.properties.Tool_file)
		g.deps = append(g.deps, toolpath)
		tool = toolpath.String()
	} else if g.properties.Tool != "" {
		ctx.VisitDirectDeps(func(module blueprint.Module) {
			if t, ok := module.(HostToolProvider); ok {
				p := t.HostToolPath()
				if p.Valid() {
					g.deps = append(g.deps, p.Path())
					tool = p.String()
				} else {
					ctx.ModuleErrorf("host tool %q missing output file", ctx.OtherModuleName(module))
				}
			} else {
				ctx.ModuleErrorf("unknown dependency %q", ctx.OtherModuleName(module))
			}
		})
	}

	g.genPath = common.PathForModuleGen(ctx, "")

	for _, task := range g.tasks(ctx) {
		g.generateSourceFile(ctx, task, tool)
	}
}

func (g *generator) generateSourceFile(ctx common.AndroidModuleContext, task generateTask, tool string) {
	ctx.ModuleBuild(pctx, common.ModuleBuildParams{
		Rule:      g.rule,
		Output:    task.out,
		Inputs:    task.in,
		Implicits: g.deps,
		Args: map[string]string{
			"tool": tool,
		},
	})

	g.outputFiles = append(g.outputFiles, task.out)
}

func generatorFactory(tasks taskFunc, props ...interface{}) (blueprint.Module, []interface{}) {
	module := &generator{
		tasks: tasks,
	}

	props = append(props, &module.properties)

	return common.InitAndroidModule(module, props...)
}

func GenSrcsFactory() (blueprint.Module, []interface{}) {
	properties := &genSrcsProperties{}

	tasks := func(ctx common.AndroidModuleContext) []generateTask {
		srcFiles := ctx.ExpandSources(properties.Srcs, nil)
		tasks := make([]generateTask, 0, len(srcFiles))
		for _, in := range srcFiles {
			tasks = append(tasks, generateTask{
				in:  common.Paths{in},
				out: common.GenPathWithExt(ctx, in, properties.Output_extension),
			})
		}
		return tasks
	}

	return generatorFactory(tasks, properties)
}

type genSrcsProperties struct {
	// list of input files
	Srcs []string

	// extension that will be substituted for each output file
	Output_extension string
}

func GenRuleFactory() (blueprint.Module, []interface{}) {
	properties := &genRuleProperties{}

	tasks := func(ctx common.AndroidModuleContext) []generateTask {
		return []generateTask{
			{
				in:  ctx.ExpandSources(properties.Srcs, nil),
				out: common.PathForModuleGen(ctx, properties.Out),
			},
		}
	}

	return generatorFactory(tasks, properties)
}

type genRuleProperties struct {
	// list of input files
	Srcs []string

	// name of the output file that will be generated
	Out string
}
