// Copyright 2015 The Vanadium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package vdl

import (
	"fmt"
	"reflect"
	"sync"
	"unsafe"
)

const (
	// IEEE 754 represents float64 using 52 bits to represent the mantissa, with
	// an extra implied leading bit.  That gives us 53 bits to store integers
	// without overflow - i.e. [0, (2^53)-1].  And since 2^53 is a small power of
	// two, it can also be stored without loss via mantissa=1 exponent=53.  Thus
	// we have our max and min values.  Ditto for float32, which uses 23 bits with
	// an extra implied leading bit.
	float64MaxInt = (1 << 53)
	float64MinInt = -(1 << 53)
	float32MaxInt = (1 << 24)
	float32MinInt = -(1 << 24)
)

var (
	bitlenReflect = [...]uintptr{
		reflect.Uint8:   8,
		reflect.Uint16:  16,
		reflect.Uint32:  32,
		reflect.Uint64:  64,
		reflect.Uint:    8 * unsafe.Sizeof(uint(0)),
		reflect.Uintptr: 8 * unsafe.Sizeof(uintptr(0)),
		reflect.Int8:    8,
		reflect.Int16:   16,
		reflect.Int32:   32,
		reflect.Int64:   64,
		reflect.Int:     8 * unsafe.Sizeof(int(0)),
		reflect.Float32: 32,
		reflect.Float64: 64,
	}

	bitlenVDL = [...]uintptr{
		Byte:    8,
		Uint16:  16,
		Uint32:  32,
		Uint64:  64,
		Int8:    8,
		Int16:   16,
		Int32:   32,
		Int64:   64,
		Float32: 32,
		Float64: 64,
	}
)

// bitlen{R,V} enforce static type safety on kind.
func bitlenR(kind reflect.Kind) uintptr { return bitlenReflect[kind] }
func bitlenV(kind Kind) uintptr         { return bitlenVDL[kind] }

// isRTBytes returns true iff rt is an array or slice of bytes.
func isRTBytes(rt reflect.Type) bool {
	return (rt.Kind() == reflect.Array || rt.Kind() == reflect.Slice) && rt.Elem().Kind() == reflect.Uint8
}

// rtBytes extracts []byte from rv.  Assumes isRTBytes(rv.Type()) == true.
func rtBytes(rv reflect.Value) []byte {
	// Fastpath if the underlying type is []byte
	if rv.Kind() == reflect.Slice && rv.Type().Elem() == rtByte {
		return rv.Bytes()
	}
	// Slowpath copying bytes one by one.
	ret := make([]byte, rv.Len())
	for ix := 0; ix < rv.Len(); ix++ {
		ret[ix] = rv.Index(ix).Convert(rtByte).Interface().(byte)
	}
	return ret
}

// IsZeroer is the interface that wraps the VDLIsZero method.
//
// VDLIsZero returns true iff the receiver that implements this method is the
// VDL zero value.
type IsZeroer interface {
	VDLIsZero() bool
}

type stringer interface {
	String() string
}
type namer interface {
	Name() string
}
type indexer interface {
	Index() int
}

// rvFlattenPointers repeatedly dereferences pointers, creating new values if
// the pointer is nil, and returns the final non-pointer reflect value.  As a
// special-case, *Type is returned as a pointer.
func rvFlattenPointers(rv reflect.Value) reflect.Value {
	for rv.Kind() == reflect.Ptr {
		if rv.Type() == rtPtrToType {
			// Special-case to stop at *Type, which is filled in via readNonReflect by
			// the reader, or by rvZeroValue.
			return rv
		}
		if rv.IsNil() {
			rv.Set(reflect.New(rv.Type().Elem()))
		}
		rv = rv.Elem()
	}
	return rv
}

// zeroDecoder is a decoder that only returns zero values.
type zeroDecoder struct{ tt *Type }

func (z zeroDecoder) StartValue(want *Type) error {
	if !Compatible(z.tt, want) {
		return fmt.Errorf("vdl: zero incompatible decode from %v into %v", z.tt, want)
	}
	return nil
}
func (z zeroDecoder) FinishValue() error         { return nil }
func (z zeroDecoder) SkipValue() error           { return nil }
func (z zeroDecoder) IgnoreNextStartValue()      {}
func (z zeroDecoder) NextEntry() (bool, error)   { return true, nil }
func (z zeroDecoder) NextField() (string, error) { return "", nil }
func (z zeroDecoder) Type() *Type                { return z.tt }
func (z zeroDecoder) IsAny() bool                { return z.tt == AnyType }
func (z zeroDecoder) IsOptional() bool           { return z.tt.Kind() == Optional }
func (z zeroDecoder) IsNil() bool                { return z.IsAny() || z.IsOptional() }
func (z zeroDecoder) Index() int                 { return 0 }
func (z zeroDecoder) LenHint() int               { return 0 }

