package zerochecker

import (
	
	
)

var driverValuerType = reflect.TypeOf((*driver.Valuer)(nil)).Elem()
var appenderType = reflect.TypeOf((*valueAppender)(nil)).Elem()
var isZeroerType = reflect.TypeOf((*isZeroer)(nil)).Elem()

type isZeroer interface {
	IsZero() bool
}

type valueAppender interface {
	AppendValue(b []byte, flags int) ([]byte, error)
}

type Func func(reflect.Value) bool

func ( reflect.Type) Func {
	if .Implements(isZeroerType) {
		return isZeroInterface
	}

	switch .Kind() {
	case reflect.Array:
		if .Elem().Kind() == reflect.Uint8 {
			return isZeroBytes
		}
		return isZeroLen
	case reflect.String:
		return isZeroLen
	case reflect.Bool:
		return isZeroBool
	case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
		return isZeroInt
	case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
		return isZeroUint
	case reflect.Float32, reflect.Float64:
		return isZeroFloat
	case reflect.Interface, reflect.Ptr, reflect.Slice, reflect.Map:
		return isNil
	}

	if .Implements(appenderType) {
		return isZeroAppenderValue
	}
	if .Implements(driverValuerType) {
		return isZeroDriverValue
	}

	return isZeroFalse
}

func ( reflect.Value) bool {
	if .Kind() == reflect.Ptr && .IsNil() {
		return true
	}
	return .Interface().(isZeroer).IsZero()
}

func ( reflect.Value) bool {
	if .Kind() == reflect.Ptr {
		return .IsNil()
	}

	 := .Interface().(valueAppender)
	,  := .AppendValue(nil, 0)
	if  != nil {
		return false
	}
	return  == nil
}

func ( reflect.Value) bool {
	if .Kind() == reflect.Ptr {
		return .IsNil()
	}

	 := .Interface().(driver.Valuer)
	,  := .Value()
	if  != nil {
		return false
	}
	return  == nil
}

func ( reflect.Value) bool {
	return .Len() == 0
}

func ( reflect.Value) bool {
	return .IsNil()
}

func ( reflect.Value) bool {
	return !.Bool()
}

func ( reflect.Value) bool {
	return .Int() == 0
}

func ( reflect.Value) bool {
	return .Uint() == 0
}

func ( reflect.Value) bool {
	return .Float() == 0
}

func ( reflect.Value) bool {
	 := .Slice(0, .Len()).Bytes()
	for ,  := range  {
		if  != 0 {
			return false
		}
	}
	return true
}

func ( reflect.Value) bool {
	return false
}