// Copyright 2020 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 adt

import (
	"fmt"
	"reflect"
	"regexp"

	"github.com/cockroachdb/apd/v2"
	"golang.org/x/text/runes"

	"cuelang.org/go/cue/ast"
	"cuelang.org/go/cue/errors"
	"cuelang.org/go/cue/format"
	"cuelang.org/go/cue/token"
)

// A Unifier implements a strategy for CUE's unification operation. It must
// handle the following aspects of CUE evaluation:
//
//    - Structural and reference cycles
//    - Non-monotic validation
//    - Fixed-point computation of comprehension
//
type Unifier interface {
	// Unify fully unifies all values of a Vertex to completion and stores
	// the result in the Vertex. If Unify was called on v before it returns
	// the cached results.
	Unify(c *OpContext, v *Vertex, state VertexStatus) // error or bool?

	// Evaluate returns the evaluated value associated with v. It may return a
	// partial result. That is, if v was not yet unified, it may return a
	// concrete value that must be the result assuming the configuration has no
	// errors.
	//
	// This semantics allows CUE to break reference cycles in a straightforward
	// manner.
	//
	// Vertex v must still be evaluated at some point to catch the underlying
	// error.
	//
	Evaluate(c *OpContext, v *Vertex) Value
}

// Runtime defines an interface for low-level representation conversion and
// lookup.
type Runtime interface {
	// StringIndexer allows for converting string labels to and from a
	// canonical numeric representation.
	StringIndexer

	// LoadImport loads a unique Vertex associated with a given import path. It
	// returns an error if no import for this package could be found.
	LoadImport(importPath string) (*Vertex, errors.Error)

	// StoreType associates a CUE expression with a Go type.
	StoreType(t reflect.Type, src ast.Expr, expr Expr)

	// LoadType retrieves a previously stored CUE expression for a given Go
	// type if available.
	LoadType(t reflect.Type) (src ast.Expr, expr Expr, ok bool)
}

type Config struct {
	Runtime
	Unifier

	Format func(Node) string
}

type config = Config

// New creates an operation context.
func New(v *Vertex, cfg *Config) *OpContext {
	if cfg.Runtime == nil {
		panic("nil Runtime")
	}
	if cfg.Unifier == nil {
		panic("nil Unifier")
	}
	ctx := &OpContext{
		config: *cfg,
	}
	if v != nil {
		ctx.e = &Environment{Up: nil, Vertex: v}
	}
	return ctx
}

// An OpContext associates a Runtime and Unifier to allow evaluating the types
// defined in this package. It tracks errors provides convenience methods for
// evaluating values.
type OpContext struct {
	config

	e    *Environment
	src  ast.Node
	errs *Bottom

	// TODO: remove use of tentative. Should be possible if incomplete
	// handling is done better.
	tentative int // set during comprehension evaluation
}

// Impl is for internal use only. This will go.
func (c *OpContext) Impl() Runtime {
	return c.config.Runtime
}

// If IsTentative is set, evaluation of an arc should not finalize
// to non-concrete values.
func (c *OpContext) IsTentative() bool {
	return c.tentative > 0
}

func (c *OpContext) Pos() token.Pos {
	if c.src == nil {
		return token.NoPos
	}
	return c.src.Pos()
}

func (c *OpContext) Source() ast.Node {
	return c.src
}

// NewContext creates an operation context.
func NewContext(r Runtime, u Unifier, v *Vertex) *OpContext {
	return New(v, &Config{Runtime: r, Unifier: u})
}

func (c *OpContext) pos() token.Pos {
	if c.src == nil {
		return token.NoPos
	}
	return c.src.Pos()
}

func (c *OpContext) spawn(node *Vertex) *OpContext {
	sub := *c
	node.Parent = c.e.Vertex
	sub.e = &Environment{Up: c.e, Vertex: node}
	if c.e != nil {
		sub.e.CloseID = c.e.CloseID
	}
	return &sub
}

func (c *OpContext) Env(upCount int32) *Environment {
	e := c.e
	for ; upCount > 0; upCount-- {
		e = e.Up
	}
	return e
}

func (c *OpContext) relNode(upCount int32) *Vertex {
	e := c.e
	for ; upCount > 0; upCount-- {
		e = e.Up
	}
	return e.Vertex
}