func (z zeroDecoder) DecodeBool() (bool, error)        { return false, nil }
func (z zeroDecoder) DecodeString() (string, error)    { return "", nil }
func (z zeroDecoder) DecodeUint(int) (uint64, error)   { return 0, nil }
func (z zeroDecoder) DecodeInt(int) (int64, error)     { return 0, nil }
func (z zeroDecoder) DecodeFloat(int) (float64, error) { return 0, nil }
func (z zeroDecoder) DecodeTypeObject() (*Type, error) { return AnyType, nil }
func (z zeroDecoder) DecodeBytes(fixedLen int, x *[]byte) error {
	if fixedLen >= 0 {
		for i := 0; i < fixedLen; i++ {
			(*x)[i] = 0
		}
	} else {
		*x = nil
	}
	return nil
}

func (z zeroDecoder) ReadValueBool() (bool, error)               { return false, nil }
func (z zeroDecoder) ReadValueString() (string, error)           { return "", nil }
func (z zeroDecoder) ReadValueUint(bitlen int) (uint64, error)   { return 0, nil }
func (z zeroDecoder) ReadValueInt(bitlen int) (int64, error)     { return 0, nil }
func (z zeroDecoder) ReadValueFloat(bitlen int) (float64, error) { return 0, nil }
func (z zeroDecoder) ReadValueTypeObject() (*Type, error)        { return AnyType, nil }
func (z zeroDecoder) ReadValueBytes(fixedLen int, x *[]byte) error {
	return z.DecodeBytes(fixedLen, x)
}

func (z zeroDecoder) NextEntryValueBool() (bool, bool, error)               { return true, false, nil }
func (z zeroDecoder) NextEntryValueString() (bool, string, error)           { return true, "", nil }
func (z zeroDecoder) NextEntryValueUint(bitlen int) (bool, uint64, error)   { return true, 0, nil }
func (z zeroDecoder) NextEntryValueInt(bitlen int) (bool, int64, error)     { return true, 0, nil }
func (z zeroDecoder) NextEntryValueFloat(bitlen int) (bool, float64, error) { return true, 0, nil }
func (z zeroDecoder) NextEntryValueTypeObject() (bool, *Type, error)        { return true, nil, nil }

var (
	rvAnyType               = reflect.ValueOf(AnyType)
	kkZeroValueNotCanonical = []Kind{Any, TypeObject, Union}
	kkZeroValueNotUnique    = []Kind{Any, TypeObject, Union, List, Set, Map}
)

