// 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 (
	"cuelang.org/go/cue/ast"
	"cuelang.org/go/cue/build"
	"cuelang.org/go/cue/errors"
	"cuelang.org/go/cue/token"
	"cuelang.org/go/internal"
	"cuelang.org/go/internal/core/runtime"
)

// 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 {
	x.Index.AddInst(p.ImportPath, p.rootStruct, p)
	p.index = x
	return p
}

func (x *index) getImportFromNode(v value) *Instance {
	p := x.Index.GetImportFromNode(v)
	if p == nil {
		return nil
	}
	return p.(*Instance)
}

func (x *index) getImportFromPath(id string) *Instance {
	node := x.Index.GetImportFromPath(id)
	if node == nil {
		return nil
	}
	return x.Index.GetImportFromNode(node).(*Instance)
}

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.v.v,
		})
	}
}

// newInstance creates a new instance. Use Insert to populate the instance.
func newInstance(x *index, 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 {
		if c := internal.FileComment(f); c != nil {
			docs = append(docs, c)
		}
	}
	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 := newInstance(idx, 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 := runtime.ResolveFiles(idx.Index, p, isBuiltin); 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
}

func (inst *Instance) value() Value {
	return newValueRoot(inst.newContext(), inst.rootValue)
}

// 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 {
	return inst.value().Lookup(path...)
}

// 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 {
	return inst.value().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.
//
// Deprecated: this API does not work with new-style definitions. Use
// FieldByName defined on inst.Value().
func (inst *Instance) LookupField(path ...string) (f FieldInfo, err error) {
	v := inst.value()
	for _, k := range path {
		s, err := v.Struct()
		if err != nil {
			return f, err
		}

		f, err = s.FieldByName(k, true)
		if err != nil {
			return f, err
		}
		if f.IsHidden {
			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}
	}
	value := convertVal(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
}
