// Copyright 2019 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 convert allows converting to and from Go values and Types.
package convert

import (
	"encoding"
	"encoding/json"
	"fmt"
	"math/big"
	"reflect"
	"sort"
	"strconv"
	"strings"
	"unicode/utf8"

	"github.com/cockroachdb/apd/v2"

	"cuelang.org/go/cue/ast"
	"cuelang.org/go/cue/ast/astutil"
	"cuelang.org/go/cue/errors"
	"cuelang.org/go/cue/parser"
	"cuelang.org/go/cue/token"
	"cuelang.org/go/internal"
	"cuelang.org/go/internal/core/adt"
	"cuelang.org/go/internal/core/compile"
	"cuelang.org/go/internal/core/runtime"
)

// This file contains functionality for converting Go to CUE.
//
// The code in this file is a prototype implementation and is far from
// optimized.

func GoValueToValue(ctx *adt.OpContext, x interface{}, nilIsTop bool) adt.Value {
	v := GoValueToExpr(ctx, nilIsTop, x)
	// TODO: return Value
	return toValue(v)
}

func GoTypeToExpr(ctx *adt.OpContext, x interface{}) (adt.Expr, errors.Error) {
	v := convertGoType(ctx, reflect.TypeOf(x))
	if err := ctx.Err(); err != nil {
		return v, err.Err
	}
	return v, nil
}

func toValue(e adt.Expr) adt.Value {
	if v, ok := e.(adt.Value); ok {
		return v
	}
	obj := &adt.Vertex{}
	obj.AddConjunct(adt.MakeRootConjunct(nil, e))
	return obj
}

func compileExpr(ctx *adt.OpContext, expr ast.Expr) adt.Value {
	c, err := compile.Expr(nil, ctx, pkgID(), expr)
	if err != nil {
		return &adt.Bottom{Err: errors.Promote(err, "compile")}
	}
	return adt.Resolve(ctx, c)
}

// parseTag parses a CUE expression from a cue tag.
func parseTag(ctx *adt.OpContext, obj *ast.StructLit, field, tag string) ast.Expr {
	if p := strings.Index(tag, ","); p >= 0 {
		tag = tag[:p]
	}
	if tag == "" {
		return topSentinel
	}
	expr, err := parser.ParseExpr("<field:>", tag)
	if err != nil {
		err := errors.Promote(err, "parser")
		ctx.AddErr(errors.Wrapf(err, ctx.Pos(),
			"invalid tag %q for field %q", tag, field))
		return &ast.BadExpr{}
	}
	return expr
}

// TODO: should we allow mapping names in cue tags? This only seems like a good
// idea if we ever want to allow mapping CUE to a different name than JSON.
var tagsWithNames = []string{"json", "yaml", "protobuf"}

func getName(f *reflect.StructField) string {
	name := f.Name
	for _, s := range tagsWithNames {
		if tag, ok := f.Tag.Lookup(s); ok {
			if p := strings.Index(tag, ","); p >= 0 {
				tag = tag[:p]
			}
			if tag != "" {
				name = tag
				break
			}
		}
	}
	return name
}

// isOptional indicates whether a field should be marked as optional.
func isOptional(f *reflect.StructField) bool {
	isOptional := false
	switch f.Type.Kind() {
	case reflect.Ptr, reflect.Map, reflect.Chan, reflect.Interface, reflect.Slice:
		// Note: it may be confusing to distinguish between an empty slice and
		// a nil slice. However, it is also surprising to not be able to specify
		// a default value for a slice. So for now we will allow it.
		isOptional = true
	}
	if tag, ok := f.Tag.Lookup("cue"); ok {
		// TODO: only if first field is not empty.
		isOptional = false
		for _, f := range strings.Split(tag, ",")[1:] {
			switch f {
			case "opt":
				isOptional = true
			case "req":
				return false
			}
		}
	} else if tag, ok = f.Tag.Lookup("json"); ok {
		isOptional = false
		for _, f := range strings.Split(tag, ",")[1:] {
			if f == "omitempty" {
				return true
			}
		}
	}
	return isOptional
}