// rvZeroValue returns the zero value of rt, using the vdl zero rules.
//
// VDL and Go define zero values differently.  According to VDL:
//    Any:        nil
//    TypeObject: AnyType
//    Union:      zero value of the type at index 0
// The Go zero value isn't always right.  Here are the Go zero values:
//    Any:        interface{}(nil), *vom.RawBytes(nil) or *vdl.Value(nil)
//    TypeObject: (*Type)(nil)
//    Union:      UnionInterface(nil)
// Here are the Go values we actually want:
//    Any:        *vom.RawBytes or *vdl.Value representing any(nil)
//    TypeObject: AnyType
//    Union:      UnionStruct0
//
// Thus we must special-case values of these types, or any types that contain
// these types inline.  I.e. if an array, struct, or union contains one of these
// types, it will show up in the zero value, and needs special-casing.
//
// TODO(toddw): Cache the generated zero values, if it's too expensive to
// generate them each time.
func rvZeroValue(rt reflect.Type, tt *Type) (reflect.Value, error) {
	// Easy fastpath; if the type doesn't contain the hard types inline, the
	// regular Go zero value is sufficient.
	if !tt.ContainsKind(WalkInline, kkZeroValueNotCanonical...) {
		return reflect.Zero(rt), nil
	}
	// Create the result we'll return.
	result := reflect.New(rt).Elem()
	// Flatten pointers and check for fast non-reflect support.  We re-use the
	// readNonReflect logic with a decoder that only produces zero values.  This
	// handles vom.RawBytes/vdl.Value, as well as TypeObject.
	rv := rvFlattenPointers(result)
	rt = rv.Type()
	if err := readNonReflect(zeroDecoder{tt}, false, rv.Addr().Interface()); err != errReadMustReflect {
		return result, err
	}
	// The only representation left for Any types is nil interfaces
	if tt == AnyType && rt.Kind() == reflect.Interface {
		return result, nil
	}
	// Handle native types by returning the native value filled in with a zero
	// value of the wire type.
	if ni := nativeInfoFromNative(rt); ni != nil {
		rvWire := reflect.New(ni.WireType).Elem()
		ttWire, err := TypeFromReflect(ni.WireType)
		if err != nil {
			return reflect.Value{}, err
		}
		switch zero, err := rvZeroValue(ni.WireType, ttWire); {
		case err != nil:
			return reflect.Value{}, err
		default:
			rvWire.Set(zero)
		}
		if err := ni.ToNative(rvWire, rv.Addr()); err != nil {
			return reflect.Value{}, err
		}
		return result, nil
	}
	// Handle composite types with inline subtypes.
	switch {
	case tt.Kind() == Union && rt.Kind() == reflect.Interface:
		// Set the union interface with the zero value of the type at index 0.
		ri, _, err := deriveReflectInfo(rt)
		if err != nil {
			return reflect.Value{}, err
		}
		rvFieldStruct := reflect.New(ri.UnionFields[0].RepType).Elem()
		switch zero, err := rvZeroValue(rvFieldStruct.Field(0).Type(), tt.Field(0).Type); {
		case err != nil:
			return reflect.Value{}, err
		default:
			rvFieldStruct.Field(0).Set(zero)
			rv.Set(rvFieldStruct)
		}
	case tt.Kind() == Array && rt.Kind() == reflect.Array:
		for ix := 0; ix < rt.Len(); ix++ {
			switch zero, err := rvZeroValue(rt.Elem(), tt.Elem()); {
			case err != nil:
				return reflect.Value{}, err
			default:
				rv.Index(ix).Set(zero)
			}
		}
	case tt.Kind() == Struct && rt.Kind() == reflect.Struct:
		for ix := 0; ix < tt.NumField(); ix++ {
			field := tt.Field(ix)
			rvField := rv.Field(rtFieldIndexByName(rt, field.Name))
			switch zero, err := rvZeroValue(rvField.Type(), field.Type); {
			case err != nil:
				return reflect.Value{}, err
			default:
				rvField.Set(zero)
			}
		}
	default:
		return reflect.Value{}, fmt.Errorf("vdl: rvZeroValue unhandled rt: %v tt: %v", rt, tt)
	}
	return result, nil
}

