// 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 (
	"fmt"
	"strings"
	"unicode"
	"unicode/utf8"
)

// A Variable represents a global Ninja variable definition that will be written
// to the output .ninja file.  A variable may contain references to other global
// Ninja variables, but circular variable references are not allowed.
type Variable interface {
	packageContext() *packageContext
	name() string                                        // "foo"
	fullName(pkgNames map[*packageContext]string) string // "pkg.foo" or "path.to.pkg.foo"
	value(config interface{}) (*ninjaString, error)
	String() string
}

// A Pool represents a Ninja pool that will be written to the output .ninja
// file.
type Pool interface {
	packageContext() *packageContext
	name() string                                        // "foo"
	fullName(pkgNames map[*packageContext]string) string // "pkg.foo" or "path.to.pkg.foo"
	def(config interface{}) (*poolDef, error)
	String() string
}

// A Rule represents a Ninja build rule that will be written to the output
// .ninja file.
type Rule interface {
	packageContext() *packageContext
	name() string                                        // "foo"
	fullName(pkgNames map[*packageContext]string) string // "pkg.foo" or "path.to.pkg.foo"
	def(config interface{}) (*ruleDef, error)
	scope() *basicScope
	isArg(argName string) bool
	String() string
}

type basicScope struct {
	parent    *basicScope
	variables map[string]Variable
	pools     map[string]Pool
	rules     map[string]Rule
	imports   map[string]*basicScope
}

func newScope(parent *basicScope) *basicScope {
	return &basicScope{
		parent:    parent,
		variables: make(map[string]Variable),
		pools:     make(map[string]Pool),
		rules:     make(map[string]Rule),
		imports:   make(map[string]*basicScope),
	}
}

func makeRuleScope(parent *basicScope, argNames map[string]bool) *basicScope {
	scope := newScope(parent)
	for argName := range argNames {
		_, err := scope.LookupVariable(argName)
		if err != nil {
			arg := &argVariable{argName}
			err = scope.AddVariable(arg)
			if err != nil {
				// This should not happen.  We should have already checked that
				// the name is valid and that the scope doesn't have a variable
				// with this name.
				panic(err)
			}
		}
	}

	// We treat built-in variables like arguments for the purpose of this scope.
	for _, builtin := range builtinRuleArgs {
		arg := &argVariable{builtin}
		err := scope.AddVariable(arg)
		if err != nil {
			panic(err)
		}
	}

	return scope
}

func (s *basicScope) LookupVariable(name string) (Variable, error) {
	dotIndex := strings.IndexRune(name, '.')
	if dotIndex >= 0 {
		// The variable name looks like "pkg.var"
		if dotIndex+1 == len(name) {
			return nil, fmt.Errorf("variable name %q ends with a '.'", name)
		}
		if strings.ContainsRune(name[dotIndex+1:], '.') {
			return nil, fmt.Errorf("variable name %q contains multiple '.' "+
				"characters", name)
		}

		pkgName := name[:dotIndex]
		varName := name[dotIndex+1:]

		first, _ := utf8.DecodeRuneInString(varName)
		if !unicode.IsUpper(first) {
			return nil, fmt.Errorf("cannot refer to unexported name %q", name)
		}

		importedScope, err := s.lookupImportedScope(pkgName)
		if err != nil {
			return nil, err
		}

		v, ok := importedScope.variables[varName]
		if !ok {
			return nil, fmt.Errorf("package %q does not contain variable %q",
				pkgName, varName)
		}

		return v, nil
	} else {
		// The variable name has no package part; just "var"
		for ; s != nil; s = s.parent {
			v, ok := s.variables[name]
			if ok {
				return v, nil
			}
		}
		return nil, fmt.Errorf("undefined variable %q", name)
	}
}

func (s *basicScope) IsRuleVisible(rule Rule) bool {
	_, isBuiltin := rule.(*builtinRule)
	if isBuiltin {
		return true
	}

	name := rule.name()

	for s != nil {
		if s.rules[name] == rule {
			return true
		}

		for _, import_ := range s.imports {
			if import_.rules[name] == rule {
				return true
			}
		}

		s = s.parent
	}

	return false
}

func (s *basicScope) IsPoolVisible(pool Pool) bool {
	_, isBuiltin := pool.(*builtinPool)
	if isBuiltin {
		return true
	}

	name := pool.name()

	for s != nil {
		if s.pools[name] == pool {
			return true
		}

		for _, import_ := range s.imports {
			if import_.pools[name] == pool {
				return true
			}
		}

		s = s.parent
	}

	return false
}

