// Copyright 2015 The Vanadium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package compile

import (
	"fmt"
	"path"
	"regexp"
	"strings"
	"unicode"

	"v.io/v23/vdl"
	"v.io/v23/vdlroot/vdltool"
	"v.io/x/ref/lib/vdl/opconst"
	"v.io/x/ref/lib/vdl/parse"
	"v.io/x/ref/lib/vdl/vdlutil"
)

// Env is the environment for compilation.  It contains all errors that were
// collected during the execution - you can pass Errors to the parse phase to
// collect all errors together.  As packages are compiled it also collects the
// output; after a sequence of dependent packages is compiled, all compiled
// output will be collected.
//
// Always create a new Env via NewEnv; the zero Env is invalid.
type Env struct {
	Errors   *vdlutil.Errors
	pkgs     map[string]*Package
	typeMap  map[*vdl.Type]*TypeDef
	constMap map[*vdl.Value]*ConstDef

	disallowPathQualifiers bool // Disallow syntax like "a/b/c".Type
}

// NewEnv creates a new Env, allowing up to maxErrors errors before we stop.
func NewEnv(maxErrors int) *Env {
	return NewEnvWithErrors(vdlutil.NewErrors(maxErrors))
}

// NewEnvWithErrors creates a new Env, using the given errs to collect errors.
func NewEnvWithErrors(errs *vdlutil.Errors) *Env {
	env := &Env{
		Errors:   errs,
		pkgs:     make(map[string]*Package),
		typeMap:  make(map[*vdl.Type]*TypeDef),
		constMap: make(map[*vdl.Value]*ConstDef),
	}
	// The env always starts out with the built-in package.
	env.pkgs[BuiltInPackage.Name] = BuiltInPackage
	for _, def := range BuiltInFile.TypeDefs {
		env.typeMap[def.Type] = def
	}
	for _, def := range BuiltInFile.ConstDefs {
		env.constMap[def.Value] = def
	}
	return env
}

// FindTypeDef returns the type definition corresponding to t, or nil if t isn't
// a defined type.  All built-in and user-defined named types are considered
// defined; e.g. unnamed lists don't have a corresponding type def.
func (e *Env) FindTypeDef(t *vdl.Type) *TypeDef { return e.typeMap[t] }

// FindConstDef returns the const definition corresponding to v, or nil if v
// isn't a defined const.  All user-defined named consts are considered defined;
// e.g. method tags don't have a corresponding const def.
func (e *Env) FindConstDef(v *vdl.Value) *ConstDef { return e.constMap[v] }

// ResolvePackage resolves a package path to its previous compiled results.
func (e *Env) ResolvePackage(path string) *Package {
	return e.pkgs[path]
}

// ResolvePackageGenPath resolves a package gen path to its previous compiled
// results.
func (e *Env) ResolvePackageGenPath(genPath string) *Package {
	for _, pkg := range e.pkgs {
		if pkg.GenPath == genPath {
			return pkg
		}
	}
	return nil
}

// Resolves a name against the current package and imported package namespace.
func (e *Env) resolve(name string, file *File) (val interface{}, matched string) {
	// First handle package-path qualified identifiers, which look like this:
	//   "a/b/c".Ident   (qualified with package path "a/b/c")
	// These must be handled first, since the package-path may include dots.
	if strings.HasPrefix(name, `"`) {
		if parts := strings.SplitN(name[1:], `".`, 2); len(parts) == 2 {
			path, remain := parts[0], parts[1]
			if e.disallowPathQualifiers {
				// TODO(toddw): Add real position.
				e.Errorf(file, parse.Pos{}, "package path qualified identifier %s not allowed", name)
			}
			if file.ValidateImportPackagePath(path) {
				if pkg := e.ResolvePackage(path); pkg != nil {
					if dotParts := strings.Split(remain, "."); len(dotParts) > 0 {
						if val := pkg.resolve(dotParts[0], false); val != nil {
							return val, `"` + path + `".` + dotParts[0]
						}
					}
				}
			}
		}
	}
	// Now handle built-in and package-local identifiers.  Examples:
	//   string
	//   TypeName
	//   EnumType.Label
	//   ConstName
	//   StructConst.Field
	//   InterfaceName
	nameParts := strings.Split(name, ".")
	if len(nameParts) == 0 {
		return nil, ""
	}
	if builtin := BuiltInPackage.resolve(nameParts[0], false); builtin != nil {
		return builtin, nameParts[0]
	}
	if local := file.Package.resolve(nameParts[0], true); local != nil {
		return local, nameParts[0]
	}
	// Now handle package qualified identifiers, which look like this:
	//   pkg.Ident   (qualified with local package identifier pkg)
	if len(nameParts) > 1 {
		if path := file.LookupImportPath(nameParts[0]); path != "" {
			if pkg := e.ResolvePackage(path); pkg != nil {
				if val := pkg.resolve(nameParts[1], false); val != nil {
					return val, nameParts[0] + "." + nameParts[1]
				}
			}
		}
	}
	// No match found.
	return nil, ""
}

