// Copyright 2014 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 blueprint

import (
	"errors"
	"fmt"
	"reflect"
	"runtime"
	"strings"
	"sync"
)

// A PackageContext provides a way to create package-scoped Ninja pools,
// rules, and variables.  A Go package should create a single unexported
// package-scoped PackageContext variable that it uses to create all package-
// scoped Ninja object definitions.  This PackageContext object should then be
// passed to all calls to define module- or singleton-specific Ninja
// definitions.  For example:
//
//     package blah
//
//     import (
//         "blueprint"
//     )
//
//     var (
//         pctx = NewPackageContext("path/to/blah")
//
//         myPrivateVar = pctx.StaticVariable("myPrivateVar", "abcdef")
//         MyExportedVar = pctx.StaticVariable("MyExportedVar", "$myPrivateVar 123456!")
//
//         SomeRule = pctx.StaticRule(...)
//     )
//
//     // ...
//
//     func (m *MyModule) GenerateBuildActions(ctx blueprint.Module) {
//         ctx.Build(pctx, blueprint.BuildParams{
//             Rule:    SomeRule,
//             Outputs: []string{"$myPrivateVar"},
//         })
//     }
type PackageContext interface {
	Import(pkgPath string)
	ImportAs(as, pkgPath string)

	StaticVariable(name, value string) Variable
	VariableFunc(name string, f func(config interface{}) (string, error)) Variable
	VariableConfigMethod(name string, method interface{}) Variable

	StaticPool(name string, params PoolParams) Pool
	PoolFunc(name string, f func(interface{}) (PoolParams, error)) Pool

	StaticRule(name string, params RuleParams, argNames ...string) Rule
	RuleFunc(name string, f func(interface{}) (RuleParams, error), argNames ...string) Rule

	AddNinjaFileDeps(deps ...string)

	getScope() *basicScope
}

type packageContext struct {
	fullName      string
	shortName     string
	pkgPath       string
	scope         *basicScope
	ninjaFileDeps []string
}

var _ PackageContext = &packageContext{}

func (p *packageContext) getScope() *basicScope {
	return p.scope
}

var packageContexts = map[string]*packageContext{}

// NewPackageContext creates a PackageContext object for a given package.  The
// pkgPath argument should always be set to the full path used to import the
// package.  This function may only be called from a Go package's init()
// function or as part of a package-scoped variable initialization.
func NewPackageContext(pkgPath string) PackageContext {
	checkCalledFromInit()

	if _, present := packageContexts[pkgPath]; present {
		panic(fmt.Errorf("package %q already has a package context", pkgPath))
	}

	pkgName := pkgPathToName(pkgPath)
	err := validateNinjaName(pkgName)
	if err != nil {
		panic(err)
	}

	i := strings.LastIndex(pkgPath, "/")
	shortName := pkgPath[i+1:]

	p := &packageContext{
		fullName:  pkgName,
		shortName: shortName,
		pkgPath:   pkgPath,
		scope:     newScope(nil),
	}

	packageContexts[pkgPath] = p

	return p
}

var Phony Rule = &builtinRule{
	name_: "phony",
}

var Console Pool = &builtinPool{
	name_: "console",
}

var errRuleIsBuiltin = errors.New("the rule is a built-in")
var errPoolIsBuiltin = errors.New("the pool is a built-in")
var errVariableIsArg = errors.New("argument variables have no value")

// checkCalledFromInit panics if a Go package's init function is not on the
// call stack.
func checkCalledFromInit() {
	for skip := 3; ; skip++ {
		_, funcName, ok := callerName(skip)
		if !ok {
			panic("not called from an init func")
		}

		if funcName == "init" || strings.HasPrefix(funcName, "init·") {
			return
		}
	}
}

