package utils

import (
	"bytes"
	"encoding/gob"
	"encoding/json"
	"errors"
	"fmt"
	"gitlab.fjmaimaimai.com/mmm-go/gocomm/pkg/log"
	"reflect"
	"strings"
)

// 此函数将指定的结构体成员值更新到结构体中
func SetStructValueByType(s interface{}, columnType string, columnValue interface{}) error {
	columnValueV := reflect.ValueOf(columnValue)
	var setValue reflect.Value
	var flag = false
	v := reflect.ValueOf(s)
	for i, n := 0, v.Elem().NumField(); i < n; i++ {
		if v.Elem().Type().Field(i).Name == columnType {
			setValue = v.Elem().Field(i)
			flag = true
			break
		}
	}
	if !flag {
		return errors.New("struct is not type:")
	} else if !setValue.CanSet() {
		return errors.New("setValue.CanSet is false")
	} else if setValue.Kind() != columnValueV.Kind() {
		return errors.New("struct field and value of type is error")
	}
	switch columnValueV.Kind() {
	case reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int, reflect.Int64:
		setValue.SetInt(int64(columnValueV.Int()))
	case reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
		setValue.SetUint(uint64(columnValueV.Uint()))
	case reflect.Float32, reflect.Float64:
		setValue.SetFloat(float64(columnValueV.Float()))
	case reflect.String:
		setValue.SetString(columnValueV.String())
	case reflect.Struct:
		setValue.Set(columnValueV)
	default:
		return errors.New("columnValue err for:" + columnType)
	}
	return nil
}

func JoinInts(ids []int, spilt string) string {
	var idStrings []string = make([]string, len(ids))
	for i := 0; i < len(ids); i++ {
		idStrings[i] = fmt.Sprintf("%v", ids[i])
	}
	return strings.Join(idStrings, spilt)
}
func JoinInt8s(ids []int8, spilt string) string {
	var idStrings []string = make([]string, len(ids))
	for i := 0; i < len(ids); i++ {
		idStrings[i] = fmt.Sprintf("%v", ids[i])
	}
	return strings.Join(idStrings, spilt)
}
func JoinInt64s(ids []int64, spilt string) string {
	var idStrings []string = make([]string, len(ids))
	for i := 0; i < len(ids); i++ {
		idStrings[i] = fmt.Sprintf("%v", ids[i])
	}
	return strings.Join(idStrings, spilt)
}

//判断是否为空
func IsNil(i interface{}) bool {
	vi := reflect.ValueOf(i)
	if vi.Kind() == reflect.Ptr {
		return vi.IsNil()
	}
	return false
}

func JsonUnmarshal(jsonData string, v interface{}) {
	if len(jsonData) == 0 {
		return
	}
	if e := json.Unmarshal([]byte(jsonData), v); e != nil {
		log.Error("json.unmarshal error data:", jsonData, e)
	}
}

//深度拷贝
func DeepCopy(dst, src interface{}) error {
	var buf bytes.Buffer
	if err := gob.NewEncoder(&buf).Encode(src); err != nil {
		return err
	}
	return gob.NewDecoder(&buf).Decode(dst)
}