// 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 eval

import (
	"sort"

	"cuelang.org/go/internal/core/adt"
)

// Nodes man not reenter a disjunction.
//
// Copy one layer deep; throw away items on failure.

// DISJUNCTION ALGORITHM
//
// The basic concept of the algorithm is to use backtracking to find valid
// disjunctions. The algorithm can stop if two matching disjuncts are found
// where one does not subsume the other.
//
// At a later point, we can introduce a filter step to filter out possible
// disjuncts based on, say, discriminator fields or field exclusivity (oneOf
// fields in Protobuf).
//
// To understand the details of the algorithm, it is important to understand
// some properties of disjunction.
//
//
// EVALUATION OF A DISJUNCTION IS SELF CONTAINED
//
// In other words, fields outside of a disjunction cannot bind to values within
// a disjunction whilst evaluating that disjunction. This allows the computation
// of disjunctions to be isolated from side effects.
//
// The intuition behind this is as follows: as a disjunction is not a concrete
// value, it is not possible to lookup a field within a disjunction if it has
// not yet been evaluated. So if a reference within a disjunction that is needed
// to disambiguate that disjunction refers to a field outside the scope of the
// disjunction which, in turn, refers to a field within the disjunction, this
// results in a cycle error. We achieve this by not removing the cycle marker of
// the Vertex of the disjunction until the disjunction is resolved.
//
// Note that the following disjunct is still allowed:
//
//    a: 1
//    b: a
//
// Even though `a` refers to the root of the disjunction, it does not _select
// into_ the disjunction. Implementation-wise, it also doesn't have to, as the
// respective vertex is available within the Environment. Referencing a node
// outside the disjunction that in turn selects the disjunction root, however,
// will result in a detected cycle.
//
// As usual, cycle detection should be interpreted marked as incomplete, so that
// the referring node will not be fixed to an error prematurely.
//
//
// SUBSUMPTION OF AMBIGUOUS DISJUNCTS
//
// A disjunction can be evaluated to a concrete value if only one disjunct
// remains. Aside from disambiguating through unification failure, disjuncts
// may also be disambiguated by taking the least specific of two disjuncts.
// For instance, if a subsumes b, then the result of disjunction may be a.
//
//   NEW ALGORITHM NO LONGER VERIFIES SUBSUMPTION. SUBSUMPTION IS INHERENTLY
//   IMPRECISE (DUE TO BULK OPTIONAL FIELDS). OTHER THAN THAT, FOR SCALAR VALUES
//   IT JUST MEANS THERE IS AMBIGUITY, AND FOR STRUCTS IT CAN LEAD TO STRANGE
//   CONSEQUENCES.
//
//   USE EQUALITY INSTEAD:
//     - Undefined == error for optional fields.
//     - So only need to check exact labels for vertices.

type envDisjunct struct {
	env         *adt.Environment
	values      []disjunct
	numDefaults int
	cloneID     uint32
	isEmbed     bool
}

type disjunct struct {
	expr      adt.Expr
	isDefault bool
}

func (n *nodeContext) addDisjunction(env *adt.Environment, x *adt.DisjunctionExpr, cloneID uint32, isEmbed bool) {
	a := []disjunct{}

	numDefaults := 0
	for _, v := range x.Values {
		isDef := v.Default // || n.hasDefaults(env, v.Val)
		if isDef {
			numDefaults++
		}
		a = append(a, disjunct{v.Val, isDef})
	}

	sort.SliceStable(a, func(i, j int) bool {
		return !a[j].isDefault && a[i].isDefault != a[j].isDefault
	})

	n.disjunctions = append(n.disjunctions,
		envDisjunct{env, a, numDefaults, cloneID, isEmbed})
}

func (n *nodeContext) addDisjunctionValue(env *adt.Environment, x *adt.Disjunction, cloneID uint32, isEmbed bool) {
	a := []disjunct{}

	for i, v := range x.Values {
		a = append(a, disjunct{v, i < x.NumDefaults})
	}

	n.disjunctions = append(n.disjunctions,
		envDisjunct{env, a, x.NumDefaults, cloneID, isEmbed})
}

