// 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"
	"cuelang.org/go/internal/core/runtime"
)

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 pathToStrings(e.v.Path())
}

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

func mkErr(idx *runtime.Runtime, 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
}
