// 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 (
	"errors"
	"fmt"
	"reflect"
	"sync"
	"unsafe"
)

// rtCacheT is a map from reflect.Type to *Type.  The only instance is rtCache,
// which is a global cache to speed up repeated lookups.
//
// All locking is performed in TypeFromReflect.
type rtCacheT struct {
	sync.RWMutex
	rtmap map[reflect.Type]*Type
}

var (
	rtCache = &rtCacheT{
		rtmap: map[reflect.Type]*Type{
			// Ensure TypeOf(WireError{}) returns the built-in VDL error type.
			reflect.TypeOf(WireError{}): ErrorType.Elem(),
		},
	}
	rtCacheEnabled = true
)

func (reg *rtCacheT) lookup(rt reflect.Type) *Type {
	if !rtCacheEnabled {
		return nil
	}
	return reg.rtmap[rt]
}

func (reg *rtCacheT) update(pending map[reflect.Type]TypeOrPending) {
	if !rtCacheEnabled {
		return
	}
	for rt, top := range pending {
		t, _ := getBuiltType(top)
		reg.rtmap[rt] = t
	}
}

// getBuiltType returns the built type from top.
func getBuiltType(top TypeOrPending) (*Type, error) {
	switch ttop := top.(type) {
	case *Type:
		return ttop, nil
	case PendingType:
		return ttop.Built()
	}
	panic(fmt.Errorf("vdl: unknown type in TypeOrPending: %T %v", top, top))
}

// TypeOf returns the type corresponding to v.  It's a helper for calling
// TypeFromReflect, and panics on any errors.
func TypeOf(v interface{}) *Type {
	t, err := TypeFromReflect(reflect.TypeOf(v))
	if err != nil {
		panic(fmt.Errorf("vdl: can't take TypeOf(%T): %v", v, err))
	}
	return t
}

// Normalize the rt type.  The VDL type system Optional is represented as a Go
// pointer.  Only structs may be optional in VDL, but we still allow the pointer
// forms of other types in Go.  E.g. VDL doesn't allow ?map, but we do allow Go
// **map, and consider that to be a VDL map; the pointers are flattened away.
//
// In addition all Go interfaces are represented with the single Any type,
// except for Go interfaces that describe Union types.
//
// By normalizing the rt type we simplify type creation, and also reduce
// redundancy in the rtCache.
func normalizeType(rt reflect.Type) reflect.Type {
	// Flatten rt to no pointers, and rtAtMostOnePtr to at most one pointer.
	hasPtr := false
	for rt.Kind() == reflect.Ptr {
		if ni := nativeInfoFromNative(rt); ni != nil {
			if hasPtr {
				return normalizeType(reflect.PtrTo(ni.WireType))
			}
			return normalizeType(ni.WireType)
		}
		hasPtr = true
		rt = rt.Elem()
	}
	if ni := nativeInfoFromNative(rt); ni != nil {
		if hasPtr {
			return normalizeType(reflect.PtrTo(ni.WireType))
		}
		return normalizeType(ni.WireType)
	}
	rtAtMostOnePtr := rt
	if hasPtr {
		rtAtMostOnePtr = reflect.PtrTo(rt)
	}
	if rt.ConvertibleTo(rtError) || rtAtMostOnePtr.ConvertibleTo(rtError) {
		// TODO(bprosnitz) Remove this for new vdl error logic
		return rtError
	}
	if rt == rtWireError || rt == rtError {
		// Return if this is vdl.WireError or error because we want verror.E to be the
		// type stored in reflect info.
		// TODO(bprosnitz) Remove this special case.
		return rtAtMostOnePtr
	}
	// Handle special cases.  Union may be either an interface or a struct, and
	// should be handled first.
	if ri, _, _ := deriveReflectInfo(rt); ri != nil {
		if len(ri.UnionFields) > 0 {
			return rt
		}
		// Use the type defined in the reflect info.  Typically this is the same as
		// the original rt, but in some cases we use __VDLReflect to override the
		// vdl type.  E.g. vom.RawBytes claims that it is AnyType.
		rt = ri.Type
	}
	switch {
	case rt.Kind() == reflect.Interface:
		// Collapse all interfaces to interface{}
		return rtInterface
	case rt.Kind() == reflect.Struct && rt.PkgPath() != "":
		// Named structs may be optional, so we keep the pointer.
		return rtAtMostOnePtr
	}
	return rt
}