// isOmitEmpty means that the zero value is interpreted as undefined.
func isOmitEmpty(f *reflect.StructField) bool {
	isOmitEmpty := false
	switch f.Type.Kind() {
	case reflect.Ptr, reflect.Map, reflect.Chan, reflect.Interface, reflect.Slice:
		// Note: it may be confusing to distinguish between an empty slice and
		// a nil slice. However, it is also surprising to not be able to specify
		// a default value for a slice. So for now we will allow it.
		isOmitEmpty = true

	default:
		// TODO: we can also infer omit empty if a type cannot be nil if there
		// is a constraint that unconditionally disallows the zero value.
	}
	tag, ok := f.Tag.Lookup("json")
	if ok {
		isOmitEmpty = false
		for _, f := range strings.Split(tag, ",")[1:] {
			if f == "omitempty" {
				return true
			}
		}
	}
	return isOmitEmpty
}

// parseJSON parses JSON into a CUE value. b must be valid JSON.
func parseJSON(ctx *adt.OpContext, b []byte) adt.Value {
	expr, err := parser.ParseExpr("json", b)
	if err != nil {
		panic(err) // cannot happen
	}
	return compileExpr(ctx, expr)
}

func isZero(v reflect.Value) bool {
	x := v.Interface()
	if x == nil {
		return true
	}
	switch k := v.Kind(); k {
	case reflect.Struct, reflect.Array:
		// we never allow optional values for these types.
		return false

	case reflect.Chan, reflect.Func, reflect.Interface, reflect.Map,
		reflect.Slice:
		// Note that for maps we preserve the distinction between a nil map and
		// an empty map.
		return v.IsNil()

	case reflect.String:
		return v.Len() == 0

	default:
		return x == reflect.Zero(v.Type()).Interface()
	}
}

func GoValueToExpr(ctx *adt.OpContext, nilIsTop bool, x interface{}) adt.Expr {
	e := convertRec(ctx, nilIsTop, x)
	if e == nil {
		return ctx.AddErrf("unsupported Go type (%v)", e)
	}
	return e
}

func isNil(x reflect.Value) bool {
	switch x.Kind() {
	// Only check for supported types; ignore func and chan.
	case reflect.Ptr, reflect.Map, reflect.Slice, reflect.Interface:
		return x.IsNil()
	}
	return false
}