// ResolveType resolves a name to a type definition.
// Returns the type def and the portion of name that was matched.
func (e *Env) ResolveType(name string, file *File) (td *TypeDef, matched string) {
	v, matched := e.resolve(name, file)
	td, _ = v.(*TypeDef)
	if td == nil {
		return nil, ""
	}
	return td, matched
}

// ResolveConst resolves a name to a const definition.
// Returns the const def and the portion of name that was matched.
func (e *Env) ResolveConst(name string, file *File) (cd *ConstDef, matched string) {
	v, matched := e.resolve(name, file)
	cd, _ = v.(*ConstDef)
	if cd == nil {
		return nil, ""
	}
	return cd, matched
}

// ResolveInterface resolves a name to an interface definition.
// Returns the interface and the portion of name that was matched.
func (e *Env) ResolveInterface(name string, file *File) (i *Interface, matched string) {
	v, matched := e.resolve(name, file)
	i, _ = v.(*Interface)
	if i == nil {
		return nil, ""
	}
	return i, matched
}

// evalSelectorOnValue evaluates the selector on v.
func (e *Env) evalSelectorOnValue(v *vdl.Value, selector string) (opconst.Const, error) {
	for _, fieldName := range strings.Split(selector, ".") {
		if v.Kind() != vdl.Struct {
			return opconst.Const{}, fmt.Errorf("invalid selector on const of kind: %v", v.Type().Kind())
		}
		next := v.StructFieldByName(fieldName)
		if next == nil {
			return opconst.Const{}, fmt.Errorf("invalid field name on struct %s: %s", v, fieldName)
		}
		v = next
	}
	return opconst.FromValue(v), nil
}

// evalSelectorOnType evaluates the selector on t.
func (e *Env) evalSelectorOnType(t *vdl.Type, selector string) (opconst.Const, error) {
	if t.Kind() != vdl.Enum {
		return opconst.Const{}, fmt.Errorf("invalid selector on type of kind: %v", t.Kind())
	}
	index := t.EnumIndex(selector)
	if index < 0 {
		return opconst.Const{}, fmt.Errorf("invalid label on enum %s: %s", t.Name(), selector)
	}
	return opconst.FromValue(vdl.EnumValue(t, index)), nil
}

// EvalConst resolves and evaluates a name to a const.
func (e *Env) EvalConst(name string, file *File) (opconst.Const, error) {
	if cd, matched := e.ResolveConst(name, file); cd != nil {
		if matched == name {
			return opconst.FromValue(cd.Value), nil
		}
		remainder := name[len(matched)+1:]
		c, err := e.evalSelectorOnValue(cd.Value, remainder)
		if err != nil {
			return opconst.Const{}, err
		}
		return c, nil
	}
	if td, matched := e.ResolveType(name, file); td != nil {
		if matched == name {
			return opconst.Const{}, fmt.Errorf("%s is a type", name)
		}
		remainder := name[len(matched)+1:]
		c, err := e.evalSelectorOnType(td.Type, remainder)
		if err != nil {
			return opconst.Const{}, err
		}
		return c, nil
	}
	return opconst.Const{}, fmt.Errorf("%s undefined", name)
}

// Errorf is a helper for error reporting, to consistently contain the file and
// position of the error when possible.
func (e *Env) Errorf(file *File, pos parse.Pos, format string, v ...interface{}) {
	e.Errors.Error(fpStringf(file, pos, format, v...))
}

func (e *Env) prefixErrorf(file *File, pos parse.Pos, err error, format string, v ...interface{}) {
	e.Errors.Error(fpStringf(file, pos, format, v...) + " (" + err.Error() + ")")
}

func fpString(file *File, pos parse.Pos) string {
	return path.Join(file.Package.Path, file.BaseName) + ":" + pos.String()
}

