// 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(ctx VariableFuncContext, 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{
		fullName_: s.namePrefix + name,
		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{
		fullName_: s.namePrefix + name,
		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 {
	fullName_ 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.fullName_
}

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

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

type localRule struct {
	fullName_ 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.fullName_
}

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

type nameTracker struct {
	variables map[Variable]string
	rules     map[Rule]string
	pools     map[Pool]string

	pkgNames map[*packageContext]string
}

func (m *nameTracker) Variable(v Variable) string {
	if m == nil {
		return v.fullName(nil)
	}
	if name, ok := m.variables[v]; ok {
		return name
	}
	return v.fullName(m.pkgNames)
}

func (m *nameTracker) Rule(r Rule) string {
	if m == nil {
		return r.fullName(nil)
	}
	if name, ok := m.rules[r]; ok {
		return name
	}
	return r.fullName(m.pkgNames)
}

func (m *nameTracker) Pool(p Pool) string {
	if m == nil {
		return p.fullName(nil)
	}
	if name, ok := m.pools[p]; ok {
		return name
	}
	return p.fullName(m.pkgNames)
}