func (n *nodeContext) updateResult() (isFinal bool) {
	n.postDisjunct()

	if n.hasErr() {
		return n.isFinal
	}

	d := n.nodeShared.disjunct
	if d == nil {
		d = &adt.Disjunction{}
		n.nodeShared.disjunct = d
	}

	result := *n.node
	if result.Value == nil {
		result.Value = n.getValidators()
	}

	for _, v := range d.Values {
		if Equal(n.ctx, v, &result) {
			return isFinal
		}
	}

	p := &result
	d.Values = append(d.Values, p)
	if n.defaultMode == isDefault {
		// Keep defaults sorted first.
		i := d.NumDefaults
		j := i + 1
		copy(d.Values[j:], d.Values[i:])
		d.Values[i] = p
		d.NumDefaults = j
	}

	// return n.isFinal

	switch {
	case !n.nodeShared.hasResult():

	case n.nodeShared.isDefault() && n.defaultMode != isDefault:
		return n.isFinal

	case !n.nodeShared.isDefault() && n.defaultMode == isDefault:

	default:
		if x := n.result(); x == nil && Equal(n.ctx, n.node, x) {
			return n.isFinal
		}

		// TODO: Compute fancy error message.
		n.nodeShared.resultNode = n
		// n.nodeShared.result.AddErr(n.ctx, &adt.Bottom{
		// 	Code: adt.IncompleteError,
		// 	Err:  errors.Newf(n.ctx.Pos(), "ambiguous disjunction"),
		// })
		n.nodeShared.result_.Arcs = nil
		n.nodeShared.result_.Structs = nil
		return n.isFinal // n.defaultMode == isDefault
	}

	n.nodeShared.resultNode = n
	n.nodeShared.setResult(n.node)

	return n.isFinal
}

func (n *nodeContext) tryDisjuncts() (finished bool) {
	if !n.insertDisjuncts() || !n.updateResult() {
		if !n.isFinal {
			return false // More iterations to do.
		}
	}

	if n.nodeShared.hasResult() {
		return true // found something
	}

	if len(n.disjunctions) > 0 {
		b := &adt.Bottom{
			// TODO(errors): we should not make this error worse by discarding
			// the type or error. Using IncompleteError is a compromise. But
			// really we should keep track of the errors and return a more
			// accurate result here.
			Code: adt.IncompleteError,
			Err:  n.ctx.Newf("empty disjunction"),
		}
		n.node.AddErr(n.ctx, b)
	}
	return true
}

// TODO: add proper conjuncts for the ones used by the disjunctions to replace
// the original source.
//
func (n *nodeContext) insertDisjuncts() (inserted bool) {
	p := 0
	inserted = true

	disjunctions := []envDisjunct{}

	// fmt.Println("----", debug.NodeString(n.ctx, n.node, nil))
	for _, d := range n.disjunctions {
		disjunctions = append(disjunctions, d)

		sub := len(n.disjunctions)
		defMode, ok := n.insertSingleDisjunct(p, d, false)
		p++
		if !ok {
			inserted = false
			break
		}

		subMode := maybeDefault
		for ; sub < len(n.disjunctions); sub++ {
			d := n.disjunctions[sub]

			// TODO: HACK ALERT: we ignore the default tags of the subexpression
			// if we already have a scalar value and can no longer change the
			// outcome.
			// This is not conform the spec, but mimics the old implementation.
			// It also results in nicer default semantics. Changing this will
			// break existing CUE code in awkward ways.
			// We probably should address this when we figure out how to change
			// the spec to accommodate for this. For instance, we could say
			// that if a disjunction only contributes a single disjunct to an
			// end result, default information is ignored. Not the greatest
			// definition, though.
			// Another alternative might be to have a special builtin that
			// mimics the good behavior.
			// Note that the same result can be obtained in CUE by adding
			// 0 to a referenced number (forces the default to be discarded).
			wasScalar := n.scalar != nil // Hack line 1

			disjunctions = append(disjunctions, d)
			mode, ok := n.insertSingleDisjunct(p, d, true)
			p++
			if !ok {
				inserted = false
				break
			}

			if !wasScalar { // Hack line 2.
				subMode = combineDefault(subMode, mode)
			}
		}
		defMode = combineSubDefault(defMode, subMode)

		n.defaultMode = combineDefault(n.defaultMode, defMode)
	}

	// Find last disjunction at which there is no overflow.
	for ; p > 0 && n.stack[p-1]+1 >= len(disjunctions[p-1].values); p-- {
	}
	if p > 0 {
		// Increment a valid position and set all subsequent entries to 0.
		n.stack[p-1]++
		n.stack = n.stack[:p]
	}
	return inserted
}