func fpStringf(file *File, pos parse.Pos, format string, v ...interface{}) string {
	return fmt.Sprintf(fpString(file, pos)+" "+format, v...)
}

// DisallowPathQualifiers disables syntax like "a/b/c".Type.
func (e *Env) DisallowPathQualifiers() *Env {
	e.disallowPathQualifiers = true
	return e
}

// Representation of the components of an vdl file.  These data types represent
// the results of the compilation, used by generators for different languages.

// Package represents a vdl package, containing a list of files.
type Package struct {
	// Name is the name of the package, specified in the vdl files.
	// E.g. "bar"
	Name string
	// Path is the package path; the path used in VDL import clauses.
	// E.g. "foo/bar".
	Path string
	// GenPath is the package path to use for code generation.  It is typically
	// the same as Path, except for vdlroot standard packages.
	// E.g. "v.io/v23/vdlroot/time"
	GenPath string
	// Files holds the files contained in the package.
	Files []*File
	// FileDoc holds the top-level file documentation, which must be the same for
	// every file in the package.  This is typically used to hold boilerplate that
	// must appear in every generated file, e.g. a copyright notice.
	FileDoc string
	// Config holds the configuration for this package, specifying options used
	// during compilation and code generation.
	Config vdltool.Config

	// We hold some internal maps to make local name resolution cheap and easy.
	typeMap  map[string]*TypeDef
	constMap map[string]*ConstDef
	ifaceMap map[string]*Interface

	// We also hold some internal slices, to remember the dependency ordering.
	typeDefs  []*TypeDef
	constDefs []*ConstDef
	errorDefs []*ErrorDef
	ifaceDefs []*Interface

	// lowercaseIdents maps from lowercased identifier to a detail string; it's
	// used to detect and report identifier conflicts.
	lowercaseIdents map[string]string
}

func newPackage(name, pkgPath, genPath string, config vdltool.Config) *Package {
	return &Package{
		Name:            name,
		Path:            pkgPath,
		GenPath:         genPath,
		Config:          config,
		typeMap:         make(map[string]*TypeDef),
		constMap:        make(map[string]*ConstDef),
		ifaceMap:        make(map[string]*Interface),
		lowercaseIdents: make(map[string]string),
	}
}

// QualifiedName returns the fully-qualified name of an identifier, by
// prepending the identifier with the package path.
func (p *Package) QualifiedName(id string) string {
	if p.Path == "" {
		return id
	}
	return p.Path + "." + id
}

// ResolveType resolves the type name to its definition.
func (p *Package) ResolveType(name string) *TypeDef { return p.typeMap[name] }

// ResolveConst resolves the const name to its definition.
func (p *Package) ResolveConst(name string) *ConstDef { return p.constMap[name] }

// ResolveInterface resolves the interface name to its definition.
func (p *Package) ResolveInterface(name string) *Interface { return p.ifaceMap[name] }

// resolve resolves a name against the package.
// Checks for duplicate definitions should be performed before this is called.
func (p *Package) resolve(name string, isLocal bool) interface{} {
	if t := p.ResolveType(name); t != nil && (t.Exported || isLocal) {
		return t
	}
	if c := p.ResolveConst(name); c != nil && (c.Exported || isLocal) {
		return c
	}
	if i := p.ResolveInterface(name); i != nil && (i.Exported || isLocal) {
		return i
	}
	return nil
}

// Doc returns the package documentation, which should only exist in a single
// file in the package.
func (p *Package) Doc() string {
	for _, file := range p.Files {
		if doc := file.PackageDef.Doc; doc != "" {
			return doc
		}
	}
	return ""
}

// TypeDefs returns all types defined in this package, in dependency order.  If
// type B refers to type A, B depends on A, and A will appear before B.  Types
// may have cyclic dependencies; the ordering of cyclicly dependent types is
// arbitrary.
func (p *Package) TypeDefs() []*TypeDef { return p.typeDefs }

// ConstDefs returns all consts defined in this package, in dependency order.
// If const B refers to const A, B depends on A, and A will appear before B.
// Consts cannot have cyclic dependencies.
func (p *Package) ConstDefs() (x []*ConstDef) { return p.constDefs }

// ErrorDefs returns all errors defined in this package.  Errors don't have
// dependencies.
func (p *Package) ErrorDefs() (x []*ErrorDef) { return p.errorDefs }