// callerName returns the package path and function name of the calling
// function.  The skip argument has the same meaning as the skip argument of
// runtime.Callers.
func callerName(skip int) (pkgPath, funcName string, ok bool) {
	var pc [1]uintptr
	n := runtime.Callers(skip+1, pc[:])
	if n != 1 {
		return "", "", false
	}

	f := runtime.FuncForPC(pc[0])
	fullName := f.Name()

	lastDotIndex := strings.LastIndex(fullName, ".")
	if lastDotIndex == -1 {
		panic("unable to distinguish function name from package")
	}

	if fullName[lastDotIndex-1] == ')' {
		// The caller is a method on some type, so it's name looks like
		// "pkg/path.(type).method".  We need to go back one dot farther to get
		// to the package name.
		lastDotIndex = strings.LastIndex(fullName[:lastDotIndex], ".")
	}

	pkgPath = fullName[:lastDotIndex]
	funcName = fullName[lastDotIndex+1:]
	ok = true
	return
}

// pkgPathToName makes a Ninja-friendly name out of a Go package name by
// replaceing all the '/' characters with '.'.  We assume the results are
// unique, though this is not 100% guaranteed for Go package names that
// already contain '.' characters. Disallowing package names with '.' isn't
// reasonable since many package names contain the name of the hosting site
// (e.g. "code.google.com").  In practice this probably isn't really a
// problem.
func pkgPathToName(pkgPath string) string {
	return strings.Replace(pkgPath, "/", ".", -1)
}

// Import enables access to the exported Ninja pools, rules, and variables
// that are defined at the package scope of another Go package.  Go's
// visibility rules apply to these references - capitalized names indicate
// that something is exported.  It may only be called from a Go package's
// init() function.  The Go package path passed to Import must have already
// been imported into the Go package using a Go import statement.  The
// imported variables may then be accessed from Ninja strings as
// "${pkg.Variable}", while the imported rules can simply be accessed as
// exported Go variables from the package.  For example:
//
//     import (
//         "blueprint"
//         "foo/bar"
//     )
//
//     var pctx = NewPackagePath("blah")
//
//     func init() {
//         pctx.Import("foo/bar")
//     }
//
//     ...
//
//     func (m *MyModule) GenerateBuildActions(ctx blueprint.Module) {
//         ctx.Build(pctx, blueprint.BuildParams{
//             Rule:    bar.SomeRule,
//             Outputs: []string{"${bar.SomeVariable}"},
//         })
//     }
//
// Note that the local name used to refer to the package in Ninja variable names
// is derived from pkgPath by extracting the last path component.  This differs
// from Go's import declaration, which derives the local name from the package
// clause in the imported package.  By convention these names are made to match,
// but this is not required.
func (p *packageContext) Import(pkgPath string) {
	checkCalledFromInit()
	importPkg, ok := packageContexts[pkgPath]
	if !ok {
		panic(fmt.Errorf("package %q has no context", pkgPath))
	}

	err := p.scope.AddImport(importPkg.shortName, importPkg.scope)
	if err != nil {
		panic(err)
	}
}

// ImportAs provides the same functionality as Import, but it allows the local
// name that will be used to refer to the package to be specified explicitly.
// It may only be called from a Go package's init() function.
func (p *packageContext) ImportAs(as, pkgPath string) {
	checkCalledFromInit()
	importPkg, ok := packageContexts[pkgPath]
	if !ok {
		panic(fmt.Errorf("package %q has no context", pkgPath))
	}

	err := validateNinjaName(as)
	if err != nil {
		panic(err)
	}

	err = p.scope.AddImport(as, importPkg.scope)
	if err != nil {
		panic(err)
	}
}

type staticVariable struct {
	pctx   *packageContext
	name_  string
	value_ string
}

// StaticVariable returns a Variable whose value does not depend on any
// configuration information.  It may only be called during a Go package's
// initialization - either from the init() function or as part of a package-
// scoped variable's initialization.
//
// This function is usually used to initialize a package-scoped Go variable that
// represents a Ninja variable that will be output.  The name argument should
// exactly match the Go variable name, and the value string may reference other
// Ninja variables that are visible within the calling Go package.
func (p *packageContext) StaticVariable(name, value string) Variable {
	checkCalledFromInit()
	err := validateNinjaName(name)
	if err != nil {
		panic(err)
	}

	v := &staticVariable{p, name, value}
	err = p.scope.AddVariable(v)
	if err != nil {
		panic(err)
	}

	return v
}

