package utility

import "fmt"

func Remove(sl []interface{}, f func(v1 interface{}) bool) []interface{} {
	for k, v := range sl {
		if f(v) {
			sl[k] = sl[len(sl)-1]
			sl = sl[:len(sl)-1]
			return sl
		}
	}
	return sl
}

func InSlice[K comparable](src []K, sub K) bool {
	for _, v := range src {
		if v == sub {
			return true
		}
	}
	return false
}

func RemoveSlice[K comparable](src []K, sub K) []K {
	for k, v := range src {
		if v == sub {
			copy(src[k:], src[k+1:])
			return src[:len(src)-1]
		}
	}
	return src
}

func RemoveSliceFast[K comparable](src []K, sub K) []K {
	for k, v := range src {
		if v == sub {
			src[k] = src[len(src)-1]
			return src[:len(src)-1]
		}
	}
	return src
}

func RemoveOneFromSlice[K any](src []K, cmp func(K) bool) []K {
	for k, v := range src {
		if cmp(v) {
			copy(src[k:], src[k+1:])
			return src[:len(src)-1]
		}
	}
	return src
}

// 切片相减
// [1,1,2,3] - [1,1,2,4] = [3]
func SubSlice[K comparable](src []K, sub []K) []K {

	// 组织MAP表
	subMap := make(map[K]int, len(sub))
	for _, v := range sub {
		subMap[v] += 1
	}
	remove := func(val K) bool {
		v, ok := subMap[val]
		if !ok {
			return false
		}

		if v > 1 {
			subMap[val] -= 1
		} else {
			delete(subMap, val)
		}
		return true
	}

	index := 0
	for _, v := range src {

		if remove(v) {
			continue
		}

		src[index] = v
		index += 1
	}
	src = src[:index]
	return src
}

// 切片比较
// [1,2,3] == [1,2,4] = -1
// [1,2,3] == [1,3,2] = 0
// [1,2,3] == [1,2,3] = 1
func CompareSlice[K comparable](p1 []K, p2 []K) int {
	// 长度不等直接-1
	if len(p1) != len(p2) {
		return -1
	}

	// 逐个比较每个相等则为1
	allEq := true
	for k, v := range p1 {
		if v != p2[k] {
			allEq = false
			break
		}
	}
	if allEq {
		return 1
	}

	// 个数统计，每个相等则为0
	p1Nums := make(map[K]int)
	for _, v := range p1 {
		p1Nums[v] += 1
	}
	p2Nums := make(map[K]int)
	for _, v := range p2 {
		p2Nums[v] += 1
	}
	if len(p1Nums) != len(p2Nums) {
		return -1
	}

	for k, v := range p1Nums {
		n := p2Nums[k]
		if n != v {
			return -1
		}
	}
	return 0
}

// k,v相等返回true；否则返回false
// [K comparable, V comparable]
func CompareMap[K comparable, V comparable](p1 map[K]V, p2 map[K]V) bool {
	//长度不等则为-1
	if len(p1) != len(p2) {
		return false
	}

	for k, v := range p1 {
		n, ok := p2[k]
		if !ok {
			return false
		}
		if n != v {
			return false
		}
	}
	return true
}

func TestSlice() {

	//[1,1,2,3] - [1,1,2,4] = [3]
	fmt.Println(SubSlice([]int{1, 1, 2, 3}, []int{1, 1, 2, 4}))

	fmt.Println(SubSlice([]int{1, 1, 2, 3}, []int{}))

	fmt.Println(SubSlice([]int{}, []int{1, 1, 2, 4}))

}