// basicType returns the *Type corresponding to rt for basic types that cannot
// be named by the user, and have a well-known conversion.
func basicType(rt reflect.Type) *Type {
	for rt.Kind() == reflect.Ptr {
		rt = rt.Elem()
	}
	switch rt {
	case rtError:
		// TODO(bprosnitz) Remove this for new vdl error logic
		return ErrorType
	case rtInterface, rtValue:
		return AnyType
	case rtType:
		return TypeObjectType
	}
	return nil
}

// TypeFromReflect returns the type corresponding to rt.  Not all reflect types
// have a valid type; reflect.Chan, reflect.Func and reflect.UnsafePointer are
// unsupported, as are maps with pointer keys, as well as structs with only
// unexported fields.
func TypeFromReflect(rt reflect.Type) (*Type, error) {
	if rt == nil {
		// Special case to avoid panic for nil rt.
		return AnyType, nil
	}
	// Fastpath - grab the reader lock and check if rt is already in the cache.
	if t := basicType(rt); t != nil {
		return t, nil
	}
	rtCache.RLock()
	t := rtCache.lookup(rt)
	rtCache.RUnlock()
	if t != nil {
		return t, nil
	}
	// Slowpath - first register rt and all subtypes, to ensure they're known.
	// This avoids some of the tricky ordering issues between vdl.Register and
	// vdl.TypeFromReflect, when they are called in init functions.
	if err := registerRecursive(rt); err != nil {
		return nil, err
	}
	// Slowpath - grab the writer lock.  We hold the lock even while building the
	// type, since TypeBuilder requires that if two types are identical, they must
	// be represented by the same Type or PendingType.  Here's an example:
	//   type Str string
	//   type Foo struct { A, B Str }
	//
	// If we built type Foo without the lock, we might end up with this ordering:
	//    thread_1 build Foo
	//    thread_1 build Foo.A
	//
	//    thread_2 build Foo
	//    thread_2 build Foo.A
	//    thread_2 build Foo.B
	//    thread_2 update map
	//
	//    thread_1 build Foo.B // type Str found in map, different from Foo.A
	//
	// The problem is that thread_1 now has two different representations of Str
	// in its TypeBuilder - it built type Str itself for Foo.A, and it found Str
	// from the map for Foo.B.  The TypeBuilder notices this inconsistency, and
	// returns an error.
	//
	// Side note: you might think there's a simpler fix; if each thread updated
	// the map (under the lock) as it built each type, we wouldn't need to lock
	// the entire type-building operation.  But note that TypeBuilder only returns
	// PendingType as types are being built, and only returns the final Type when
	// Build is called at the very end, in order to support cyclic types.
	rtCache.Lock()
	defer rtCache.Unlock()
	// The strategy is to recursively populate the builder with the type and
	// subtypes, keeping track of new types in pending.  After all types have been
	// populated, we build the types and update rtCache with all pending types.
	builder := new(TypeBuilder)
	pending := make(map[reflect.Type]TypeOrPending)
	result, err := typeFromReflectLocked(rt, builder, pending)
	if err != nil {
		return nil, err
	}
	builder.Build()
	built, err := getBuiltType(result)
	if built == nil {
		// There must have been an error building one of the types.  Return the
		// first error we find, favoring errors from building the result itself.
		if err != nil {
			return nil, err
		}
		for _, top := range pending {
			_, err := getBuiltType(top)
			if err != nil {
				return nil, err
			}
		}
		panic(fmt.Errorf("vdl: inconsistent results from TypeBuilder.Build: %v", pending))
	}
	rtCache.update(pending)
	return built, nil
}

// typeFromReflectLocked returns the Type or PendingType corresponding to rt.
// It either returns the type directly from the cache or pending map, or makes
// the type based on rt.
//
// REQUIRES: rtCache is locked
func typeFromReflectLocked(rt reflect.Type, builder *TypeBuilder, pending map[reflect.Type]TypeOrPending) (TypeOrPending, error) {
	rtOrig := rt
	rt = normalizeType(rt)
	if t := basicType(rt); t != nil {
		pending[rtOrig] = t
		return t, nil
	}
	if t := rtCache.lookup(rt); t != nil {
		pending[rtOrig] = t
		return t, nil
	}
	if p, ok := pending[rt]; ok {
		// If the type is already in our pending map, we return it now.  This breaks
		// infinite loops from recursive types.
		return p, nil
	}
	return makeTypeFromReflectLocked(rtOrig, rt, builder, pending)
}