func (v *staticVariable) packageContext() *packageContext {
	return v.pctx
}

func (v *staticVariable) name() string {
	return v.name_
}

func (v *staticVariable) fullName(pkgNames map[*packageContext]string) string {
	return packageNamespacePrefix(pkgNames[v.pctx]) + v.name_
}

func (v *staticVariable) value(interface{}) (*ninjaString, error) {
	ninjaStr, err := parseNinjaString(v.pctx.scope, v.value_)
	if err != nil {
		err = fmt.Errorf("error parsing variable %s value: %s", v, err)
		panic(err)
	}
	return ninjaStr, nil
}

func (v *staticVariable) String() string {
	return v.pctx.pkgPath + "." + v.name_
}

type variableFunc struct {
	pctx   *packageContext
	name_  string
	value_ func(interface{}) (string, error)
}

// VariableFunc returns a Variable whose value is determined by a function that
// takes a config object as input and returns either the variable value or an
// error.  It may only be called during a Go package's initialization - either
// from the init() function or as part of a package-scoped variable's
// initialization.
//
// This function is usually used to initialize a package-scoped Go variable that
// represents a Ninja variable that will be output.  The name argument should
// exactly match the Go variable name, and the value string returned by f may
// reference other Ninja variables that are visible within the calling Go
// package.
func (p *packageContext) VariableFunc(name string,
	f func(config interface{}) (string, error)) Variable {

	checkCalledFromInit()

	err := validateNinjaName(name)
	if err != nil {
		panic(err)
	}

	v := &variableFunc{p, name, f}
	err = p.scope.AddVariable(v)
	if err != nil {
		panic(err)
	}

	return v
}

// VariableConfigMethod returns a Variable whose value is determined by calling
// a method on the config object.  The method must take no arguments and return
// a single string that will be the variable's value.  It may only be called
// during a Go package's initialization - either from the init() function or as
// part of a package-scoped variable's initialization.
//
// This function is usually used to initialize a package-scoped Go variable that
// represents a Ninja variable that will be output.  The name argument should
// exactly match the Go variable name, and the value string returned by method
// may reference other Ninja variables that are visible within the calling Go
// package.
func (p *packageContext) VariableConfigMethod(name string,
	method interface{}) Variable {

	checkCalledFromInit()

	err := validateNinjaName(name)
	if err != nil {
		panic(err)
	}

	methodValue := reflect.ValueOf(method)
	validateVariableMethod(name, methodValue)

	fun := func(config interface{}) (string, error) {
		result := methodValue.Call([]reflect.Value{reflect.ValueOf(config)})
		resultStr := result[0].Interface().(string)
		return resultStr, nil
	}

	v := &variableFunc{p, name, fun}
	err = p.scope.AddVariable(v)
	if err != nil {
		panic(err)
	}

	return v
}

func (v *variableFunc) packageContext() *packageContext {
	return v.pctx
}

func (v *variableFunc) name() string {
	return v.name_
}

func (v *variableFunc) fullName(pkgNames map[*packageContext]string) string {
	return packageNamespacePrefix(pkgNames[v.pctx]) + v.name_
}

func (v *variableFunc) value(config interface{}) (*ninjaString, error) {
	value, err := v.value_(config)
	if err != nil {
		return nil, err
	}

	ninjaStr, err := parseNinjaString(v.pctx.scope, value)
	if err != nil {
		err = fmt.Errorf("error parsing variable %s value: %s", v, err)
		panic(err)
	}

	return ninjaStr, nil
}

func (v *variableFunc) String() string {
	return v.pctx.pkgPath + "." + v.name_
}

func validateVariableMethod(name string, methodValue reflect.Value) {
	methodType := methodValue.Type()
	if methodType.Kind() != reflect.Func {
		panic(fmt.Errorf("method given for variable %s is not a function",
			name))
	}
	if n := methodType.NumIn(); n != 1 {
		panic(fmt.Errorf("method for variable %s has %d inputs (should be 1)",
			name, n))
	}
	if n := methodType.NumOut(); n != 1 {
		panic(fmt.Errorf("method for variable %s has %d outputs (should be 1)",
			name, n))
	}
	if kind := methodType.Out(0).Kind(); kind != reflect.String {
		panic(fmt.Errorf("method for variable %s does not return a string",
			name))
	}
}