func (s *basicScope) lookupImportedScope(pkgName string) (*basicScope, error) {
	for ; s != nil; s = s.parent {
		importedScope, ok := s.imports[pkgName]
		if ok {
			return importedScope, nil
		}
	}
	return nil, fmt.Errorf("unknown imported package %q (missing call to "+
		"blueprint.Import()?)", pkgName)
}

func (s *basicScope) AddImport(name string, importedScope *basicScope) error {
	_, present := s.imports[name]
	if present {
		return fmt.Errorf("import %q is already defined in this scope", name)
	}
	s.imports[name] = importedScope
	return nil
}

func (s *basicScope) AddVariable(v Variable) error {
	name := v.name()
	_, present := s.variables[name]
	if present {
		return fmt.Errorf("variable %q is already defined in this scope", name)
	}
	s.variables[name] = v
	return nil
}

func (s *basicScope) AddPool(p Pool) error {
	name := p.name()
	_, present := s.pools[name]
	if present {
		return fmt.Errorf("pool %q is already defined in this scope", name)
	}
	s.pools[name] = p
	return nil
}

func (s *basicScope) AddRule(r Rule) error {
	name := r.name()
	_, present := s.rules[name]
	if present {
		return fmt.Errorf("rule %q is already defined in this scope", name)
	}
	s.rules[name] = r
	return nil
}

type localScope struct {
	namePrefix string
	scope      *basicScope
}

func newLocalScope(parent *basicScope, namePrefix string) *localScope {
	return &localScope{
		namePrefix: namePrefix,
		scope:      newScope(parent),
	}
}

// ReparentTo sets the localScope's parent scope to the scope of the given
// package context.  This allows a ModuleContext and SingletonContext to call
// a function defined in a different Go package and have that function retain
// access to all of the package-scoped variables of its own package.
func (s *localScope) ReparentTo(pctx PackageContext) {
	s.scope.parent = pctx.getScope()
}

func (s *localScope) LookupVariable(name string) (Variable, error) {
	return s.scope.LookupVariable(name)
}

func (s *localScope) IsRuleVisible(rule Rule) bool {
	return s.scope.IsRuleVisible(rule)
}

func (s *localScope) IsPoolVisible(pool Pool) bool {
	return s.scope.IsPoolVisible(pool)
}

func (s *localScope) AddLocalVariable(name, value string) (*localVariable,
	error) {

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

	if strings.ContainsRune(name, '.') {
		return nil, fmt.Errorf("local variable name %q contains '.'", name)
	}

	ninjaValue, err := parseNinjaString(s.scope, value)
	if err != nil {
		return nil, err
	}

	v := &localVariable{
		namePrefix: s.namePrefix,
		name_:      name,
		value_:     ninjaValue,
	}

	err = s.scope.AddVariable(v)
	if err != nil {
		return nil, err
	}

	return v, nil
}

func (s *localScope) AddLocalRule(name string, params *RuleParams,
	argNames ...string) (*localRule, error) {

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

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

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

	ruleScope := makeRuleScope(s.scope, argNamesSet)

	def, err := parseRuleParams(ruleScope, params)
	if err != nil {
		return nil, err
	}

	r := &localRule{
		namePrefix: s.namePrefix,
		name_:      name,
		def_:       def,
		argNames:   argNamesSet,
		scope_:     ruleScope,
	}

	err = s.scope.AddRule(r)
	if err != nil {
		return nil, err
	}

	return r, nil
}

type localVariable struct {
	namePrefix string
	name_      string
	value_     *ninjaString
}

func (l *localVariable) packageContext() *packageContext {
	return nil
}

func (l *localVariable) name() string {
	return l.name_
}

func (l *localVariable) fullName(pkgNames map[*packageContext]string) string {
	return l.namePrefix + l.name_
}

func (l *localVariable) value(interface{}) (*ninjaString, error) {
	return l.value_, nil
}

func (l *localVariable) String() string {
	return "<local var>:" + l.namePrefix + l.name_
}

type localRule struct {
	namePrefix string
	name_      string
	def_       *ruleDef
	argNames   map[string]bool
	scope_     *basicScope
}

func (l *localRule) packageContext() *packageContext {
	return nil
}

func (l *localRule) name() string {
	return l.name_
}

func (l *localRule) fullName(pkgNames map[*packageContext]string) string {
	return l.namePrefix + l.name_
}

func (l *localRule) def(interface{}) (*ruleDef, error) {
	return l.def_, nil
}

func (r *localRule) scope() *basicScope {
	return r.scope_
}

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

func (r *localRule) String() string {
	return "<local rule>:" + r.namePrefix + r.name_
}
