// 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 (
	"github.com/cockroachdb/apd"
)

// context manages evaluation state.
type context struct {
	*apd.Context

	*index

	forwardMap []scope // pairs
	oldSize    []int

	// constraints are to be evaluated at the end values to be evaluated later.
	constraints []value
	noDelay     bool
	exprDepth   int // nesting of expression that are not unification
	evalDepth   int
	cycleErr    bool

	// for debug strings
	nodeRefs map[scope]string

	// tracing
	trace bool
	level int
}

var baseContext apd.Context

func init() {
	baseContext = apd.BaseContext
	baseContext.Precision = 24
}

// newContext returns a new evaluation context.
func (idx *index) newContext() *context {
	c := &context{
		Context: &baseContext,
		index:   idx,
	}
	return c
}

// delayConstraint schedules constraint to be evaluated and returns ret. If
// delaying constraints is currently not allowed, it returns an error instead.
func (c *context) delayConstraint(ret evaluated, constraint value) evaluated {
	if c.noDelay {
		return c.mkErr(ret, "delayed constraint %v violated", debugStr(c, constraint))
	}
	c.constraints = append(c.constraints, constraint)
	return ret
}

func (c *context) processDelayedConstraints() evaluated {
	cons := c.constraints
	c.constraints = c.constraints[:0]
	for _, dc := range cons {
		c.noDelay = true
		v := c.manifest(dc)
		c.noDelay = false
		if isBottom(v) {
			return c.mkErr(dc, "constraint violated: %v", debugStr(c, v))
		}
	}
	return nil
}

func (c *context) deref(f scope) scope {
outer:
	for {
		for i := 0; i < len(c.forwardMap); i += 2 {
			if c.forwardMap[i] == f {
				f = c.forwardMap[i+1]
				continue outer
			}
		}
		return f
	}
}

func (c *context) pushForwards(pairs ...scope) *context {
	c.oldSize = append(c.oldSize, len(c.forwardMap))
	c.forwardMap = append(c.forwardMap, pairs...)
	return c
}

func (c *context) popForwards() {
	last := len(c.oldSize) - 1
	c.forwardMap = c.forwardMap[:c.oldSize[last]]
	c.oldSize = c.oldSize[:last]
}