func (n *nodeContext) insertSingleDisjunct(p int, d envDisjunct, isSub bool) (mode defaultMode, ok bool) {
	if p >= len(n.stack) {
		n.stack = append(n.stack, 0)
	}

	k := n.stack[p]
	v := d.values[k]
	n.isFinal = n.isFinal && k == len(d.values)-1
	c := adt.MakeConjunct(d.env, v.expr)
	n.addExprConjunct(c, d.cloneID, d.isEmbed)

	for n.expandOne() {
	}

	switch {
	case d.numDefaults == 0:
		mode = maybeDefault
	case v.isDefault:
		mode = isDefault
	default:
		mode = notDefault
	}

	return mode, !n.hasErr()
}

// Default rules from spec:
//
// U1: (v1, d1) & v2       => (v1&v2, d1&v2)
// U2: (v1, d1) & (v2, d2) => (v1&v2, d1&d2)
//
// D1: (v1, d1) | v2       => (v1|v2, d1)
// D2: (v1, d1) | (v2, d2) => (v1|v2, d1|d2)
//
// M1: *v        => (v, v)
// M2: *(v1, d1) => (v1, d1)
//
// NOTE: M2 cannot be *(v1, d1) => (v1, v1), as this has the weird property
// of making a value less specific. This causes issues, for instance, when
// trimming.
//
// The old implementation does something similar though. It will discard
// default information after first determining if more than one conjunct
// has survived.
//
// def + maybe -> def
// not + maybe -> def
// not + def   -> def

type defaultMode int

const (
	maybeDefault defaultMode = iota
	notDefault
	isDefault
)

// combineSubDefault combines default modes where b is a subexpression in
// a disjunctions.
//
// Default rules from spec:
//
// D1: (v1, d1) | v2       => (v1|v2, d1)
// D2: (v1, d1) | (v2, d2) => (v1|v2, d1|d2)
//
// Spec:
// M1: *v        => (v, v)
// M2: *(v1, d1) => (v1, d1)
//
func combineSubDefault(a, b defaultMode) defaultMode {
	switch {
	case a == maybeDefault && b == maybeDefault: // D1
		return maybeDefault
	case a == maybeDefault && b == notDefault: // D1
		return notDefault
	case a == maybeDefault && b == isDefault: // D1
		return isDefault
	case a == notDefault && b == maybeDefault: // D1
		return notDefault
	case a == notDefault && b == notDefault: // D2
		return notDefault
	case a == notDefault && b == isDefault: // D2
		return isDefault
	case a == isDefault && b == maybeDefault: // D1
		return isDefault
	case a == isDefault && b == notDefault: // M2
		return notDefault
	case a == isDefault && b == isDefault: // D2
		return isDefault
	default:
		panic("unreachable")
	}
}

// combineDefaults combines default modes for unifying conjuncts.
//
// Default rules from spec:
//
// U1: (v1, d1) & v2       => (v1&v2, d1&v2)
// U2: (v1, d1) & (v2, d2) => (v1&v2, d1&d2)
func combineDefault(a, b defaultMode) defaultMode {
	if a > b {
		a, b = b, a
	}
	switch {
	case a == maybeDefault && b == maybeDefault:
		return maybeDefault
	case a == maybeDefault && b == notDefault:
		return notDefault
	case a == maybeDefault && b == isDefault:
		return isDefault
	case a == notDefault && b == notDefault:
		return notDefault
	case a == notDefault && b == isDefault:
		return notDefault
	case a == isDefault && b == isDefault:
		return isDefault
	default:
		panic("unreachable")
	}
}