// validateType returns a non-nil error if rt is not a valid vdl type.
func validateType(rt reflect.Type) error {
	// Flatten pointers to simplify the checks.
	for rt.Kind() == reflect.Ptr {
		rt = rt.Elem()
	}
	// Now check error conditions.
	if rt == rtReflectValue {
		return errTypeFromReflectValue
	}
	switch rt.Kind() {
	case reflect.Chan, reflect.Func, reflect.UnsafePointer:
		return fmt.Errorf("reflect type %q not supported", rt)
	}
	return nil
}

// makeTypeFromReflectLocked makes the Type or PendingType corresponding to rt.
// Calls typeFromReflect to recursively generate subtypes.
//
// REQUIRES: rtCache is locked
// PRE-CONDITION:  rt doesn't exist in rtCache or pending.
// POST-CONDITION: rt exists in pending.
func makeTypeFromReflectLocked(rtOrig, rt reflect.Type, builder *TypeBuilder, pending map[reflect.Type]TypeOrPending) (TypeOrPending, error) {
	if err := validateType(rt); err != nil {
		return nil, err
	}
	if rt.Kind() == reflect.Ptr {
		// Pointers are turned into Optional.
		opt := builder.Optional()
		pending[rt] = opt
		pending[rtOrig] = opt
		elem, err := typeFromReflectLocked(rt.Elem(), builder, pending)
		if err != nil {
			return nil, err
		}
		opt.AssignElem(elem)
		return opt, nil
	}
	ri, _, err := deriveReflectInfo(rt)
	if err != nil {
		return nil, err
	}
	if ri.Name == "" {
		// Unnamed types are made directly.  There's no way to create a recursive
		// type based solely on unnamed types, so it's ok to to update pending
		// *after* making the unnamed type.
		unnamed, err := makeUnnamedFromReflectLocked(ri, builder, pending)
		if err != nil {
			return nil, err
		}
		pending[ri.Type] = unnamed
		pending[rtOrig] = unnamed
		return unnamed, nil
	}
	// Named types are trickier, since they may be recursive.  First create the
	// named type and add it to pending.  We must special-case union types; the
	// interface type and all field types are keyed in the pending map to point to
	// the created vdl type.
	named := builder.Named(ri.Name)
	pending[ri.Type] = named
	pending[rtOrig] = named
	for _, unionField := range ri.UnionFields {
		pending[unionField.RepType] = named
	}
	// Now make the unnamed underlying type.  Recursive types will find the
	// existing entry in pending, and avoid the infinite loop.
	unnamed, err := makeUnnamedFromReflectLocked(ri, builder, pending)
	if err != nil {
		return nil, err
	}
	// Finally assign the base type and we're done.
	named.AssignBase(unnamed)
	return named, nil
}

// makeUnnamedFromReflectLocked makes the underlying unnamed Type or PendingType
// corresponding to ri.
//
// REQUIRES: rtCache is locked
func makeUnnamedFromReflectLocked(ri *reflectInfo, builder *TypeBuilder, pending map[reflect.Type]TypeOrPending) (TypeOrPending, error) {
	// Handle enum types
	if len(ri.EnumLabels) > 0 {
		enum := builder.Enum()
		for _, label := range ri.EnumLabels {
			enum.AppendLabel(label)
		}
		return enum, nil
	}
	// Handle union types
	if len(ri.UnionFields) > 0 {
		union := builder.Union()
		for _, f := range ri.UnionFields {
			in, err := typeFromReflectLocked(f.Type, builder, pending)
			if err != nil {
				return nil, err
			}
			union.AppendField(f.Name, in)
		}
		return union, nil
	}
	// Handle composite types
	rt := ri.Type
	switch rt.Kind() {
	case reflect.Array:
		elem, err := typeFromReflectLocked(rt.Elem(), builder, pending)
		if err != nil {
			return nil, err
		}
		return builder.Array().AssignLen(rt.Len()).AssignElem(elem), nil
	case reflect.Slice:
		elem, err := typeFromReflectLocked(rt.Elem(), builder, pending)
		if err != nil {
			return nil, err
		}
		return builder.List().AssignElem(elem), nil
	case reflect.Map:
		if rt.Key().Kind() == reflect.Ptr {
			return nil, fmt.Errorf("invalid key %q in %q", rt.Key(), rt)
		}
		key, err := typeFromReflectLocked(rt.Key(), builder, pending)
		if err != nil {
			return nil, err
		}
		if rt.Elem() == rtUnnamedEmptyStruct {
			// The map actually represents a set
			return builder.Set().AssignKey(key), nil
		}
		elem, err := typeFromReflectLocked(rt.Elem(), builder, pending)
		if err != nil {
			return nil, err
		}
		return builder.Map().AssignKey(key).AssignElem(elem), nil
	case reflect.Struct:
		st := builder.Struct()
		for fx := 0; fx < rt.NumField(); fx++ {
			// TODO(toddw): How should we handle anonymous (aka embedded) fields?
			// Note that unexported embedded fields may themselves have exported
			// fields.  See https://github.com/golang/go/issues/12367
			rtField := rt.Field(fx)
			if rtField.PkgPath != "" {
				continue // field isn't exported
			}
			field, err := typeFromReflectLocked(rtField.Type, builder, pending)
			if err != nil {
				return nil, err
			}
			st.AppendField(rtField.Name, field)
		}
		if rt.NumField() > 0 && st.NumField() == 0 {
			return nil, fmt.Errorf("type %q only has unexported fields", rt)
		}
		return st, nil
	}
	// Handle scalar types
	if t := typeFromRTKind[rt.Kind()]; t != nil {
		return t, nil
	}
	panic(fmt.Errorf("vdl: makeUnnamedFromReflectLocked unhandled %v %v", rt.Kind(), rt))
}

