package reflect2

import (
	"github.com/modern-go/concurrent"
	"reflect"
	"unsafe"
)

type Type interface {
	Kind() reflect.Kind
	// New return pointer to data of this type
	New() interface{}
	// UnsafeNew return the allocated space pointed by unsafe.Pointer
	UnsafeNew() unsafe.Pointer
	// PackEFace cast a unsafe pointer to object represented pointer
	PackEFace(ptr unsafe.Pointer) interface{}
	// Indirect dereference object represented pointer to this type
	Indirect(obj interface{}) interface{}
	// UnsafeIndirect dereference pointer to this type
	UnsafeIndirect(ptr unsafe.Pointer) interface{}
	// Type1 returns reflect.Type
	Type1() reflect.Type
	Implements(thatType Type) bool
	String() string
	RType() uintptr
	// interface{} of this type has pointer like behavior
	LikePtr() bool
	IsNullable() bool
	IsNil(obj interface{}) bool
	UnsafeIsNil(ptr unsafe.Pointer) bool
	Set(obj interface{}, val interface{})
	UnsafeSet(ptr unsafe.Pointer, val unsafe.Pointer)
	AssignableTo(anotherType Type) bool
}

type ListType interface {
	Type
	Elem() Type
	SetIndex(obj interface{}, index int, elem interface{})
	UnsafeSetIndex(obj unsafe.Pointer, index int, elem unsafe.Pointer)
	GetIndex(obj interface{}, index int) interface{}
	UnsafeGetIndex(obj unsafe.Pointer, index int) unsafe.Pointer
}

type ArrayType interface {
	ListType
	Len() int
}

type SliceType interface {
	ListType
	MakeSlice(length int, cap int) interface{}
	UnsafeMakeSlice(length int, cap int) unsafe.Pointer
	Grow(obj interface{}, newLength int)
	UnsafeGrow(ptr unsafe.Pointer, newLength int)
	Append(obj interface{}, elem interface{})
	UnsafeAppend(obj unsafe.Pointer, elem unsafe.Pointer)
	LengthOf(obj interface{}) int
	UnsafeLengthOf(ptr unsafe.Pointer) int
	SetNil(obj interface{})
	UnsafeSetNil(ptr unsafe.Pointer)
	Cap(obj interface{}) int
	UnsafeCap(ptr unsafe.Pointer) int
}

type StructType interface {
	Type
	NumField() int
	Field(i int) StructField
	FieldByName(name string) StructField
	FieldByIndex(index []int) StructField
	FieldByNameFunc(match func(string) bool) StructField
}

type StructField interface {
	Offset() uintptr
	Name() string
	PkgPath() string
	Type() Type
	Tag() reflect.StructTag
	Index() []int
	Anonymous() bool
	Set(obj interface{}, value interface{})
	UnsafeSet(obj unsafe.Pointer, value unsafe.Pointer)
	Get(obj interface{}) interface{}
	UnsafeGet(obj unsafe.Pointer) unsafe.Pointer
}

type MapType interface {
	Type
	Key() Type
	Elem() Type
	MakeMap(cap int) interface{}
	UnsafeMakeMap(cap int) unsafe.Pointer
	SetIndex(obj interface{}, key interface{}, elem interface{})
	UnsafeSetIndex(obj unsafe.Pointer, key unsafe.Pointer, elem unsafe.Pointer)
	TryGetIndex(obj interface{}, key interface{}) (interface{}, bool)
	GetIndex(obj interface{}, key interface{}) interface{}
	UnsafeGetIndex(obj unsafe.Pointer, key unsafe.Pointer) unsafe.Pointer
	Iterate(obj interface{}) MapIterator
	UnsafeIterate(obj unsafe.Pointer) MapIterator
}

type MapIterator interface {
	HasNext() bool
	Next() (key interface{}, elem interface{})
	UnsafeNext() (key unsafe.Pointer, elem unsafe.Pointer)
}

type PtrType interface {
	Type
	Elem() Type
}

type InterfaceType interface {
	NumMethod() int
}

type Config struct {
	UseSafeImplementation bool
}

type API interface {
	TypeOf(obj interface{}) Type
	Type2(type1 reflect.Type) Type
}

var ConfigUnsafe = Config{UseSafeImplementation: false}.Froze()
var ConfigSafe = Config{UseSafeImplementation: true}.Froze()

type frozenConfig struct {
	useSafeImplementation bool
	cache                 *concurrent.Map
}

func (cfg Config) Froze() *frozenConfig {
	return &frozenConfig{
		useSafeImplementation: cfg.UseSafeImplementation,
		cache: concurrent.NewMap(),
	}
}