// Interfaces returns all interfaces defined in this package, in dependency
// order.  If interface B embeds interface A, B depends on A, and A will appear
// before B.  Interfaces cannot have cyclic dependencies.
func (p *Package) Interfaces() (x []*Interface) { return p.ifaceDefs }

// File represents a compiled vdl file.
type File struct {
	BaseName   string       // Base name of the vdl file, e.g. "foo.vdl"
	PackageDef NamePos      // Name, position and docs of the "package" clause
	TypeDefs   []*TypeDef   // Types defined in this file
	ConstDefs  []*ConstDef  // Consts defined in this file
	ErrorDefs  []*ErrorDef  // Errors defined in this file
	Interfaces []*Interface // Interfaces defined in this file
	Package    *Package     // Parent package

	TypeDeps    map[*vdl.Type]bool // Types the file depends on
	PackageDeps []*Package         // Packages the file depends on, sorted by path

	// Imports maps the user-supplied imports from local package name to package
	// path.  They may be different from PackageDeps since we evaluate all consts
	// to their final typed value.  E.g. let's say we have three vdl files:
	//
	//   a/a.vdl  type Foo int32; const A1 = Foo(1)
	//   b/b.vdl  import "a";     const B1 = a.Foo(1); const B2 = a.A1 + 1
	//   c/c.vdl  import "b";     const C1 = b.B1;     const C2 = b.B1 + 1
	//
	// The final type and value of the constants:
	//   A1 = a.Foo(1); B1 = a.Foo(1); C1 = a.Foo(1)
	//                  B2 = a.Foo(2); C2 = a.Foo(2)
	//
	// Note that C1 and C2 both have final type a.Foo, even though c.vdl doesn't
	// explicitly import "a", and the generated c.go shouldn't import "b" since
	// it's not actually used anymore.
	imports map[string]*importPath
}

type importPath struct {
	path string
	pos  parse.Pos
	used bool // was this import path ever used?
}

// LookupImportPath translates local into a package path name, based on the
// imports associated with the file.  Returns the empty string "" if local
// couldn't be found; every valid package path is non-empty.
func (f *File) LookupImportPath(local string) string {
	if imp, ok := f.imports[local]; ok {
		imp.used = true
		return imp.path
	}
	return ""
}

// ValidateImportPackagePath returns true iff path is listed in the file's
// imports, and marks the import as used.
func (f *File) ValidateImportPackagePath(path string) bool {
	for _, imp := range f.imports {
		if imp.path == path {
			imp.used = true
			return true
		}
	}
	return false
}

// identDetail formats a detail string for calls to DeclareIdent.
func identDetail(kind string, file *File, pos parse.Pos) string {
	return fmt.Sprintf("%s at %s:%s", kind, file.BaseName, pos)
}

// DeclareIdent declares ident with the given detail string.  Returns an error
// if ident conflicts with an existing identifier in this file or package, where
// the error includes the the previous declaration detail.
func (f *File) DeclareIdent(ident, detail string) error {
	// Identifiers must be distinct from the the import names used in this file,
	// but can differ by only their capitalization.  E.g.
	//   import "foo"
	//   type foo string // BAD, type "foo" collides with import "foo"
	//   type Foo string //  OK, type "Foo" distinct from import "foo"
	//   type FoO string //  OK, type "FoO" distinct from import "foo"
	if i, ok := f.imports[ident]; ok {
		return fmt.Errorf("previous import at %s", i.pos)
	}
	// Identifiers must be distinct from all other identifiers within this
	// package, and cannot differ by only their capitalization.  E.g.
	//   type foo string
	//   const foo = "a" // BAD, const "foo" collides with type "foo"
	//   const Foo = "A" // BAD, const "Foo" collides with type "foo"
	//   const FoO = "A" // BAD, const "FoO" collides with type "foo"
	lower := strings.ToLower(ident)
	if prevDetail := f.Package.lowercaseIdents[lower]; prevDetail != "" {
		return fmt.Errorf("previous %s", prevDetail)
	}
	f.Package.lowercaseIdents[lower] = detail
	return nil
}

// Interface represents a set of embedded interfaces and methods.
type Interface struct {
	NamePos               // interface name, pos and doc
	Exported bool         // is this interface exported?
	Embeds   []*Interface // list of embedded interfaces
	Methods  []*Method    // list of methods
	File     *File        // parent file
}

