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

//go:generate go run gen.go

package cue

import (
	"fmt"
	"io"
	"math/big"
	"path"
	"reflect"
	"sort"
	"strconv"
	"strings"

	"cuelang.org/go/cue/ast"
	"github.com/cockroachdb/apd"
)

// A builtin is a builtin function or constant.
//
// A function may return and a constant may be any of the following types:
//
//   error (translates to bottom)
//   nil   (translates to null)
//   bool
//   int*
//   uint*
//   float64
//   string
//   *big.Float
//   *big.Int
//
//   For any of the above, including interface{} and these types recursively:
//   []T
//   map[string]T
//
type builtin struct {
	baseValue
	Name   string
	Params []kind
	Result kind
	Func   func(c *callCtxt)
	// Const  interface{}
	Const evaluated
}

var _ caller = &builtin{}

var lenBuiltin = &builtin{
	Name:   "len",
	Params: []kind{stringKind | bytesKind | listKind | structKind},
	Result: intKind,
	Func: func(c *callCtxt) {
		v := c.value(0)
		switch v.Kind() {
		case StructKind:
			s, _ := v.structVal(c.ctx)
			c.ret = s.Len()
		case ListKind:
			i := 0
			iter, _ := v.List()
			for ; iter.Next(); i++ {
			}
			c.ret = i
		case BytesKind:
			b, _ := v.Bytes()
			c.ret = len(b)
		case StringKind:
			s, _ := v.String()
			c.ret = len(s)
		}
	},
}

func (x *builtin) kind() kind {
	if x.Const != nil {
		return x.Const.kind()
	}
	return lambdaKind
}

func (x *builtin) evalPartial(ctx *context) evaluated {
	if x.Const != nil {
		return x.Const
	}
	return x
}

func (x *builtin) subsumesImpl(ctx *context, v value, mode subsumeMode) bool {
	if y, ok := v.(*builtin); ok {
		return x == y
	}
	return false
}

func (x *builtin) call(ctx *context, src source, args ...evaluated) (ret value) {
	if x.Func == nil {
		return ctx.mkErr(x, "Builtin %q is not a function", x.Name)
	}
	if len(x.Params) != len(args) {
		return ctx.mkErr(src, x, "number of arguments does not match (%d vs %d)",
			len(x.Params), len(args))
	}
	for i, a := range args {
		if x.Params[i] != bottomKind {
			if unifyType(x.Params[i], a.kind()) == bottomKind {
				return ctx.mkErr(src, x, "argument %d requires type %v, found %v", i+1, x.Params[i], a.kind())
			}
		}
	}
	call := callCtxt{src: src, ctx: ctx, args: args}
	defer func() {
		var errVal interface{} = call.err
		if err := recover(); err != nil {
			errVal = err
		}
		switch err := errVal.(type) {
		case nil:
		case *bottom:
			ret = err
		default:
			ret = ctx.mkErr(src, x, "call error: %v", err)
		}
	}()
	x.Func(&call)
	return convert(ctx, x, call.ret)
}

// callCtxt is passed to builtin implementations.
type callCtxt struct {
	src  source
	ctx  *context
	args []evaluated
	err  error
	ret  interface{}
}

var builtins map[string][]*builtin

func initBuiltins(pkgs map[string][]*builtin) {
	builtins = pkgs
	for k, b := range pkgs {
		builtins["-/"+path.Base(k)] = b
	}
}

func getBuiltinShorthandPkg(ctx *context, shorthand string) *structLit {
	return getBuiltinPkg(ctx, "-/"+shorthand)
}

func getBuiltinPkg(ctx *context, path string) *structLit {
	p, ok := builtins[path]
	if !ok {
		return nil
	}

	// TODO(perf): store in index

	obj := &structLit{}
	for _, b := range p {
		f := ctx.label(b.Name, false) // never starts with _
		// n := &node{baseValue: newBase(imp.Path)}
		obj.arcs = append(obj.arcs, arc{feature: f, v: b})
	}
	sort.Sort(obj)
	return obj
}

// do returns whether the call should be done.
func (c *callCtxt) do() bool {
	return c.err == nil
}

func (c *callCtxt) value(i int) Value {
	return newValueRoot(c.ctx, c.args[i])
}

func (c *callCtxt) int(i int) int     { return int(c.intValue(i, 64)) }
func (c *callCtxt) int8(i int) int8   { return int8(c.intValue(i, 8)) }
func (c *callCtxt) int16(i int) int16 { return int16(c.intValue(i, 16)) }
func (c *callCtxt) int32(i int) int32 { return int32(c.intValue(i, 32)) }
func (c *callCtxt) rune(i int) rune   { return rune(c.intValue(i, 32)) }
func (c *callCtxt) int64(i int) int64 { return int64(c.intValue(i, 64)) }

func (c *callCtxt) intValue(i, bits int) int64 {
	x := newValueRoot(c.ctx, c.args[i])
	n, err := x.Int(nil)
	if err != nil {
		c.err = c.ctx.mkErr(c.src, "argument %d must be in int, found number", i)
		return 0
	}
	if n.BitLen() > bits {
		c.err = c.ctx.mkErr(c.src, err, "argument %d out of range: has %d > %d bits", n.BitLen(), bits)
	}
	res, _ := x.Int64()
	return res
}

