// 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 validate collects errors from an evaluated Vertex.
package validate

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

type Config struct {
	// Concrete, if true, requires that all values be concrete.
	Concrete bool

	// DisallowCycles indicates that there may not be cycles.
	DisallowCycles bool

	// AllErrors continues descending into a Vertex, even if errors are found.
	AllErrors bool

	// TODO: omitOptional, if this is becomes relevant.
}

// Validate checks that a value has certain properties. The value must have
// been evaluated.
func Validate(ctx *adt.OpContext, v *adt.Vertex, cfg *Config) *adt.Bottom {
	if cfg == nil {
		cfg = &Config{}
	}
	x := validator{Config: *cfg, ctx: ctx}
	x.validate(v)
	return x.err
}

type validator struct {
	Config
	ctx          *adt.OpContext
	err          *adt.Bottom
	inDefinition int
}

func (v *validator) checkConcrete() bool {
	return v.Concrete && v.inDefinition == 0
}

func (v *validator) add(b *adt.Bottom) {
	if !v.AllErrors {
		v.err = adt.CombineErrors(nil, v.err, b)
		return
	}
	if !b.ChildError {
		v.err = adt.CombineErrors(nil, v.err, b)
	}
}

func (v *validator) validate(x *adt.Vertex) {
	defer v.ctx.PopArc(v.ctx.PushArc(x))

	if b, _ := x.Value.(*adt.Bottom); b != nil {
		switch b.Code {
		case adt.CycleError:
			if v.checkConcrete() || v.DisallowCycles {
				v.add(b)
			}

		case adt.IncompleteError, adt.NotExistError:
			if v.checkConcrete() {
				v.add(b)
			}

		default:
			v.add(b)
		}
		if !b.HasRecursive {
			return
		}

	} else if v.checkConcrete() {
		x := x.Default()
		if !adt.IsConcrete(x) {
			v.add(&adt.Bottom{
				Code: adt.IncompleteError,
				Err:  v.ctx.Newf("incomplete value %v", v.ctx.Str(x.Value)),
			})
		}
	}

	for _, a := range x.Arcs {
		if !v.AllErrors && v.err != nil {
			break
		}
		if a.Label.IsRegular() {
			v.validate(a)
		} else {
			v.inDefinition++
			v.validate(a)
			v.inDefinition--
		}
	}
}
