// 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"
	"regexp"
	"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)(nil)

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 = NewBuiltinRule("phony")

var Console Pool = NewBuiltinPool("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·") ||
			funcName == "init.ializers" || strings.HasPrefix(funcName, "init.") {
			return
		}
	}
}

// A regex to find a package path within a function name. It finds the shortest string that is
// followed by '.' and doesn't have any '/'s left.
var pkgPathRe = regexp.MustCompile(`^(.*?)\.([^/]+)$`)

// 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
	}
	frames := runtime.CallersFrames(pc[:])
	frame, _ := frames.Next()
	f := frame.Function
	s := pkgPathRe.FindStringSubmatch(f)
	if len(s) < 3 {
		panic(fmt.Errorf("failed to extract package path and function name from %q", f))
	}

	return s[1], s[2], true
}

// 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
	fullName_ 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{
		pctx:   p,
		name_:  name,
		value_: 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 {
	if v.fullName_ != "" {
		return v.fullName_
	}
	return packageNamespacePrefix(pkgNames[v.pctx]) + v.name_
}

func (v *staticVariable) memoizeFullName(pkgNames map[*packageContext]string) {
	v.fullName_ = v.fullName(pkgNames)
}

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)
	fullName_ string
}

// 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{
		pctx:   p,
		name_:  name,
		value_: 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{
		pctx:   p,
		name_:  name,
		value_: 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 {
	if v.fullName_ != "" {
		return v.fullName_
	}
	return packageNamespacePrefix(pkgNames[v.pctx]) + v.name_
}

func (v *variableFunc) memoizeFullName(pkgNames map[*packageContext]string) {
	v.fullName_ = v.fullName(pkgNames)
}

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) memoizeFullName(pkgNames map[*packageContext]string) {
	// Nothing to do, full name is known at initialization.
}

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
	fullName_ string
}

// 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{
		pctx:   p,
		name_:  name,
		params: 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 {
	if p.fullName_ != "" {
		return p.fullName_
	}
	return packageNamespacePrefix(pkgNames[p.pctx]) + p.name_
}

func (p *staticPool) memoizeFullName(pkgNames map[*packageContext]string) {
	p.fullName_ = p.fullName(pkgNames)
}

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)
	fullName_  string
}

// 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{
		pctx:       p,
		name_:      name,
		paramsFunc: 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 {
	if p.fullName_ != "" {
		return p.fullName_
	}
	return packageNamespacePrefix(pkgNames[p.pctx]) + p.name_
}

func (p *poolFunc) memoizeFullName(pkgNames map[*packageContext]string) {
	p.fullName_ = p.fullName(pkgNames)
}

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) memoizeFullName(pkgNames map[*packageContext]string) {
	// Nothing to do, full name is known at initialization.
}

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

// NewBuiltinPool returns a Pool object that refers to a pool name created outside of Blueprint
func NewBuiltinPool(name string) Pool {
	return &builtinPool{
		name_: name,
	}
}

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

type staticRule struct {
	pctx       *packageContext
	name_      string
	params     RuleParams
	argNames   map[string]bool
	scope_     *basicScope
	fullName_  string
	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 {
	if r.fullName_ != "" {
		return r.fullName_
	}
	return packageNamespacePrefix(pkgNames[r.pctx]) + r.name_
}

func (r *staticRule) memoizeFullName(pkgNames map[*packageContext]string) {
	r.fullName_ = r.fullName(pkgNames)
}

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
	fullName_  string
	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 {
	if r.fullName_ != "" {
		return r.fullName_
	}
	return packageNamespacePrefix(pkgNames[r.pctx]) + r.name_
}

func (r *ruleFunc) memoizeFullName(pkgNames map[*packageContext]string) {
	r.fullName_ = r.fullName(pkgNames)
}

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) memoizeFullName(pkgNames map[*packageContext]string) {
	// Nothing to do, full name is known at initialization.
}

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_
}

// NewBuiltinRule returns a Rule object that refers to a rule that was created outside of Blueprint
func NewBuiltinRule(name string) Rule {
	return &builtinRule{
		name_: name,
	}
}

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