func (c *OpContext) relLabel(upCount int32) Feature {
	// locate current label.
	e := c.e
	for ; upCount > 0; upCount-- {
		e = e.Up
	}
	return e.DynamicLabel
}

func (c *OpContext) concreteIsPossible(x Expr) bool {
	if v, ok := x.(Value); ok {
		if v.Concreteness() > Concrete {
			c.AddErrf("value can never become concrete")
			return false
		}
	}
	return true
}

// HasErr reports whether any error was reported, including whether value
// was incomplete.
func (c *OpContext) HasErr() bool {
	return c.errs != nil
}

func (c *OpContext) Err() *Bottom {
	b := c.errs
	c.errs = nil
	return b
}

func (c *OpContext) addErrf(code ErrorCode, pos token.Pos, msg string, args ...interface{}) {
	for i, a := range args {
		switch x := a.(type) {
		case Node:
			args[i] = c.Str(x)
		case ast.Node:
			b, _ := format.Node(x)
			args[i] = string(b)
		case Feature:
			args[i] = x.SelectorString(c.Runtime)
		}
	}

	err := errors.Newf(pos, msg, args...)
	c.addErr(code, err)
}

func (c *OpContext) addErr(code ErrorCode, err errors.Error) {
	c.errs = CombineErrors(c.src, c.errs, &Bottom{Code: code, Err: err})
}

// AddBottom records an error in OpContext.
func (c *OpContext) AddBottom(b *Bottom) {
	c.errs = CombineErrors(c.src, c.errs, b)
}

// AddErr records an error in OpContext. It returns errors collected so far.
func (c *OpContext) AddErr(err errors.Error) *Bottom {
	if err != nil {
		c.errs = CombineErrors(c.src, c.errs, &Bottom{Err: err})
	}
	return c.errs
}

// NewErrf creates a *Bottom value and returns it. The returned uses the
// current source as the point of origin of the error.
func (c *OpContext) NewErrf(format string, args ...interface{}) *Bottom {
	err := errors.Newf(c.pos(), format, args...)
	return &Bottom{Src: c.src, Err: err, Code: EvalError}
}

// AddErrf records an error in OpContext. It returns errors collected so far.
func (c *OpContext) AddErrf(format string, args ...interface{}) *Bottom {
	return c.AddErr(errors.Newf(c.pos(), format, args...))
}

func (c *OpContext) validate(v Value) *Bottom {
	switch x := v.(type) {
	case *Bottom:
		return x
	case *Vertex:
		v := c.Unifier.Evaluate(c, x)
		if b, ok := v.(*Bottom); ok {
			return b
		}
	}
	return nil
}

type frame struct {
	env *Environment
	err *Bottom
	src ast.Node
}

func (c *OpContext) PushState(env *Environment, src ast.Node) (saved frame) {
	saved.env = c.e
	saved.err = c.errs
	saved.src = c.src

	c.errs = nil
	if src != nil {
		c.src = src
	}
	if env != nil {
		c.e = env
	}

	return saved
}

func (c *OpContext) PopState(s frame) *Bottom {
	err := c.errs
	c.e = s.env
	c.errs = s.err
	c.src = s.src
	return err
}

// Resolve finds a node in the tree.
//
// Should only be used to insert Conjuncts. TODO: perhaps only return Conjuncts
// and error.
func (c *OpContext) Resolve(env *Environment, r Resolver) (*Vertex, *Bottom) {
	s := c.PushState(env, r.Source())

	arc := r.resolve(c)
	// TODO: check for cycle errors?

	err := c.PopState(s)
	if err != nil {
		return nil, err
	}

	return arc, err
}

// Validate calls validates value for the given validator.
func (c *OpContext) Validate(check Validator, value Value) *Bottom {
	return check.validate(c, value)
}

// Yield evaluates a Yielder and calls f for each result.
func (c *OpContext) Yield(env *Environment, y Yielder, f YieldFunc) *Bottom {
	s := c.PushState(env, y.Source())

	c.tentative++

	y.yield(c, f)

	c.tentative--

	return c.PopState(s)

}