func convertRec(ctx *adt.OpContext, nilIsTop bool, x interface{}) adt.Value {
	if internal.CoreValue != nil {
		if ii, iv := internal.CoreValue(x); ii != nil {
			i := ii.(*runtime.Runtime)
			v := iv.(*adt.Vertex)
			// TODO: panic if nto the same runtime.
			_ = i
			return v
		}
	}
	src := ctx.Source()
	switch v := x.(type) {
	case nil:
		if nilIsTop {
			ident, _ := ctx.Source().(*ast.Ident)
			return &adt.Top{Src: ident}
		}
		return &adt.Null{Src: ctx.Source()}

	case *ast.File:
		x, err := compile.Files(nil, ctx, pkgID(), v)
		if err != nil {
			return &adt.Bottom{Err: errors.Promote(err, "compile")}
		}
		if len(x.Conjuncts) != 1 {
			panic("unexpected length")
		}
		return x

	case ast.Expr:
		return compileExpr(ctx, v)

	case *big.Int:
		return &adt.Num{Src: src, K: adt.IntKind, X: *apd.NewWithBigInt(v, 0)}

	case *big.Rat:
		// should we represent this as a binary operation?
		n := &adt.Num{Src: src, K: adt.IntKind}
		_, err := apd.BaseContext.Quo(&n.X, apd.NewWithBigInt(v.Num(), 0), apd.NewWithBigInt(v.Denom(), 0))
		if err != nil {
			return ctx.AddErrf("could not convert *big.Rat: %v", err)
		}
		if !v.IsInt() {
			n.K = adt.FloatKind
		}
		return n

	case *big.Float:
		n := &adt.Num{Src: src, K: adt.FloatKind}
		_, _, err := n.X.SetString(v.String())
		ctx.AddErr(errors.Promote(err, "invalid float"))
		return n

	case *apd.Decimal:
		// TODO: should we allow an "int" bit to be set here? It is a bit
		// tricky, as we would also need to pass down the result of rounding.
		// So more likely an API must return explicitly whether a value is
		// a float or an int after all.
		// The code to autodetect whether something is an integer can be done
		// with this:
		// var d apd.Decimal
		// res, _ := apd.BaseContext.RoundToIntegralExact(&d, v)
		// integer := !res.Inexact()
		n := &adt.Num{Src: ctx.Source(), K: adt.FloatKind}
		n.X = *v
		return n

	case json.Marshaler:
		b, err := v.MarshalJSON()
		if err != nil {
			return ctx.AddErr(errors.Promote(err, "json.Marshaler"))
		}

		return parseJSON(ctx, b)

	case encoding.TextMarshaler:
		b, err := v.MarshalText()
		if err != nil {
			return ctx.AddErr(errors.Promote(err, "encoding.TextMarshaler"))
		}
		b, err = json.Marshal(string(b))
		if err != nil {
			return ctx.AddErr(errors.Promote(err, "json"))
		}
		return parseJSON(ctx, b)

	case error:
		var errs errors.Error
		switch x := v.(type) {
		case errors.Error:
			errs = x
		default:
			errs = ctx.Newf("%s", x.Error())
		}
		return &adt.Bottom{Err: errs}
	case bool:
		return &adt.Bool{Src: ctx.Source(), B: v}
	case string:
		if !utf8.ValidString(v) {
			return ctx.AddErrf("cannot convert result to string: invalid UTF-8")
		}
		return &adt.String{Src: ctx.Source(), Str: v}
	case []byte:
		return &adt.Bytes{Src: ctx.Source(), B: v}
	case int:
		return toInt(ctx, int64(v))
	case int8:
		return toInt(ctx, int64(v))
	case int16:
		return toInt(ctx, int64(v))
	case int32:
		return toInt(ctx, int64(v))
	case int64:
		return toInt(ctx, int64(v))
	case uint:
		return toUint(ctx, uint64(v))
	case uint8:
		return toUint(ctx, uint64(v))
	case uint16:
		return toUint(ctx, uint64(v))
	case uint32:
		return toUint(ctx, uint64(v))
	case uint64:
		return toUint(ctx, uint64(v))
	case uintptr:
		return toUint(ctx, uint64(v))
	case float64:
		n := &adt.Num{Src: src, K: adt.FloatKind}
		_, _, err := n.X.SetString(fmt.Sprintf("%g", v))
		ctx.AddErr(errors.Promote(err, "invalid float"))
		return n
	case float32:
		n := &adt.Num{Src: src, K: adt.FloatKind}
		_, _, err := n.X.SetString(fmt.Sprintf("%g", v))
		ctx.AddErr(errors.Promote(err, "invalid float"))
		return n

	case reflect.Value:
		if v.CanInterface() {
			return convertRec(ctx, nilIsTop, v.Interface())
		}

	default:
		value := reflect.ValueOf(v)
		switch value.Kind() {
		case reflect.Bool:
			return &adt.Bool{Src: ctx.Source(), B: value.Bool()}

		case reflect.String:
			str := value.String()
			if !utf8.ValidString(str) {
				return ctx.AddErrf("cannot convert result to string: invalid UTF-8")
			}
			return &adt.String{Src: ctx.Source(), Str: str}

		case reflect.Int, reflect.Int8, reflect.Int16,
			reflect.Int32, reflect.Int64:
			return toInt(ctx, value.Int())

		case reflect.Uint, reflect.Uint8, reflect.Uint16,
			reflect.Uint32, reflect.Uint64, reflect.Uintptr:
			return toUint(ctx, value.Uint())

		case reflect.Float32, reflect.Float64:
			return convertRec(ctx, nilIsTop, value.Float())

		case reflect.Ptr:
			if value.IsNil() {
				if nilIsTop {
					ident, _ := ctx.Source().(*ast.Ident)
					return &adt.Top{Src: ident}
				}
				return &adt.Null{Src: ctx.Source()}
			}
			return convertRec(ctx, nilIsTop, value.Elem().Interface())

		case reflect.Struct:
			obj := &adt.StructLit{Src: src}
			v := &adt.Vertex{}
			v.AddConjunct(adt.MakeRootConjunct(nil, obj))
			v.SetValue(ctx, adt.Finalized, &adt.StructMarker{})

			t := value.Type()
			for i := 0; i < value.NumField(); i++ {
				t := t.Field(i)
				if t.PkgPath != "" {
					continue
				}
				val := value.Field(i)
				if !nilIsTop && isNil(val) {
					continue
				}
				if tag, _ := t.Tag.Lookup("json"); tag == "-" {
					continue
				}
				if isOmitEmpty(&t) && isZero(val) {
					continue
				}
				sub := convertRec(ctx, nilIsTop, val.Interface())
				if sub == nil {
					// mimic behavior of encoding/json: skip fields of unsupported types
					continue
				}
				if _, ok := sub.(*adt.Bottom); ok {
					return sub
				}

				// leave errors like we do during normal evaluation or do we
				// want to return the error?
				name := getName(&t)
				if name == "-" {
					continue
				}
				f := ctx.StringLabel(name)
				obj.Decls = append(obj.Decls, &adt.Field{Label: f, Value: sub})
				arc, ok := sub.(*adt.Vertex)
				if ok {
					arc.Label = f
				} else {
					arc = &adt.Vertex{Label: f, Value: sub}
					arc.AddConjunct(adt.MakeRootConjunct(nil, sub))
				}
				v.Arcs = append(v.Arcs, arc)
			}

			return v

		case reflect.Map:
			obj := &adt.StructLit{Src: src}
			v := &adt.Vertex{Value: &adt.StructMarker{}}
			v.AddConjunct(adt.MakeRootConjunct(nil, obj))
			v.SetValue(ctx, adt.Finalized, &adt.StructMarker{})

			t := value.Type()
			switch key := t.Key(); key.Kind() {
			case reflect.String,
				reflect.Int, reflect.Int8, reflect.Int16,
				reflect.Int32, reflect.Int64,
				reflect.Uint, reflect.Uint8, reflect.Uint16,
				reflect.Uint32, reflect.Uint64, reflect.Uintptr:
				keys := value.MapKeys()
				sort.Slice(keys, func(i, j int) bool {
					return fmt.Sprint(keys[i]) < fmt.Sprint(keys[j])
				})
				for _, k := range keys {
					val := value.MapIndex(k)
					// if isNil(val) {
					// 	continue
					// }

					sub := convertRec(ctx, nilIsTop, val.Interface())
					// mimic behavior of encoding/json: report error of
					// unsupported type.
					if sub == nil {
						return ctx.AddErrf("unsupported Go type (%v)", val)
					}
					if isBottom(sub) {
						return sub
					}

					s := fmt.Sprint(k)
					f := ctx.StringLabel(s)
					obj.Decls = append(obj.Decls, &adt.Field{
						Label: f,
						Value: sub,
					})
					arc, ok := sub.(*adt.Vertex)
					if ok {
						arc.Label = f
					} else {
						arc = &adt.Vertex{Label: f, Value: sub}
						arc.AddConjunct(adt.MakeRootConjunct(nil, sub))
					}
					v.Arcs = append(v.Arcs, arc)
				}

			default:
				return ctx.AddErrf("unsupported Go type for map key (%v)", key)
			}

			return v

		case reflect.Slice, reflect.Array:
			var values []adt.Value

			for i := 0; i < value.Len(); i++ {
				val := value.Index(i)
				x := convertRec(ctx, nilIsTop, val.Interface())
				if x == nil {
					return ctx.AddErrf("unsupported Go type (%v)", val)
				}
				if isBottom(x) {
					return x
				}
				values = append(values, x)
			}

			return ctx.NewList(values...)
		}
	}
	return nil
}