var (
	errTypeFromReflectValue = errors.New("invalid vdl.TypeOf(reflect.Value{})")

	rtInterface          = reflect.TypeOf((*interface{})(nil)).Elem()
	rtBool               = reflect.TypeOf(false)
	rtByte               = reflect.TypeOf(byte(0))
	rtByteList           = reflect.TypeOf([]byte(nil))
	rtUint16             = reflect.TypeOf(uint16(0))
	rtUint32             = reflect.TypeOf(uint32(0))
	rtUint64             = reflect.TypeOf(uint64(0))
	rtInt8               = reflect.TypeOf(int8(0))
	rtInt16              = reflect.TypeOf(int16(0))
	rtInt32              = reflect.TypeOf(int32(0))
	rtInt64              = reflect.TypeOf(int64(0))
	rtFloat32            = reflect.TypeOf(float32(0))
	rtFloat64            = reflect.TypeOf(float64(0))
	rtString             = reflect.TypeOf("")
	rtError              = reflect.TypeOf((*error)(nil)).Elem()
	rtWireError          = reflect.TypeOf(WireError{})
	rtType               = reflect.TypeOf(Type{})
	rtValue              = reflect.TypeOf(Value{})
	rtPtrToType          = reflect.TypeOf((*Type)(nil))
	rtPtrToValue         = reflect.TypeOf((*Value)(nil))
	rtReflectValue       = reflect.TypeOf(reflect.Value{})
	rtTargeter           = reflect.TypeOf((*Targeter)(nil)).Elem()
	rtNamer              = reflect.TypeOf((*namer)(nil)).Elem()
	rtIndexer            = reflect.TypeOf((*indexer)(nil)).Elem()
	rtIsZeroer           = reflect.TypeOf((*IsZeroer)(nil)).Elem()
	rtUnnamedEmptyStruct = reflect.TypeOf(struct{}{})

	typeFromRTKind = [...]*Type{
		reflect.Bool:    BoolType,
		reflect.Uint8:   ByteType,
		reflect.Uint16:  Uint16Type,
		reflect.Uint32:  Uint32Type,
		reflect.Uint64:  Uint64Type,
		reflect.Uint:    uintType(8 * unsafe.Sizeof(uint(0))),
		reflect.Uintptr: uintType(8 * unsafe.Sizeof(uintptr(0))),
		reflect.Int8:    Int8Type,
		reflect.Int16:   Int16Type,
		reflect.Int32:   Int32Type,
		reflect.Int64:   Int64Type,
		reflect.Int:     intType(8 * unsafe.Sizeof(int(0))),
		reflect.Float32: Float32Type,
		reflect.Float64: Float64Type,
		reflect.String:  StringType,
	}
)

func uintType(bitlen uintptr) *Type {
	switch bitlen {
	case 32:
		return Uint32Type
	default:
		return Uint64Type
	}
}

func intType(bitlen uintptr) *Type {
	switch bitlen {
	case 32:
		return Int32Type
	default:
		return Int64Type
	}
}
