// Copyright 2018 The CUE Authors
//
// 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 cue

import (
	goast "go/ast"

	"cuelang.org/go/cue/ast"
	"cuelang.org/go/cue/build"
	"cuelang.org/go/cue/errors"
	"cuelang.org/go/cue/token"
	"cuelang.org/go/internal"
)

// An Instance defines a single configuration based on a collection of
// underlying CUE files.
type Instance struct {
	*index

	rootStruct *structLit // the struct to insert root values into
	rootValue  value      // the value to evaluate: may add comprehensions

	// scope is used as an additional top-level scope between the package scope
	// and the predeclared identifiers.
	scope *structLit

	ImportPath  string
	Dir         string
	PkgName     string
	DisplayName string

	Incomplete bool         // true if Pkg and all its dependencies are free of errors
	Err        errors.Error // non-nil if the package had errors

	inst *build.Instance

	complete bool // for cycle detection
}

func (x *index) addInst(p *Instance) *Instance {
	if p.rootStruct == nil {
		panic("struct must not be nil")
	}
	p.index = x
	x.imports[p.rootValue] = p
	if p.ImportPath != "" {
		x.importsByPath[p.ImportPath] = p
	}
	return p
}

func (x *index) getImportFromNode(v value) *Instance {
	imp := x.imports[v]
	if imp == nil && x.parent != nil {
		return x.parent.getImportFromNode(v)
	}
	return imp
}

func init() {
	internal.MakeInstance = func(value interface{}) interface{} {
		v := value.(Value)
		x := v.eval(v.ctx())
		st, ok := x.(*structLit)
		if !ok {
			st = &structLit{baseValue: x.base(), emit: x}
		}
		return v.ctx().index.addInst(&Instance{
			rootStruct: st,
			rootValue:  v.path.v,
		})
	}
}

// newInstance creates a new instance. Use Insert to populate the instance.
func (x *index) newInstance(p *build.Instance) *Instance {
	// TODO: associate root source with structLit.
	st := &structLit{baseValue: baseValue{nil}}
	i := &Instance{
		rootStruct: st,
		rootValue:  st,
		inst:       p,
	}
	if p != nil {
		i.ImportPath = p.ImportPath
		i.Dir = p.Dir
		i.PkgName = p.PkgName
		i.DisplayName = p.ImportPath
		if p.Err != nil {
			i.setListOrError(p.Err)
		}
	}
	return x.addInst(i)
}

func (inst *Instance) setListOrError(err errors.Error) {
	inst.Incomplete = true
	inst.Err = errors.Append(inst.Err, err)
}

func (inst *Instance) setError(err errors.Error) {
	inst.Incomplete = true
	inst.Err = errors.Append(inst.Err, err)
}

func (inst *Instance) eval(ctx *context) evaluated {
	// TODO: remove manifest here?
	v := ctx.manifest(inst.rootValue)
	if s, ok := v.(*structLit); ok && s.emit != nil {
		e := s.emit.evalPartial(ctx)
		src := binSrc(token.NoPos, opUnify, v, e)
	outer:
		switch e.(type) {
		case *structLit, *top:
			v = binOp(ctx, src, opUnifyUnchecked, v, e)
			if s, ok := v.(*structLit); ok {
				s.emit = nil
			}

		default:
			for _, a := range s.arcs {
				if !a.definition {
					v = binOp(ctx, src, opUnify, v, e)
					break outer
				}
			}
			return e
		}
	}
	return v
}

func init() {
	internal.EvalExpr = func(value, expr interface{}) interface{} {
		v := value.(Value)
		e := expr.(ast.Expr)
		ctx := v.idx.newContext()
		return newValueRoot(ctx, evalExpr(ctx, v.eval(ctx), e))
	}
}

func evalExpr(ctx *context, x value, expr ast.Expr) evaluated {
	if isBottom(x) {
		return ctx.mkErr(x, "error evaluating instance: %v", x)
	}
	obj, ok := x.(*structLit)
	if !ok {
		return ctx.mkErr(x, "instance is not a struct, found %s", x.kind())
	}
	v := newVisitor(ctx.index, nil, nil, obj, true)
	return v.walk(expr).evalPartial(ctx)
}

// Doc returns the package comments for this instance.
func (inst *Instance) Doc() []*ast.CommentGroup {
	var docs []*ast.CommentGroup
	if inst.inst == nil {
		return nil
	}
	for _, f := range inst.inst.Files {
		pkg, _, _ := internal.PackageInfo(f)
		if pkg == nil {
			continue
		}
		var cg *ast.CommentGroup
		for _, c := range pkg.Comments() {
			if c.Position == 0 {
				cg = c
			}
		}
		if cg != nil {
			docs = append(docs, cg)
		}
	}
	return docs
}

// Value returns the root value of the configuration. If the configuration
// defines in emit value, it will be that value. Otherwise it will be all
// top-level values.
func (inst *Instance) Value() Value {
	ctx := inst.newContext()
	return newValueRoot(ctx, inst.eval(ctx))
}

// Eval evaluates an expression within an existing instance.
//
// Expressions may refer to builtin packages if they can be uniquely identified.
func (inst *Instance) Eval(expr ast.Expr) Value {
	ctx := inst.newContext()
	result := evalExpr(ctx, inst.eval(ctx), expr)
	return newValueRoot(ctx, result)
}