// Concrete returns the concrete value of x after evaluating it.
// msg is used to mention the context in which an error occurred, if any.
func (c *OpContext) Concrete(env *Environment, x Expr, msg interface{}) (result Value, complete bool) {

	v, complete := c.Evaluate(env, x)

	v, ok := c.getDefault(v)
	if !ok {
		return v, false
	}

	if !IsConcrete(v) {
		complete = false
		b := c.NewErrf("non-concrete value %v in operand to %s", c.Str(v), msg)
		b.Code = IncompleteError
		v = b
	}

	if !complete {
		return v, complete
	}

	return v, true
}

func (c *OpContext) getDefault(v Value) (result Value, ok bool) {
	var d *Disjunction
	switch x := v.(type) {
	default:
		return v, true

	case *Vertex:
		switch t := x.Value.(type) {
		case *Disjunction:
			d = t

		case *StructMarker, *ListMarker:
			return v, true

		default:
			return t, true
		}

	case *Disjunction:
		d = x
	}

	if d.NumDefaults != 1 {
		c.addErrf(IncompleteError, c.pos(),
			"unresolved disjunction %s (type %s)", c.Str(d), d.Kind())
		return nil, false
	}
	return c.getDefault(d.Values[0])
}

// Evaluate evaluates an expression within the given environment and indicates
// whether the result is complete. It will always return a non-nil result.
func (c *OpContext) Evaluate(env *Environment, x Expr) (result Value, complete bool) {
	s := c.PushState(env, x.Source())

	val := c.eval(x)

	complete = true

	if err, _ := val.(*Bottom); err != nil && err.IsIncomplete() {
		complete = false
	}
	if val == nil {
		complete = false
		// TODO ENSURE THIS DOESN"T HAPPEN>
		val = &Bottom{
			Code: IncompleteError,
			Err:  errors.Newf(token.NoPos, "UNANTICIPATED ERROR"),
		}

	}

	_ = c.PopState(s)

	if !complete || val == nil {
		return val, false
	}

	return val, true
}

// value evaluates expression v within the current environment. The result may
// be nil if the result is incomplete. value leaves errors untouched to that
// they can be collected by the caller.
func (c *OpContext) value(x Expr) (result Value) {
	v := c.evalState(x, Partial)

	v, _ = c.getDefault(v)
	return v
}

func (c *OpContext) eval(v Expr) (result Value) {
	return c.evalState(v, Partial)
}

func (c *OpContext) evalState(v Expr, state VertexStatus) (result Value) {
	savedSrc := c.src
	c.src = v.Source()
	err := c.errs
	c.errs = nil

	defer func() {
		c.errs = CombineErrors(c.src, c.errs, err)
		c.errs = CombineErrors(c.src, c.errs, result)
		if c.errs != nil {
			result = c.errs
		}
		c.src = savedSrc
	}()

	switch x := v.(type) {
	case Value:
		return x

	case Evaluator:
		v := x.evaluate(c)
		return v

	case Resolver:
		arc := x.resolve(c)
		if c.HasErr() {
			return nil
		}
		if isIncomplete(arc) {
			if arc != nil {
				return arc.Value
			}
			return nil
		}

		v := c.Unifier.Evaluate(c, arc)
		return v

	default:
		// return nil
		c.AddErrf("unexpected Expr type %T", v)
	}
	return nil
}

func (c *OpContext) lookup(x *Vertex, pos token.Pos, l Feature) *Vertex {
	if l == InvalidLabel || x == nil {
		// TODO: is it possible to have an invalid label here? Maybe through the
		// API?
		return &Vertex{}
	}

	var kind Kind
	if x.Value != nil {
		kind = x.Value.Kind()
	}

	switch kind {
	case StructKind:
		if l.Typ() == IntLabel {
			c.addErrf(0, pos, "invalid struct selector %s (type int)", l)
		}

	case ListKind:
		switch {
		case l.Typ() == IntLabel:
			switch {
			case l.Index() < 0:
				c.addErrf(0, pos, "invalid list index %s (index must be non-negative)", l)
				return nil
			case l.Index() > len(x.Arcs):
				c.addErrf(0, pos, "invalid list index %s (out of bounds)", l)
				return nil
			}

		case l.IsDef():

		default:
			c.addErrf(0, pos, "invalid list index %s (type string)", l)
			return nil
		}

	default:
		// TODO: ?
		// if !l.IsDef() {
		// 	c.addErrf(0, nil, "invalid selector %s (must be definition for non-structs)", l)
		// }
	}

	a := x.Lookup(l)
	if a == nil {
		code := IncompleteError
		if !x.Accept(c, l) {
			code = 0
		}
		// TODO: if the struct was a literal struct, we can also treat it as
		// closed and make this a permanent error.
		c.addErrf(code, pos, "undefined field %s", l.SelectorString(c.Runtime))
	}
	return a
}