func (c *callCtxt) uint(i int) uint     { return uint(c.uintValue(i, 64)) }
func (c *callCtxt) uint8(i int) uint8   { return uint8(c.uintValue(i, 8)) }
func (c *callCtxt) byte(i int) uint8    { return byte(c.uintValue(i, 8)) }
func (c *callCtxt) uint16(i int) uint16 { return uint16(c.uintValue(i, 16)) }
func (c *callCtxt) uint32(i int) uint32 { return uint32(c.uintValue(i, 32)) }
func (c *callCtxt) uint64(i int) uint64 { return uint64(c.uintValue(i, 64)) }

func (c *callCtxt) uintValue(i, bits int) uint64 {
	x := newValueRoot(c.ctx, c.args[i])
	n, err := x.Int(nil)
	if err != nil {
		c.err = c.ctx.mkErr(c.src, "argument %d must be an integer", i)
		return 0
	}
	if n.Sign() < 0 {
		c.err = c.ctx.mkErr(c.src, "argument %d must be a positive integer", i)
		return 0
	}
	if n.BitLen() > bits {
		c.err = c.ctx.mkErr(c.src, err, "argument %d out of range: has %d > %d bits", i, n.BitLen(), bits)
	}
	res, _ := x.Uint64()
	return res
}

func (c *callCtxt) float64(i int) float64 {
	x := newValueRoot(c.ctx, c.args[i])
	res, err := x.Float64()
	if err != nil {
		c.err = c.ctx.mkErr(c.src, err, "invalid argument %d: %v", i, err)
		return 0
	}
	return res
}

func (c *callCtxt) bigInt(i int) *big.Int {
	x := newValueRoot(c.ctx, c.args[i])
	n, err := x.Int(nil)
	if err != nil {
		c.err = c.ctx.mkErr(c.src, "argument %d must be in int, found number", i)
		return nil
	}
	return n
}

func (c *callCtxt) bigFloat(i int) *big.Float {
	x := newValueRoot(c.ctx, c.args[i])
	var mant big.Int
	exp, err := x.MantExp(&mant)
	if err != nil {
		c.err = c.ctx.mkErr(c.src, err, "invalid argument %d: %v", i, err)
		return nil
	}
	f := &big.Float{}
	f.SetInt(&mant)
	if exp != 0 {
		var g big.Float
		e := big.NewInt(int64(exp))
		f.Mul(f, g.SetInt(e.Exp(ten, e, nil)))
	}
	return f
}

func (c *callCtxt) string(i int) string {
	x := newValueRoot(c.ctx, c.args[i])
	v, err := x.String()
	if err != nil {
		c.err = c.ctx.mkErr(c.src, err, "invalid argument %d: %v", i, err)
		return ""
	}
	return v
}

func (c *callCtxt) bytes(i int) []byte {
	x := newValueRoot(c.ctx, c.args[i])
	v, err := x.Bytes()
	if err != nil {
		c.err = c.ctx.mkErr(c.src, err, "invalid argument %d: %v", i, err)
		return nil
	}
	return v
}

func (c *callCtxt) reader(i int) io.Reader {
	x := newValueRoot(c.ctx, c.args[i])
	// TODO: optimize for string and bytes cases
	r, err := x.Reader()
	if err != nil {
		c.err = c.ctx.mkErr(c.src, err, "invalid argument %d: %v", i, err)
		return nil
	}
	return r
}

func (c *callCtxt) bool(i int) bool {
	x := newValueRoot(c.ctx, c.args[i])
	b, err := x.Bool()
	if err != nil {
		c.err = c.ctx.mkErr(c.src, err, "invalid argument %d: %v", i, err)
		return false
	}
	return b
}

func (c *callCtxt) error(i int) error {
	x := newValueRoot(c.ctx, c.args[i])
	return x.Err()
}

func (c *callCtxt) list(i int) (a Iterator) {
	x := newValueRoot(c.ctx, c.args[i])
	v, err := x.List()
	if err != nil {
		c.err = c.ctx.mkErr(c.src, err, "invalid argument %d: %v", i, err)
		return Iterator{ctx: c.ctx}
	}
	return v
}

func (c *callCtxt) strList(i int) (a []string) {
	x := newValueRoot(c.ctx, c.args[i])
	v, err := x.List()
	if err != nil {
		c.err = c.ctx.mkErr(c.src, err, "invalid argument %d: %v", i, err)
		return nil
	}
	for i := 0; v.Next(); i++ {
		str, err := v.Value().String()
		if err != nil {
			c.err = c.ctx.mkErr(c.src, err, "list element %d: %v", i, err)
		}
		a = append(a, str)
	}
	return a
}

