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

func (v Value) toErr(b *adt.Bottom) (err errors.Error) {
	errs := errors.Errors(b.Err)
	if len(errs) > 1 {
		for _, e := range errs {
			bb := *b
			bb.Err = e
			err = errors.Append(err, &valueError{v: v, err: &bb})
		}
		return err
	}
	return &valueError{v: v, err: b}
}

var _ errors.Error = &valueError{}

// A valueError is returned as a result of evaluating a value.
type valueError struct {
	v   Value
	err *adt.Bottom
}

func (e *valueError) Unwrap() error {
	if e.err.Err == nil {
		return nil
	}
	return errors.Unwrap(e.err.Err)
}

func (e *valueError) Bottom() *adt.Bottom { return e.err }

func (e *valueError) Error() string {
	return errors.String(e)
}

func (e *valueError) Position() token.Pos {
	if e.err.Err != nil {
		return e.err.Err.Position()
	}
	src := e.err.Source()
	if src == nil {
		return token.NoPos
	}
	return src.Pos()
}

func (e *valueError) InputPositions() []token.Pos {
	if e.err.Err == nil {
		return nil
	}
	return e.err.Err.InputPositions()
}

func (e *valueError) Msg() (string, []interface{}) {
	if e.err.Err == nil {
		return "", nil
	}
	return e.err.Err.Msg()
}

func (e *valueError) Path() (a []string) {
	if e.err.Err != nil {
		a = e.err.Err.Path()
		if a != nil {
			return a
		}
	}
	return e.v.appendPath(nil)
}

var errNotExists = &adt.Bottom{
	Code: adt.NotExistError,
	Err:  errors.Newf(token.NoPos, "undefined value"),
}

func (idx *index) mkErr(src adt.Node, args ...interface{}) *adt.Bottom {
	var e *adt.Bottom
	var code adt.ErrorCode = -1
outer:
	for i, a := range args {
		switch x := a.(type) {
		case adt.ErrorCode:
			code = x
		case *adt.Bottom:
			e = adt.CombineErrors(nil, e, x)
		case []*adt.Bottom:
			for _, b := range x {
				e = adt.CombineErrors(nil, e, b)
			}
		case errors.Error:
			e = adt.CombineErrors(nil, e, &adt.Bottom{Err: x})
		case adt.Expr:
		case string:
			args := args[i+1:]
			// Do not expand message so that errors can be localized.
			pos := pos(src)
			if code < 0 {
				code = 0
			}
			e = adt.CombineErrors(nil, e, &adt.Bottom{
				Code: code,
				Err:  errors.Newf(pos, x, args...),
			})
			break outer
		}
	}
	if code >= 0 {
		e.Code = code
	}
	return e
}