func (c *OpContext) Label(x Value) Feature {
	return labelFromValue(c, x)
}

func (c *OpContext) typeError(v Value, k Kind) {
	if isError(v) {
		return
	}
	if !IsConcrete(v) && v.Kind()&k != 0 {
		c.addErrf(IncompleteError, pos(v),
			"incomplete %s value '%s'", k, c.Str(v))
	} else {
		c.AddErrf("cannot use %s (type %s) as type %s", c.Str(v), v.Kind(), k)
	}
}

func (c *OpContext) typeErrorAs(v Value, k Kind, as interface{}) {
	if as == nil {
		c.typeError(v, k)
		return
	}
	if isError(v) {
		return
	}
	if !IsConcrete(v) && v.Kind()&k != 0 {
		c.addErrf(IncompleteError, pos(v),
			"incomplete %s value '%s' in as", k, c.Str(v), as)
	} else {
		c.AddErrf("cannot use %s (type %s) as type %s in %v",
			c.Str(v), v.Kind(), k, as)
	}
}

var emptyNode = &Vertex{}

func pos(x Node) token.Pos {
	if x.Source() == nil {
		return token.NoPos
	}
	return x.Source().Pos()
}

func (c *OpContext) node(x Expr, state VertexStatus) *Vertex {
	v := c.evalState(x, state)

	node, ok := v.(*Vertex)
	if !ok {
		if isError(v) {
			if v == nil {
				c.addErrf(IncompleteError, pos(x), "incomplete value %s", c.Str(x))
			}
			return emptyNode
		}
		if v.Kind()&StructKind != 0 {
			c.addErrf(IncompleteError, pos(x),
				"incomplete feed source value %s (type %s)",
				x.Source(), v.Kind())
		} else {
			c.addErrf(0, pos(x),
				"invalid operand %s (found %s, want list or struct)",
				x.Source(), v.Kind())

		}
		return emptyNode
	}
	return node.Default()
}

// Elems returns the elements of a list.
func (c *OpContext) Elems(v Value) []*Vertex {
	list := c.list(v)
	return list.Elems()
}

func (c *OpContext) list(v Value) *Vertex {
	x, ok := v.(*Vertex)
	if !ok || !x.IsList() {
		c.typeError(v, ListKind)
		return emptyNode
	}
	return x
}

func (c *OpContext) scalar(v Value) Value {
	v = Unwrap(v)
	switch v.(type) {
	case *Null, *Bool, *Num, *String, *Bytes:
	default:
		c.typeError(v, ScalarKinds)
	}
	return v
}

var zero = &Num{K: NumKind}

func (c *OpContext) num(v Value, as interface{}) *Num {
	v = Unwrap(v)
	if isError(v) {
		return zero
	}
	x, ok := v.(*Num)
	if !ok {
		c.typeErrorAs(v, NumKind, as)
		return zero
	}
	return x
}

func (c *OpContext) Int64(v Value) int64 {
	v = Unwrap(v)
	if isError(v) {
		return 0
	}
	x, ok := v.(*Num)
	if !ok {
		c.typeError(v, IntKind)
		return 0
	}
	i, err := x.X.Int64()
	if err != nil {
		c.AddErrf("number is not an int64: %v", err)
		return 0
	}
	return i
}

func (c *OpContext) uint64(v Value, as string) uint64 {
	v = Unwrap(v)
	if isError(v) {
		return 0
	}
	x, ok := v.(*Num)
	if !ok {
		c.typeErrorAs(v, IntKind, as)
		return 0
	}
	if x.X.Negative {
		// TODO: improve message
		c.AddErrf("cannot convert negative number to uint64")
		return 0
	}
	if !x.X.Coeff.IsUint64() {
		// TODO: improve message
		c.AddErrf("cannot convert number %s to uint64", x.X)
		return 0
	}
	return x.X.Coeff.Uint64()
}