// lookupBuiltinPkg returns the builtin package for the given path if it exists.
func lookupBuiltinPkg(ctx *context, imp *ast.ImportSpec) evaluated {
	path, err := strconv.Unquote(imp.Path.Value)
	if err != nil {
		return ctx.mkErr(newNode(imp), "illformed import spec")
	}

	p := getBuiltinPkg(ctx, path)
	if p == nil {
		return ctx.mkErr(newNode(imp), "package %q not found", path)
	}
	return p
}

func convert(ctx *context, src source, x interface{}) evaluated {
	switch v := x.(type) {
	case evaluated:
		return v
	case nil:
		return &nullLit{src.base()}
	case *Instance:
		return v.eval(ctx)
	case error:
		return ctx.mkErr(src, v.Error())
	case bool:
		return &boolLit{src.base(), v}
	case string:
		return &stringLit{src.base(), v}
	case []byte:
		return &bytesLit{src.base(), v}
	case int:
		return toInt(ctx, src, int64(v))
	case int8:
		return toInt(ctx, src, int64(v))
	case int16:
		return toInt(ctx, src, int64(v))
	case int32:
		return toInt(ctx, src, int64(v))
	case int64:
		return toInt(ctx, src, int64(v))
	case uint:
		return toUint(ctx, src, uint64(v))
	case uint8:
		return toUint(ctx, src, uint64(v))
	case uint16:
		return toUint(ctx, src, uint64(v))
	case uint32:
		return toUint(ctx, src, uint64(v))
	case uint64:
		return toUint(ctx, src, uint64(v))
	case float64:
		r := newNum(src, floatKind)
		r.v.SetString(fmt.Sprintf("%g", v))
		return r
	case *big.Int:
		n := newNum(src, intKind)
		n.v.Coeff.Set(v)
		if v.Sign() < 0 {
			n.v.Coeff.Neg(&n.v.Coeff)
			n.v.Negative = true
		}
		return n
	case *big.Rat:
		n := newNum(src, numKind)
		ctx.Quo(&n.v, apd.NewWithBigInt(v.Num(), 0), apd.NewWithBigInt(v.Denom(), 0))
		if !v.IsInt() {
			n.k = floatKind
		}
		return n
	case *big.Float:
		n := newNum(src, floatKind)
		n.v.SetString(v.String())
		return n
	case *apd.Decimal:
		n := newNum(src, floatKind|intKind)
		n.v.Set(v)
		if !n.isInt(ctx) {
			n.k = floatKind
		}
		return n
	case reflect.Value:
		if v.CanInterface() {
			return convert(ctx, src, v.Interface())
		}

	default:
		value := reflect.ValueOf(v)
		switch value.Kind() {
		case reflect.Ptr:
			if value.IsNil() {
				return &nullLit{src.base()}
			}
			return convert(ctx, src, value.Elem().Interface())
		case reflect.Struct:
			obj := newStruct(src)
			t := value.Type()
			for i := 0; i < value.NumField(); i++ {
				t := t.Field(i)
				if t.PkgPath != "" {
					continue
				}
				sub := convert(ctx, src, value.Field(i).Interface())
				// leave errors like we do during normal evaluation or do we
				// want to return the error?
				name := t.Name
				for _, s := range []string{"cue", "json", "protobuf"} {
					if tag, ok := t.Tag.Lookup(s); ok {
						if p := strings.Index(tag, ","); p >= 0 {
							tag = tag[:p]
						}
						if tag != "" {
							name = tag
							break
						}
					}
				}
				f := ctx.strLabel(name)
				obj.arcs = append(obj.arcs, arc{feature: f, v: sub})
			}
			sort.Sort(obj)
			return obj

		case reflect.Map:
			obj := newStruct(src)
			t := value.Type()
			if t.Key().Kind() != reflect.String {
				return ctx.mkErr(src, "builtin map key not a string, but unsupported type %s", t.Key().String())
			}
			keys := []string{}
			for _, k := range value.MapKeys() {
				keys = append(keys, k.String())
			}
			sort.Strings(keys)
			for _, k := range keys {
				sub := convert(ctx, src, value.MapIndex(reflect.ValueOf(k)).Interface())
				// leave errors like we do during normal evaluation or do we
				// want to return the error?
				f := ctx.strLabel(k)
				obj.arcs = append(obj.arcs, arc{feature: f, v: sub})
			}
			sort.Sort(obj)
			return obj

		case reflect.Slice, reflect.Array:
			list := &list{baseValue: src.base()}
			for i := 0; i < value.Len(); i++ {
				x := convert(ctx, src, value.Index(i).Interface())
				if isBottom(x) {
					return x
				}
				list.a = append(list.a, x)
			}
			list.initLit()
			// There is no need to set the type of the list, as the list will
			// be of fixed size and all elements will already have a defined
			// value.
			return list
		}
	}
	return ctx.mkErr(src, "builtin returned unsupported type %T", x)
}

func toInt(ctx *context, src source, x int64) evaluated {
	n := newNum(src, intKind)
	n.v.SetInt64(x)
	return n
}

func toUint(ctx *context, src source, x uint64) evaluated {
	n := newNum(src, floatKind)
	n.v.Coeff.SetUint64(x)
	return n
}