func toInt(ctx *adt.OpContext, x int64) adt.Value {
	n := &adt.Num{Src: ctx.Source(), K: adt.IntKind}
	n.X = *apd.New(x, 0)
	return n
}

func toUint(ctx *adt.OpContext, x uint64) adt.Value {
	n := &adt.Num{Src: ctx.Source(), K: adt.IntKind}
	n.X.Coeff.SetUint64(x)
	return n
}

func convertGoType(ctx *adt.OpContext, t reflect.Type) adt.Expr {
	// TODO: this can be much more efficient.
	// TODO: synchronize
	return goTypeToValue(ctx, true, t)
}

var (
	jsonMarshaler = reflect.TypeOf(new(json.Marshaler)).Elem()
	textMarshaler = reflect.TypeOf(new(encoding.TextMarshaler)).Elem()
	topSentinel   = ast.NewIdent("_")
)

// goTypeToValue converts a Go Type to a value.
//
// TODO: if this value will always be unified with a concrete type in Go, then
// many of the fields may be omitted.
func goTypeToValue(ctx *adt.OpContext, allowNullDefault bool, t reflect.Type) adt.Expr {
	if _, t, ok := ctx.LoadType(t); ok {
		return t
	}

	_, v := goTypeToValueRec(ctx, allowNullDefault, t)
	if v == nil {
		return ctx.AddErrf("unsupported Go type (%v)", t)
	}
	return v
}