// Merge unifies the given instances into a single one.
//
// Errors regarding conflicts are included in the result, but not reported, so
// that these will only surface during manifestation. This allows
// non-conflicting parts to be used.
func Merge(inst ...*Instance) *Instance {
	switch len(inst) {
	case 0:
		return nil
	case 1:
		return inst[0]
	}

	values := []value{}
	for _, i := range inst {
		if i.Err != nil {
			return i
		}
		values = append(values, i.rootValue)
	}
	merged := &mergedValues{values: values}

	ctx := inst[0].newContext()

	st, ok := ctx.manifest(merged).(*structLit)
	if !ok {
		return nil
	}

	p := ctx.index.addInst(&Instance{
		rootStruct: st,
		rootValue:  merged,
		complete:   true,
	})
	return p
}

// Build creates a new instance from the build instances, allowing unbound
// identifier to bind to the top-level field in inst. The top-level fields in
// inst take precedence over predeclared identifier and builtin functions.
func (inst *Instance) Build(p *build.Instance) *Instance {
	p.Complete()

	idx := inst.index

	i := idx.newInstance(p)
	if i.Err != nil {
		return i
	}

	ctx := inst.newContext()
	val := newValueRoot(ctx, inst.rootValue)
	v, err := val.structValFull(ctx)
	if err != nil {
		i.setError(val.toErr(err))
		return i
	}
	i.scope = v.obj

	if err := resolveFiles(idx, p); err != nil {
		i.setError(err)
		return i
	}
	for _, f := range p.Files {
		if err := i.insertFile(f); err != nil {
			i.setListOrError(err)
		}
	}
	i.complete = true

	return i
}

// Lookup reports the value at a path starting from the top level struct. The
// Exists method of the returned value will report false if the path did not
// exist. The Err method reports if any error occurred during evaluation. The
// empty path returns the top-level configuration struct. Use LookupDef for definitions or LookupField for
// any kind of field.
func (inst *Instance) Lookup(path ...string) Value {
	idx := inst.index
	ctx := idx.newContext()
	v := newValueRoot(ctx, inst.rootValue)
	for _, k := range path {
		obj, err := v.structValData(ctx)
		if err != nil {
			return Value{idx, &valueData{arc: arc{cache: err, v: err}}}
		}
		v = obj.Lookup(k)
	}
	return v
}

// LookupDef reports the definition with the given name within struct v. The
// Exists method of the returned value will report false if the definition did
// not exist. The Err method reports if any error occurred during evaluation.
func (inst *Instance) LookupDef(path string) Value {
	ctx := inst.index.newContext()
	v := newValueRoot(ctx, inst.rootValue.evalPartial(ctx))
	return v.LookupDef(path)
}

// LookupField reports a Field at a path starting from v, or an error if the
// path is not. The empty path returns v itself.
//
// It cannot look up hidden or unexported fields.
func (inst *Instance) LookupField(path ...string) (f FieldInfo, err error) {
	idx := inst.index
	ctx := idx.newContext()
	v := newValueRoot(ctx, inst.rootValue)
	for i, k := range path {
		s, err := v.Struct()
		if err != nil {
			return f, err
		}

		f, err = s.FieldByName(k)
		if err != nil {
			return f, err
		}
		if f.IsHidden || (i == 0 || f.IsDefinition) && !goast.IsExported(f.Name) {
			return f, errNotFound
		}
		v = f.Value
	}
	return f, err
}

// Fill creates a new instance with the values of the old instance unified with
// the given value. It is not possible to update the emit value.
//
// Values may be any Go value that can be converted to CUE, an ast.Expr or
// a Value. In the latter case, it will panic if the Value is not from the same
// Runtime.
func (inst *Instance) Fill(x interface{}, path ...string) (*Instance, error) {
	ctx := inst.newContext()
	root := ctx.manifest(inst.rootValue)
	for i := len(path) - 1; i >= 0; i-- {
		x = map[string]interface{}{path[i]: x}
	}
	var value evaluated
	if v, ok := x.(Value); ok {
		if inst.index != v.ctx().index {
			panic("value of type Value is not created with same Runtime as Instance")
		}
		value = v.eval(ctx)
	} else {
		value = convert(ctx, root, true, x)
	}
	eval := binOp(ctx, baseValue{}, opUnify, root, value)
	// TODO: validate recursively?
	err := inst.Err
	var st *structLit
	var stVal evaluated
	switch x := eval.(type) {
	case *structLit:
		st = x
		stVal = x
	default:
		// This should not happen.
		b := ctx.mkErr(eval, "error filling struct")
		err = inst.Value().toErr(b)
		st = &structLit{emit: b}
		stVal = b
	case *bottom:
		err = inst.Value().toErr(x)
		st = &structLit{emit: x}
		stVal = x
	}
	inst = inst.index.addInst(&Instance{
		rootStruct: st,
		rootValue:  stVal,
		inst:       nil,

		// Omit ImportPath to indicate this is not an importable package.
		Dir:        inst.Dir,
		PkgName:    inst.PkgName,
		Incomplete: inst.Incomplete,
		Err:        err,

		complete: err != nil,
	})
	return inst, err
}
