package utils

import (
	"fmt"
	"io"
	"log"
	"mime/multipart"
	"os"
	"reflect"
	"strconv"
	"strings"
	"time"
)

const (
	rolePrefix string = "role_"
)

// 将结构体内所有string类型字段去除首位空格
// sp为结构体指针, s为结构体值
func TrimStruct(sp interface{}, s interface{}) {
	// 判断类型是否为struct
	av := reflect.ValueOf(sp)
	avv := reflect.ValueOf(s)
	at := reflect.TypeOf(s)
	// 简单判断下
	if at.Kind() != reflect.Struct {
		log.Printf("s must be a struct")
		return
	}
	av = reflect.ValueOf(av.Interface())
	for i := 0; i < avv.NumField(); i++ {
		if at.Field(i).Type.Name() == "string" {
			f := av.Elem().Field(i)
			val := strings.TrimSpace(avv.Field(i).String())
			f.Set(reflect.ValueOf(val))
		}

	}

	return
}

//
func FmtRolePrefix(sub interface{}) string {
	var s string
	switch sub.(type) {
	case int64:
		uid := sub.(int64)
		s = strconv.FormatInt(uid, 10)
	case string:
		s = sub.(string)
	}
	return fmt.Sprintf("%s%s", rolePrefix, s)
}

// timestamp to time
func StampToTime(st int64) time.Time {
	return time.Unix(st / 1000, 0)
}

func IdsStrToIdsIntGroup(keys string) []int {
	IDS := make([]int, 0)
	ids := strings.Split(keys, ",")
	for i := 0; i < len(ids); i++ {
		ID:= ValueToInt(ids[i],0)
		IDS = append(IDS, ID)
	}
	return IDS
}

func IDsToStringIn(ids []int) string {
	ll := len(ids)
	var str string
	for i := 0; i < ll; i++ {
		if i > 0 {
			str = str + "," + ValueToString(ids[i], "")
		} else {
			str = ValueToString(ids[i], "")
		}
	}
	return str
}

func IDsToStrings(ids []string) string {
	ll := len(ids)
	var str string
	for i := 0; i < ll; i++ {
		if i > 0 {
			str = str + "','" + ValueToString(ids[i], "")
		} else {
			str = "'" + ValueToString(ids[i], "")
		}
	}
	if len(str) > 0 {
		str = str + "'"
	}
	return str
}

// SaveUploadedFile uploads the form file to specific dst.
func SaveUploadedFile(file *multipart.FileHeader, dst string) error {
	src, err := file.Open()
	if err != nil {
		return err
	}
	defer src.Close()

	out, err := os.Create(dst)
	if err != nil {
		return err
	}
	defer out.Close()

	_, err = io.Copy(out, src)
	return err
}

func MakeOrderSn(key string) string {
	// 转大写
	key = strings.ToUpper(key)

	// 获取时间戳
	ts := time.Now().Format("20060102150405.000")
	tss := fmt.Sprint(time.Now().UnixNano())
	ts = string([]byte(ts)[0:14]) + string([]byte(tss)[13:16])

	return key + ts
}
//判断字符串是否在一个数组里
func IsContain(items []string, item string) bool {
	for _, eachItem := range items {
		if eachItem == item {
			return true
		}
	}
	return false
}
// 是否是文件 不是文件也不一定是目录
func IsFile(path string) bool {
	s, err := os.Stat(path)
	if err != nil {
		return false
	}
	return !s.IsDir()
}

//求并集
func Union(slice1, slice2 []string) []string {
	m := make(map[string]int)
	for _, v := range slice1 {
		m[v]++
	}

	for _, v := range slice2 {
		times, _ := m[v]
		if times == 0 {
			slice1 = append(slice1, v)
		}
	}
	return slice1
}

//求交集
func Intersect(slice1, slice2 []string) []string {
	m := make(map[string]int)
	nn := make([]string, 0)
	for _, v := range slice1 {
		m[v]++
	}

	for _, v := range slice2 {
		times, _ := m[v]
		if times == 1 {
			nn = append(nn, v)
		}
	}
	return nn
}

//求差集 slice1-并集
func Difference(slice1, slice2 []string) []string {
	m := make(map[string]int)
	nn := make([]string, 0)
	inter := Intersect(slice1, slice2)
	for _, v := range inter {
		m[v]++
	}

	for _, value := range slice1 {
		times, _ := m[value]
		if times == 0 {
			nn = append(nn, value)
		}
	}
	return nn
}

// 将给定的整数值转换成给定长度的字符串，不足长度的在前面补足0
func ConvInt2FormatString(input, ilen int)(retstring string){
	var igap int

	if len(string(input)) >= ilen {
		retstring = string(input)
	}else{
		igap = ilen - len(strconv.Itoa(input))
		retstring = strings.Repeat("0", igap) + strconv.Itoa(input)
	}
	return
}