func (cfg *frozenConfig) TypeOf(obj interface{}) Type {
	cacheKey := uintptr(unpackEFace(obj).rtype)
	typeObj, found := cfg.cache.Load(cacheKey)
	if found {
		return typeObj.(Type)
	}
	return cfg.Type2(reflect.TypeOf(obj))
}

func (cfg *frozenConfig) Type2(type1 reflect.Type) Type {
	if type1 == nil {
		return nil
	}
	cacheKey := uintptr(unpackEFace(type1).data)
	typeObj, found := cfg.cache.Load(cacheKey)
	if found {
		return typeObj.(Type)
	}
	type2 := cfg.wrapType(type1)
	cfg.cache.Store(cacheKey, type2)
	return type2
}

func (cfg *frozenConfig) wrapType(type1 reflect.Type) Type {
	safeType := safeType{Type: type1, cfg: cfg}
	switch type1.Kind() {
	case reflect.Struct:
		if cfg.useSafeImplementation {
			return &safeStructType{safeType}
		}
		return newUnsafeStructType(cfg, type1)
	case reflect.Array:
		if cfg.useSafeImplementation {
			return &safeSliceType{safeType}
		}
		return newUnsafeArrayType(cfg, type1)
	case reflect.Slice:
		if cfg.useSafeImplementation {
			return &safeSliceType{safeType}
		}
		return newUnsafeSliceType(cfg, type1)
	case reflect.Map:
		if cfg.useSafeImplementation {
			return &safeMapType{safeType}
		}
		return newUnsafeMapType(cfg, type1)
	case reflect.Ptr, reflect.Chan, reflect.Func:
		if cfg.useSafeImplementation {
			return &safeMapType{safeType}
		}
		return newUnsafePtrType(cfg, type1)
	case reflect.Interface:
		if cfg.useSafeImplementation {
			return &safeMapType{safeType}
		}
		if type1.NumMethod() == 0 {
			return newUnsafeEFaceType(cfg, type1)
		}
		return newUnsafeIFaceType(cfg, type1)
	default:
		if cfg.useSafeImplementation {
			return &safeType
		}
		return newUnsafeType(cfg, type1)
	}
}

func TypeOf(obj interface{}) Type {
	return ConfigUnsafe.TypeOf(obj)
}

func TypeOfPtr(obj interface{}) PtrType {
	return TypeOf(obj).(PtrType)
}

func Type2(type1 reflect.Type) Type {
	if type1 == nil {
		return nil
	}
	return ConfigUnsafe.Type2(type1)
}

func PtrTo(typ Type) Type {
	return Type2(reflect.PtrTo(typ.Type1()))
}

func PtrOf(obj interface{}) unsafe.Pointer {
	return unpackEFace(obj).data
}

func RTypeOf(obj interface{}) uintptr {
	return uintptr(unpackEFace(obj).rtype)
}

func IsNil(obj interface{}) bool {
	if obj == nil {
		return true
	}
	return unpackEFace(obj).data == nil
}

func IsNullable(kind reflect.Kind) bool {
	switch kind {
	case reflect.Ptr, reflect.Map, reflect.Chan, reflect.Func, reflect.Slice, reflect.Interface:
		return true
	}
	return false
}

func likePtrKind(kind reflect.Kind) bool {
	switch kind {
	case reflect.Ptr, reflect.Map, reflect.Chan, reflect.Func:
		return true
	}
	return false
}

func likePtrType(typ reflect.Type) bool {
	if likePtrKind(typ.Kind()) {
		return true
	}
	if typ.Kind() == reflect.Struct {
		if typ.NumField() != 1 {
			return false
		}
		return likePtrType(typ.Field(0).Type)
	}
	if typ.Kind() == reflect.Array {
		if typ.Len() != 1 {
			return false
		}
		return likePtrType(typ.Elem())
	}
	return false
}

// NoEscape hides a pointer from escape analysis.  noescape is
// the identity function but escape analysis doesn't think the
// output depends on the input.  noescape is inlined and currently
// compiles down to zero instructions.
// USE CAREFULLY!
//go:nosplit
func NoEscape(p unsafe.Pointer) unsafe.Pointer {
	x := uintptr(p)
	return unsafe.Pointer(x ^ 0)
}

func UnsafeCastString(str string) []byte {
	stringHeader := (*reflect.StringHeader)(unsafe.Pointer(&str))
	sliceHeader := &reflect.SliceHeader{
		Data: stringHeader.Data,
		Cap: stringHeader.Len,
		Len: stringHeader.Len,
	}
	return *(*[]byte)(unsafe.Pointer(sliceHeader))
}