// An argVariable is a Variable that exists only when it is set by a build
// statement to pass a value to the rule being invoked.  It has no value, so it
// can never be used to create a Ninja assignment statement.  It is inserted
// into the rule's scope, which is used for name lookups within the rule and
// when assigning argument values as part of a build statement.
type argVariable struct {
	name_ string
}

func (v *argVariable) packageContext() *packageContext {
	panic("this should not be called")
}

func (v *argVariable) name() string {
	return v.name_
}

func (v *argVariable) fullName(pkgNames map[*packageContext]string) string {
	return v.name_
}

func (v *argVariable) value(config interface{}) (*ninjaString, error) {
	return nil, errVariableIsArg
}

func (v *argVariable) String() string {
	return "<arg>:" + v.name_
}

type staticPool struct {
	pctx   *packageContext
	name_  string
	params PoolParams
}

// StaticPool returns a Pool whose value does not depend on any configuration
// information.  It may only be called during a Go package's initialization -
// either from the init() function or as part of a package-scoped Go variable's
// initialization.
//
// This function is usually used to initialize a package-scoped Go variable that
// represents a Ninja pool that will be output.  The name argument should
// exactly match the Go variable name, and the params fields may reference other
// Ninja variables that are visible within the calling Go package.
func (p *packageContext) StaticPool(name string, params PoolParams) Pool {
	checkCalledFromInit()

	err := validateNinjaName(name)
	if err != nil {
		panic(err)
	}

	pool := &staticPool{p, name, params}
	err = p.scope.AddPool(pool)
	if err != nil {
		panic(err)
	}

	return pool
}

func (p *staticPool) packageContext() *packageContext {
	return p.pctx
}

func (p *staticPool) name() string {
	return p.name_
}

func (p *staticPool) fullName(pkgNames map[*packageContext]string) string {
	return packageNamespacePrefix(pkgNames[p.pctx]) + p.name_
}

func (p *staticPool) def(config interface{}) (*poolDef, error) {
	def, err := parsePoolParams(p.pctx.scope, &p.params)
	if err != nil {
		panic(fmt.Errorf("error parsing PoolParams for %s: %s", p, err))
	}
	return def, nil
}

func (p *staticPool) String() string {
	return p.pctx.pkgPath + "." + p.name_
}

type poolFunc struct {
	pctx       *packageContext
	name_      string
	paramsFunc func(interface{}) (PoolParams, error)
}

// PoolFunc returns a Pool whose value is determined by a function that takes a
// config object as input and returns either the pool parameters or an error. It
// may only be called during a Go package's initialization - either from the
// init() function or as part of a package-scoped variable's initialization.
//
// This function is usually used to initialize a package-scoped Go variable that
// represents a Ninja pool that will be output.  The name argument should
// exactly match the Go variable name, and the string fields of the PoolParams
// returned by f may reference other Ninja variables that are visible within the
// calling Go package.
func (p *packageContext) PoolFunc(name string, f func(interface{}) (PoolParams,
	error)) Pool {

	checkCalledFromInit()

	err := validateNinjaName(name)
	if err != nil {
		panic(err)
	}

	pool := &poolFunc{p, name, f}
	err = p.scope.AddPool(pool)
	if err != nil {
		panic(err)
	}

	return pool
}

func (p *poolFunc) packageContext() *packageContext {
	return p.pctx
}

func (p *poolFunc) name() string {
	return p.name_
}

func (p *poolFunc) fullName(pkgNames map[*packageContext]string) string {
	return packageNamespacePrefix(pkgNames[p.pctx]) + p.name_
}

func (p *poolFunc) def(config interface{}) (*poolDef, error) {
	params, err := p.paramsFunc(config)
	if err != nil {
		return nil, err
	}
	def, err := parsePoolParams(p.pctx.scope, &params)
	if err != nil {
		panic(fmt.Errorf("error parsing PoolParams for %s: %s", p, err))
	}
	return def, nil
}