// Method represents a method in an interface.
type Method struct {
	NamePos                // method name, pos and doc
	InArgs    []*Field     // list of positional in-args
	OutArgs   []*Field     // list of positional out-args
	InStream  *vdl.Type    // in-stream type, may be nil
	OutStream *vdl.Type    // out-stream type, may be nil
	Tags      []*vdl.Value // list of method tags
	Interface *Interface   // parent interface
}

// Field represents method arguments and error params.
type Field struct {
	NamePos           // arg name, pos and doc
	Type    *vdl.Type // arg type, never nil
}

// NamePos represents a name, its associated position and documentation.
type NamePos parse.NamePos

func (x *Field) String() string   { return fmt.Sprintf("%+v", *x) }
func (x *NamePos) String() string { return fmt.Sprintf("%+v", *x) }
func (x *Package) String() string {
	c := *x
	c.typeMap = nil
	c.constMap = nil
	c.ifaceMap = nil
	c.typeDefs = nil
	c.constDefs = nil
	c.errorDefs = nil
	c.ifaceDefs = nil
	return fmt.Sprintf("%+v", c)
}
func (x *File) String() string {
	c := *x
	c.Package = nil // avoid infinite loop
	return fmt.Sprintf("%+v", c)
}
func (x *Interface) String() string {
	c := *x
	c.File = nil // avoid infinite loop
	return fmt.Sprintf("%+v", c)
}
func (x *Method) String() string {
	c := *x
	c.Interface = nil // avoid infinite loop
	return fmt.Sprintf("%+v", c)
}

func (x *Interface) AllMethods() []*Method {
	result := make([]*Method, len(x.Methods))
	copy(result, x.Methods)
	for _, embed := range x.Embeds {
		result = append(result, embed.AllMethods()...)
	}
	return result
}

func (x *Interface) FindMethod(name string) *Method {
	for _, m := range x.AllMethods() {
		if name == m.Name {
			return m
		}
	}
	return nil
}

func (x *Interface) TransitiveEmbeds() []*Interface {
	return x.transitiveEmbeds(make(map[*Interface]bool))
}

func (x *Interface) transitiveEmbeds(seen map[*Interface]bool) []*Interface {
	var ret []*Interface
	for _, e := range x.Embeds {
		if !seen[e] {
			seen[e] = true
			ret = append(ret, e)
			ret = append(ret, e.transitiveEmbeds(seen)...)
		}
	}
	return ret
}

// We might consider allowing more characters, but we'll need to ensure they're
// allowed in all our codegen languages.
var (
	regexpIdent = regexp.MustCompile("^[A-Za-z][A-Za-z0-9_]*$")
)

// hasUpperAcronym returns true if s contains an uppercase acronym; if s
// contains a run of two uppercase letters not followed by a lowercase letter.
// The lowercase letter special-case is to allow identifiers like "AMethod".
func hasUpperAcronym(s string) bool {
	upperRun := 0
	for _, r := range s {
		switch {
		case upperRun == 2 && !unicode.IsLower(r):
			return true
		case unicode.IsUpper(r):
			upperRun++
		default:
			upperRun = 0
		}
	}
	return upperRun >= 2
}

// validConstIdent returns (exported, err) where err is non-nil iff the
// identifer is valid as the name of a const.  Exported is true if the
// identifier is exported.  Valid: "^[A-Za-z][A-Za-z0-9_]*$"
func validConstIdent(ident string, mode reservedMode) (bool, error) {
	if re := regexpIdent; !re.MatchString(ident) {
		return false, fmt.Errorf("allowed regexp: %q", re)
	}
	if reservedWord(ident, mode) {
		return false, fmt.Errorf("reserved word in a generated language")
	}
	return ident[0] >= 'A' && ident[0] <= 'Z', nil
}

// validIdent is like validConstIdent, but applies to all non-const identifiers.
// It adds an additional check for uppercase acronyms.
func validIdent(ident string, mode reservedMode) (bool, error) {
	exported, err := validConstIdent(ident, mode)
	if err != nil {
		return false, err
	}
	if hasUpperAcronym(ident) {
		// TODO(toddw): Link to documentation explaining why.
		return false, fmt.Errorf("acronyms must use CamelCase")
	}
	return exported, nil
}

// validExportedIdent returns a non-nil error iff the identifier is valid and
// exported.
func validExportedIdent(ident string, mode reservedMode) error {
	exported, err := validIdent(ident, mode)
	if err != nil {
		return err
	}
	if !exported {
		return fmt.Errorf("must be exported")
	}
	return nil
}
