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

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

	android.RegisterBottomUpMutator("genrule_deps", genruleDepsMutator)
}

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

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

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

type HostToolProvider interface {
	HostToolPath() android.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 {
	android.ModuleBase

	properties generatorProperties

	tasks taskFunc

	deps android.Paths
	rule blueprint.Rule

	genPath android.Path

	outputFiles android.Paths
}

type taskFunc func(ctx android.ModuleContext) []generateTask

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

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

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

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

func (g *generator) GenerateAndroidBuildActions(ctx android.ModuleContext) {
	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 := android.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 = android.PathForModuleGen(ctx, "")

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

func (g *generator) generateSourceFile(ctx android.ModuleContext, task generateTask, tool string) {
	ctx.ModuleBuild(pctx, android.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 android.InitAndroidModule(module, props...)
}

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

	tasks := func(ctx android.ModuleContext) []generateTask {
		srcFiles := ctx.ExpandSources(properties.Srcs, nil)
		tasks := make([]generateTask, 0, len(srcFiles))
		for _, in := range srcFiles {
			tasks = append(tasks, generateTask{
				in:  android.Paths{in},
				out: android.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 android.ModuleContext) []generateTask {
		return []generateTask{
			{
				in:  ctx.ExpandSources(properties.Srcs, nil),
				out: android.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
}