func (p *poolFunc) String() string {
	return p.pctx.pkgPath + "." + p.name_
}

type builtinPool struct {
	name_ string
}

func (p *builtinPool) packageContext() *packageContext {
	return nil
}

func (p *builtinPool) name() string {
	return p.name_
}

func (p *builtinPool) fullName(pkgNames map[*packageContext]string) string {
	return p.name_
}

func (p *builtinPool) def(config interface{}) (*poolDef, error) {
	return nil, errPoolIsBuiltin
}

func (p *builtinPool) String() string {
	return "<builtin>:" + p.name_
}

type staticRule struct {
	pctx       *packageContext
	name_      string
	params     RuleParams
	argNames   map[string]bool
	scope_     *basicScope
	sync.Mutex // protects scope_ during lazy creation
}

// StaticRule returns a Rule whose value does not depend on any configuration
// information.  It may only be called during a Go package's initialization -
// either from the init() function or as part of a package-scoped Go variable's
// initialization.
//
// This function is usually used to initialize a package-scoped Go variable that
// represents a Ninja rule that will be output.  The name argument should
// exactly match the Go variable name, and the params fields may reference other
// Ninja variables that are visible within the calling Go package.
//
// The argNames arguments list Ninja variables that may be overridden by Ninja
// build statements that invoke the rule.  These arguments may be referenced in
// any of the string fields of params.  Arguments can shadow package-scoped
// variables defined within the caller's Go package, but they may not shadow
// those defined in another package.  Shadowing a package-scoped variable
// results in the package-scoped variable's value being used for build
// statements that do not override the argument.  For argument names that do not
// shadow package-scoped variables the default value is an empty string.
func (p *packageContext) StaticRule(name string, params RuleParams,
	argNames ...string) Rule {

	checkCalledFromInit()

	err := validateNinjaName(name)
	if err != nil {
		panic(err)
	}

	err = validateArgNames(argNames)
	if err != nil {
		panic(fmt.Errorf("invalid argument name: %s", err))
	}

	argNamesSet := make(map[string]bool)
	for _, argName := range argNames {
		argNamesSet[argName] = true
	}

	ruleScope := (*basicScope)(nil) // This will get created lazily

	r := &staticRule{
		pctx:     p,
		name_:    name,
		params:   params,
		argNames: argNamesSet,
		scope_:   ruleScope,
	}
	err = p.scope.AddRule(r)
	if err != nil {
		panic(err)
	}

	return r
}

func (r *staticRule) packageContext() *packageContext {
	return r.pctx
}

func (r *staticRule) name() string {
	return r.name_
}

func (r *staticRule) fullName(pkgNames map[*packageContext]string) string {
	return packageNamespacePrefix(pkgNames[r.pctx]) + r.name_
}

func (r *staticRule) def(interface{}) (*ruleDef, error) {
	def, err := parseRuleParams(r.scope(), &r.params)
	if err != nil {
		panic(fmt.Errorf("error parsing RuleParams for %s: %s", r, err))
	}
	return def, nil
}

func (r *staticRule) scope() *basicScope {
	// We lazily create the scope so that all the package-scoped variables get
	// declared before the args are created.  Otherwise we could incorrectly
	// shadow a package-scoped variable with an arg variable.
	r.Lock()
	defer r.Unlock()

	if r.scope_ == nil {
		r.scope_ = makeRuleScope(r.pctx.scope, r.argNames)
	}
	return r.scope_
}

func (r *staticRule) isArg(argName string) bool {
	return r.argNames[argName]
}

func (r *staticRule) String() string {
	return r.pctx.pkgPath + "." + r.name_
}

type ruleFunc struct {
	pctx       *packageContext
	name_      string
	paramsFunc func(interface{}) (RuleParams, error)
	argNames   map[string]bool
	scope_     *basicScope
	sync.Mutex // protects scope_ during lazy creation
}