// rvIsZeroValue returns true iff rv represents the VDL zero value.  Here are
// the types with multiple VDL zero value representations:
//   Any:            nil, or VDLIsZero on vdl.Value/vom.RawBytes
//   TypeObject:     nil, or AnyType
//   Union:          nil, or zero value of field 0
//   List, Set, Map: nil, or empty
func rvIsZeroValue(rv reflect.Value, tt *Type) (bool, error) {
	// Walk pointers and interfaces, and handle nil values.
	for rv.Kind() == reflect.Ptr || rv.Kind() == reflect.Interface {
		if rv.IsNil() {
			// All nil pointers and nil interfaces are considered to be zero.  Note
			// that we may have a non-optional type that happens to be represented by
			// a pointer; technically nil might be considered an error, but it's
			// easier for the user (and for us) to treat it as zero.
			return true, nil
		}
		rv = rv.Elem()
	}
	// Optional types can only be zero via a nil pointer or interface.
	if tt.Kind() == Optional {
		return false, nil
	}
	rt := rv.Type()
	// Now we know that rv isn't a pointer or interface, and also isn't nil.  Call
	// VDLIsZero if it exists.  This handles the vdl.Value/vom.RawBytes cases, as
	// well generated code and user-implemented VDLIsZero methods.
	if rt.Implements(rtIsZeroer) {
		return rv.Interface().(IsZeroer).VDLIsZero(), nil
	}
	if reflect.PtrTo(rt).Implements(rtIsZeroer) {
		if rv.CanAddr() {
			return rv.Addr().Interface().(IsZeroer).VDLIsZero(), nil
		}
		// Handle the harder case where *T implements IsZeroer, but we can't take
		// the address of rv to turn it into *T.  Create a new *T value and fill it
		// in with rv, so that we can call VDLIsZero.  This is conceptually similar
		// to storing rv in a temporary variable, so that we can take the address.
		rvPtr := reflect.New(rt)
		rvPtr.Elem().Set(rv)
		return rvPtr.Interface().(IsZeroer).VDLIsZero(), nil
	}
	// Handle native types, by converting and checking the wire value for zero.
	if ni := nativeInfoFromNative(rt); ni != nil {
		rvWirePtr := reflect.New(ni.WireType)
		if err := ni.FromNative(rvWirePtr, rv); err != nil {
			return false, err
		}
		return rvIsZeroValue(rvWirePtr.Elem(), tt)
	}
	// The interface form of any was handled above in the nil checks, while the
	// non-interface forms were handled via VDLIsZero.
	if tt.Kind() == Optional || tt.Kind() == Any {
		return false, nil
	}
	// TODO(toddw): We could consider adding a "fastpath" here to check against
	// the go zero value, or the zero value created by rvZeroValue, and possibly
	// returning early.  This is tricky though; we can't use this fastpath if rt
	// contains any native types, but the only way to know whether rt contains any
	// native types is to look through the entire type, which might actually be
	// slower than the benefit of this "fastpath".  The cases where it'll help are
	// large arrays or structs.
	//
	// Handle all reflect cases.
	switch rv.Kind() {
	case reflect.Bool:
		return !rv.Bool(), nil
	case reflect.String:
		return rv.String() == "", nil
	case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
		return rv.Int() == 0, nil
	case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
		return rv.Uint() == 0, nil
	case reflect.Float32, reflect.Float64:
		return rv.Float() == 0, nil
	case reflect.Complex64, reflect.Complex128:
		return rv.Complex() == 0, nil
	case reflect.UnsafePointer:
		return rv.Pointer() == 0, nil
	case reflect.Slice, reflect.Map:
		return rv.Len() == 0, nil
	case reflect.Array:
		for ix := 0; ix < rv.Len(); ix++ {
			if z, err := rvIsZeroValue(rv.Index(ix), tt.Elem()); err != nil || !z {
				return false, err
			}
		}
		return true, nil
	case reflect.Struct:
		switch tt.Kind() {
		case Struct:
			for ix := 0; ix < tt.NumField(); ix++ {
				ttField := tt.Field(ix)
				rvField := rv.Field(rtFieldIndexByName(rt, ttField.Name))
				if z, err := rvIsZeroValue(rvField, ttField.Type); err != nil || !z {
					return false, err
				}
			}
			return true, nil
		case Union:
			// We already handled the nil union interface case above in the regular
			// pointer/interface walking.  Here we check to make sure the union field
			// struct represents field 0, and is set to its zero value.
			//
			// TypeFromReflect already validated Index(); call without error checking.
			if index := rv.Interface().(indexer).Index(); index != 0 {
				return false, nil
			}
			return rvIsZeroValue(rv.Field(0), tt.Field(0).Type)
		}
	}
	return false, fmt.Errorf("vdl: rvIsZeroValue unhandled rt: %v tt: %v", rt, tt)
}

// rtFieldIndexByName returns the index of the struct field in rt with the given
// name.  Returns -1 if the field doesn't exist.
//
// This function is purely a performance optimization; the current
// implementation of reflect.Type.Field(index) causes an allocation, which is
// avoided in the common case by caching the result.
//
// REQUIRES: rt.Kind() == reflect.Struct
func rtFieldIndexByName(rt reflect.Type, name string) int {
	rtFieldCache.RLock()
	m, ok := rtFieldCache.Map[rt]
	rtFieldCache.RUnlock()
	// Fastpath cache hit.
	if ok {
		return m[name] - 1
	}
	// Slowpath cache miss, populate the cache.
	rtFieldCache.Lock()
	defer rtFieldCache.Unlock()
	// Handle benign race, where the cache was filled in while we upgraded from a
	// reader lock to an exclusive lock.
	if m, ok := rtFieldCache.Map[rt]; ok {
		return m[name] - 1
	}
	if numField := rt.NumField(); numField > 0 {
		m = make(map[string]int, numField)
		for i := 0; i < numField; i++ {
			m[rt.Field(i).Name] = i + 1
		}
	}
	rtFieldCache.Map[rt] = m
	return m[name] - 1
}

var rtFieldCache = &rtFieldCacheType{
	Map: make(map[reflect.Type]map[string]int),
}

type rtFieldCacheType struct {
	sync.RWMutex
	Map map[reflect.Type]map[string]int
}
