package utils

import (
	"fmt"
	"reflect"
	"strings"
	"unsafe"
)

// string与slice互转,零copy省内存

// zero copy to change slice to string
func Slice2String(b []byte) (s string) {
	pBytes := (*reflect.SliceHeader)(unsafe.Pointer(&b))
	pString := (*reflect.StringHeader)(unsafe.Pointer(&s))
	pString.Data = pBytes.Data
	pString.Len = pBytes.Len
	return
}

// no copy to change string to slice
func StringToSlice(s string) (b []byte) {
	pBytes := (*reflect.SliceHeader)(unsafe.Pointer(&b))
	pString := (*reflect.StringHeader)(unsafe.Pointer(&s))
	pBytes.Data = pString.Data
	pBytes.Len = pString.Len
	pBytes.Cap = pString.Len
	return
}

// 任意slice合并
func SliceJoin(sep string, elems ...interface{}) string {
	l := len(elems)
	if l == 0 {
		return ""
	}
	if l == 1 {
		s := fmt.Sprint(elems[0])
		sLen := len(s) - 1
		if s[0] == '[' && s[sLen] == ']' {
			return strings.Replace(s[1:sLen], " ", sep, -1)
		}
		return s
	}
	sep = strings.Replace(fmt.Sprint(elems), " ", sep, -1)
	return sep[1 : len(sep)-1]
}

func DiffArray(a []string, b []string) []string {
	var diffArray []string
	temp := map[string]struct{}{}

	for _, val := range b {
		if _, ok := temp[val]; !ok {
			temp[val] = struct{}{}
		}
	}

	for _, val := range a {
		if _, ok := temp[val]; !ok {
			diffArray = append(diffArray, val)
		}
	}

	return diffArray
}