package reflectutils

import "reflect"

// GroupTypeKind 将反射的Kind值进行聚集
func GroupTypeKind(t reflect.Type) reflect.Kind {
	kind := t.Kind()

	switch {
	case kind >= reflect.Int && kind <= reflect.Int64:
		return reflect.Int64
	case kind >= reflect.Uint && kind <= reflect.Uint64:
		return reflect.Uint64
	case kind >= reflect.Float32 && kind <= reflect.Float64:
		return reflect.Float64
	default:
		return kind
	}
}

func PointerTypeElem(t reflect.Type) reflect.Type {
	elem := t
	if t.Kind() == reflect.Ptr {
		elem = t.Elem()
	}

	return elem
}

func SliceTypeElem(t reflect.Type) reflect.Type {
	elem := t
	if t.Kind() == reflect.Slice {
		elem = t.Elem()
	}

	return elem
}

func IsSliceTypeOf(t reflect.Type, elementKind reflect.Kind) bool {
	return t.Kind() == reflect.Slice && t.Elem().Kind() == elementKind
}

func IsTypeInteger(t reflect.Type) bool {
	return t.Kind() >= reflect.Int && t.Kind() <= reflect.Int64
}

func IsTypeUnsignedInteger(t reflect.Type) bool {
	return t.Kind() >= reflect.Uint && t.Kind() <= reflect.Uint64
}

func IsTypeFloat(t reflect.Type) bool {
	return t.Kind() >= reflect.Float32 && t.Kind() <= reflect.Float64
}

func IsTypeStructPointer(t reflect.Type) bool {
	return t.Kind() == reflect.Pointer && t.Elem().Kind() == reflect.Struct
}

func IsTypeStructOrStructPointer(t reflect.Type) bool {
	return t.Kind() == reflect.Struct || IsTypeStructPointer(t)
}

func IsTypeStructSliceOrStructSlicePointer(t reflect.Type) bool {
	return IsSliceTypeOf(t, reflect.Struct) || (t.Kind() == reflect.Pointer && IsSliceTypeOf(t.Elem(), reflect.Struct))
}

func IsTypeTime(t reflect.Type) bool {
	return t.Kind() == reflect.Struct && t.String() == "time.Time"
}

func IsTypeTimePointer(t reflect.Type) bool {
	return t.Kind() == reflect.Pointer && IsTypeTime(t.Elem())
}