func goTypeToValueRec(ctx *adt.OpContext, allowNullDefault bool, t reflect.Type) (e ast.Expr, expr adt.Expr) {
	if src, t, ok := ctx.LoadType(t); ok {
		return src, t
	}

	switch reflect.Zero(t).Interface().(type) {
	case *big.Int, big.Int:
		e = ast.NewIdent("int")
		goto store

	case *big.Float, big.Float, *big.Rat, big.Rat:
		e = ast.NewIdent("number")
		goto store

	case *apd.Decimal, apd.Decimal:
		e = ast.NewIdent("number")
		goto store
	}

	// Even if this is for types that we know cast to a certain type, it can't
	// hurt to return top, as in these cases the concrete values will be
	// strict instances and there cannot be any tags that further constrain
	// the values.
	if t.Implements(jsonMarshaler) || t.Implements(textMarshaler) {
		return topSentinel, nil
	}

	switch k := t.Kind(); k {
	case reflect.Ptr:
		elem := t.Elem()
		for elem.Kind() == reflect.Ptr {
			elem = elem.Elem()
		}
		e, _ = goTypeToValueRec(ctx, false, elem)
		if allowNullDefault {
			e = wrapOrNull(e)
		}

	case reflect.Interface:
		switch t.Name() {
		case "error":
			// This is really null | _|_. There is no error if the error is null.
			e = ast.NewNull()
		default:
			e = topSentinel // `_`
		}

	case reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64,
		reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
		e = compile.LookupRange(t.Kind().String()).Source().(ast.Expr)

	case reflect.Uint, reflect.Uintptr:
		e = compile.LookupRange("uint64").Source().(ast.Expr)

	case reflect.Int:
		e = compile.LookupRange("int64").Source().(ast.Expr)

	case reflect.String:
		e = ast.NewIdent("__string")

	case reflect.Bool:
		e = ast.NewIdent("__bool")

	case reflect.Float32, reflect.Float64:
		e = ast.NewIdent("__number")

	case reflect.Struct:
		obj := &ast.StructLit{}

		// TODO: dirty trick: set this to a temporary Vertex and then update the
		// arcs and conjuncts of this vertex below. This will allow circular
		// references. Maybe have a special kind of "hardlink" reference.
		ctx.StoreType(t, obj, nil)

		for i := 0; i < t.NumField(); i++ {
			f := t.Field(i)
			if f.PkgPath != "" {
				continue
			}
			_, ok := f.Tag.Lookup("cue")
			elem, _ := goTypeToValueRec(ctx, !ok, f.Type)
			if isBad(elem) {
				continue // Ignore fields for unsupported types
			}

			// leave errors like we do during normal evaluation or do we
			// want to return the error?
			name := getName(&f)
			if name == "-" {
				continue
			}

			if tag, ok := f.Tag.Lookup("cue"); ok {
				v := parseTag(ctx, obj, name, tag)
				if isBad(v) {
					return v, nil
				}
				elem = ast.NewBinExpr(token.AND, elem, v)
			}
			// TODO: if an identifier starts with __ (or otherwise is not a
			// valid CUE name), make it a string and create a map to a new
			// name for references.

			// The GO JSON decoder always allows a value to be undefined.
			d := &ast.Field{Label: ast.NewIdent(name), Value: elem}
			if isOptional(&f) {
				d.Optional = token.Blank.Pos()
			}
			obj.Elts = append(obj.Elts, d)
		}

		// TODO: should we validate references here? Can be done using
		// astutil.ToFile and astutil.Resolve.

		e = obj

	case reflect.Array, reflect.Slice:
		if t.Elem().Kind() == reflect.Uint8 {
			e = ast.NewIdent("__bytes")
		} else {
			elem, _ := goTypeToValueRec(ctx, allowNullDefault, t.Elem())
			if elem == nil {
				b := ctx.AddErrf("unsupported Go type (%v)", t.Elem())
				return &ast.BadExpr{}, b
			}

			if t.Kind() == reflect.Array {
				e = ast.NewBinExpr(token.MUL,
					ast.NewLit(token.INT, strconv.Itoa(t.Len())),
					ast.NewList(elem))
			} else {
				e = ast.NewList(&ast.Ellipsis{Type: elem})
			}
		}
		if k == reflect.Slice {
			e = wrapOrNull(e)
		}

	case reflect.Map:
		switch key := t.Key(); key.Kind() {
		case reflect.String, reflect.Int, reflect.Int8, reflect.Int16,
			reflect.Int32, reflect.Int64, reflect.Uint, reflect.Uint8,
			reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
		default:
			b := ctx.AddErrf("unsupported Go type for map key (%v)", key)
			return &ast.BadExpr{}, b
		}

		v, x := goTypeToValueRec(ctx, allowNullDefault, t.Elem())
		if v == nil {
			b := ctx.AddErrf("unsupported Go type (%v)", t.Elem())
			return &ast.BadExpr{}, b
		}
		if isBad(v) {
			return v, x
		}

		e = ast.NewStruct(&ast.Field{
			Label: ast.NewList(ast.NewIdent("__string")),
			Value: v,
		})

		e = wrapOrNull(e)
	}

store:
	// TODO: store error if not nil?
	if e != nil {
		f := &ast.File{Decls: []ast.Decl{&ast.EmbedDecl{Expr: e}}}
		astutil.Resolve(f, func(_ token.Pos, msg string, args ...interface{}) {
			ctx.AddErrf(msg, args...)
		})
		var x adt.Expr
		c, err := compile.Expr(nil, ctx, pkgID(), e)
		if err != nil {
			b := &adt.Bottom{Err: err}
			ctx.AddBottom(b)
			x = b
		} else {
			x = c.Expr()
		}
		ctx.StoreType(t, e, x)
		return e, x
	}
	return e, nil
}

func isBottom(x adt.Node) bool {
	if x == nil {
		return true
	}
	b, _ := x.(*adt.Bottom)
	return b != nil
}

func isBad(x ast.Expr) bool {
	if x == nil {
		return true
	}
	if bad, _ := x.(*ast.BadExpr); bad != nil {
		return true
	}
	return false
}

func wrapOrNull(e ast.Expr) ast.Expr {
	switch x := e.(type) {
	case *ast.BasicLit:
		if x.Kind == token.NULL {
			return x
		}
	case *ast.BadExpr:
		return e
	}
	return makeNullable(e, true)
}

func makeNullable(e ast.Expr, nullIsDefault bool) ast.Expr {
	var null ast.Expr = ast.NewNull()
	if nullIsDefault {
		null = &ast.UnaryExpr{Op: token.MUL, X: null}
	}
	return ast.NewBinExpr(token.OR, null, e)
}

// pkgID returns a package path that can never resolve to an existing package.
func pkgID() string {
	return "_"
}