func (c *OpContext) BoolValue(v Value) bool {
	return c.boolValue(v, nil)
}

func (c *OpContext) boolValue(v Value, as interface{}) bool {
	v = Unwrap(v)
	if isError(v) {
		return false
	}
	x, ok := v.(*Bool)
	if !ok {
		c.typeErrorAs(v, BoolKind, as)
		return false
	}
	return x.B
}

func (c *OpContext) StringValue(v Value) string {
	return c.stringValue(v, nil)
}

func (c *OpContext) stringValue(v Value, as interface{}) string {
	v = Unwrap(v)
	if isError(v) {
		return ""
	}
	switch x := v.(type) {
	case *String:
		return x.Str

	case *Bytes:
		return string(runes.ReplaceIllFormed().Bytes(x.B))

	case *Num:
		return x.X.String()

	default:
		if as == nil {
			c.typeError(v, StringKind)
		} else {
			c.typeErrorAs(v, StringKind, as)
		}
	}
	return ""
}

func (c *OpContext) bytesValue(v Value, as interface{}) []byte {
	v = Unwrap(v)
	if isError(v) {
		return nil
	}
	x, ok := v.(*Bytes)
	if !ok {
		c.typeErrorAs(v, BytesKind, as)
		return nil
	}
	return x.B
}

var matchNone = regexp.MustCompile("^$")

func (c *OpContext) regexp(v Value) *regexp.Regexp {
	v = Unwrap(v)
	if isError(v) {
		return matchNone
	}
	switch x := v.(type) {
	case *String:
		if x.RE != nil {
			return x.RE
		}
		// TODO: synchronization
		p, err := regexp.Compile(x.Str)
		if err != nil {
			// FatalError? How to cache error
			c.AddErrf("invalid regexp: %s", err)
			x.RE = matchNone
		} else {
			x.RE = p
		}
		return x.RE

	case *Bytes:
		if x.RE != nil {
			return x.RE
		}
		// TODO: synchronization
		p, err := regexp.Compile(string(x.B))
		if err != nil {
			c.AddErrf("invalid regexp: %s", err)
			x.RE = matchNone
		} else {
			x.RE = p
		}
		return x.RE

	default:
		c.typeError(v, StringKind|BytesKind)
		return matchNone
	}
}

func (c *OpContext) newNum(d *apd.Decimal, k Kind, sources ...Node) Value {
	if c.HasErr() {
		return c.Err()
	}
	return &Num{Src: c.src, X: *d, K: k}
}

func (c *OpContext) NewInt64(n int64, sources ...Node) Value {
	if c.HasErr() {
		return c.Err()
	}
	d := apd.New(n, 0)
	return &Num{Src: c.src, X: *d, K: IntKind}
}

func (c *OpContext) NewString(s string) Value {
	if c.HasErr() {
		return c.Err()
	}
	return &String{Src: c.src, Str: s}
}

func (c *OpContext) newBytes(b []byte) Value {
	if c.HasErr() {
		return c.Err()
	}
	return &Bytes{Src: c.src, B: b}
}

func (c *OpContext) newBool(b bool) Value {
	if c.HasErr() {
		return c.Err()
	}
	return &Bool{Src: c.src, B: b}
}

func (c *OpContext) newList(src ast.Node, parent *Vertex) *Vertex {
	return &Vertex{Parent: parent, Value: &ListMarker{}}
}

// Str reports a debug string of x.
func (c *OpContext) Str(x Node) string {
	if c.Format == nil {
		return fmt.Sprintf("%T", x)
	}
	return c.Format(x)
}

// NewList returns a new list for the given values.
func (c *OpContext) NewList(values ...Value) *Vertex {
	// TODO: consider making this a literal list instead.
	list := &ListLit{}
	v := &Vertex{
		Conjuncts: []Conjunct{{Env: nil, x: list}},
	}

	for _, x := range values {
		list.Elems = append(list.Elems, x)
	}
	c.Unify(c, v, Finalized)
	return v
}