// RuleFunc returns a Rule whose value is determined by a function that takes a
// config object as input and returns either the rule parameters or an error. It
// may only be called during a Go package's initialization - either from the
// init() function or as part of a package-scoped variable's initialization.
//
// This function is usually used to initialize a package-scoped Go variable that
// represents a Ninja rule that will be output.  The name argument should
// exactly match the Go variable name, and the string fields of the RuleParams
// returned by f may reference other Ninja variables that are visible within the
// calling Go package.
//
// The argNames arguments list Ninja variables that may be overridden by Ninja
// build statements that invoke the rule.  These arguments may be referenced in
// any of the string fields of the RuleParams returned by f.  Arguments can
// shadow package-scoped variables defined within the caller's Go package, but
// they may not shadow those defined in another package.  Shadowing a package-
// scoped variable results in the package-scoped variable's value being used for
// build statements that do not override the argument.  For argument names that
// do not shadow package-scoped variables the default value is an empty string.
func (p *packageContext) RuleFunc(name string, f func(interface{}) (RuleParams,
	error), argNames ...string) Rule {

	checkCalledFromInit()

	err := validateNinjaName(name)
	if err != nil {
		panic(err)
	}

	err = validateArgNames(argNames)
	if err != nil {
		panic(fmt.Errorf("invalid argument name: %s", err))
	}

	argNamesSet := make(map[string]bool)
	for _, argName := range argNames {
		argNamesSet[argName] = true
	}

	ruleScope := (*basicScope)(nil) // This will get created lazily

	rule := &ruleFunc{
		pctx:       p,
		name_:      name,
		paramsFunc: f,
		argNames:   argNamesSet,
		scope_:     ruleScope,
	}
	err = p.scope.AddRule(rule)
	if err != nil {
		panic(err)
	}

	return rule
}

func (r *ruleFunc) packageContext() *packageContext {
	return r.pctx
}

func (r *ruleFunc) name() string {
	return r.name_
}

func (r *ruleFunc) fullName(pkgNames map[*packageContext]string) string {
	return packageNamespacePrefix(pkgNames[r.pctx]) + r.name_
}

func (r *ruleFunc) def(config interface{}) (*ruleDef, error) {
	params, err := r.paramsFunc(config)
	if err != nil {
		return nil, err
	}
	def, err := parseRuleParams(r.scope(), &params)
	if err != nil {
		panic(fmt.Errorf("error parsing RuleParams for %s: %s", r, err))
	}
	return def, nil
}

func (r *ruleFunc) scope() *basicScope {
	// We lazily create the scope so that all the global variables get declared
	// before the args are created.  Otherwise we could incorrectly shadow a
	// global variable with an arg variable.
	r.Lock()
	defer r.Unlock()

	if r.scope_ == nil {
		r.scope_ = makeRuleScope(r.pctx.scope, r.argNames)
	}
	return r.scope_
}

func (r *ruleFunc) isArg(argName string) bool {
	return r.argNames[argName]
}

func (r *ruleFunc) String() string {
	return r.pctx.pkgPath + "." + r.name_
}

type builtinRule struct {
	name_      string
	scope_     *basicScope
	sync.Mutex // protects scope_ during lazy creation
}

func (r *builtinRule) packageContext() *packageContext {
	return nil
}

func (r *builtinRule) name() string {
	return r.name_
}

func (r *builtinRule) fullName(pkgNames map[*packageContext]string) string {
	return r.name_
}

func (r *builtinRule) def(config interface{}) (*ruleDef, error) {
	return nil, errRuleIsBuiltin
}

func (r *builtinRule) scope() *basicScope {
	r.Lock()
	defer r.Unlock()

	if r.scope_ == nil {
		r.scope_ = makeRuleScope(nil, nil)
	}
	return r.scope_
}

func (r *builtinRule) isArg(argName string) bool {
	return false
}

func (r *builtinRule) String() string {
	return "<builtin>:" + r.name_
}

func (p *packageContext) AddNinjaFileDeps(deps ...string) {
	p.ninjaFileDeps = append(p.ninjaFileDeps, deps...)
}
