package langext

import "sort"

func Sort[T OrderedConstraint](arr []T) {
	sort.Slice(arr, func(i1, i2 int) bool {
		return arr[i1] < arr[i2]
	})
}

func AsSorted[T OrderedConstraint](arr []T) []T {
	arr = ArrCopy(arr)
	sort.Slice(arr, func(i1, i2 int) bool {
		return arr[i1] < arr[i2]
	})
	return arr
}

func SortStable[T OrderedConstraint](arr []T) {
	sort.SliceStable(arr, func(i1, i2 int) bool {
		return arr[i1] < arr[i2]
	})
}

func AsSortedStable[T OrderedConstraint](arr []T) []T {
	arr = ArrCopy(arr)
	sort.SliceStable(arr, func(i1, i2 int) bool {
		return arr[i1] < arr[i2]
	})
	return arr
}

func IsSorted[T OrderedConstraint](arr []T) bool {
	return sort.SliceIsSorted(arr, func(i1, i2 int) bool {
		return arr[i1] < arr[i2]
	})
}

func SortSlice[T any](arr []T, less func(v1, v2 T) bool) {
	sort.Slice(arr, func(i1, i2 int) bool {
		return less(arr[i1], arr[i2])
	})
}

func AsSortedSlice[T any](arr []T, less func(v1, v2 T) bool) []T {
	arr = ArrCopy(arr)
	sort.Slice(arr, func(i1, i2 int) bool {
		return less(arr[i1], arr[i2])
	})
	return arr
}

func SortSliceStable[T any](arr []T, less func(v1, v2 T) bool) {
	sort.SliceStable(arr, func(i1, i2 int) bool {
		return less(arr[i1], arr[i2])
	})
}

func AsSortedSliceStable[T any](arr []T, less func(v1, v2 T) bool) []T {
	arr = ArrCopy(arr)
	sort.SliceStable(arr, func(i1, i2 int) bool {
		return less(arr[i1], arr[i2])
	})
	return arr
}

func IsSliceSorted[T any](arr []T, less func(v1, v2 T) bool) bool {
	return sort.SliceIsSorted(arr, func(i1, i2 int) bool {
		return less(arr[i1], arr[i2])
	})
}

func SortBy[TElem any, TSel OrderedConstraint](arr []TElem, selector func(v TElem) TSel) {
	sort.Slice(arr, func(i1, i2 int) bool {
		return selector(arr[i1]) < selector(arr[i2])
	})
}

func AsSortedBy[TElem any, TSel OrderedConstraint](arr []TElem, selector func(v TElem) TSel) []TElem {
	arr = ArrCopy(arr)
	sort.Slice(arr, func(i1, i2 int) bool {
		return selector(arr[i1]) < selector(arr[i2])
	})
	return arr
}

func SortByStable[TElem any, TSel OrderedConstraint](arr []TElem, selector func(v TElem) TSel) {
	sort.SliceStable(arr, func(i1, i2 int) bool {
		return selector(arr[i1]) < selector(arr[i2])
	})
}

func AsSortedByStable[TElem any, TSel OrderedConstraint](arr []TElem, selector func(v TElem) TSel) []TElem {
	arr = ArrCopy(arr)
	sort.SliceStable(arr, func(i1, i2 int) bool {
		return selector(arr[i1]) < selector(arr[i2])
	})
	return arr
}

func IsSortedBy[TElem any, TSel OrderedConstraint](arr []TElem, selector func(v TElem) TSel) {
	sort.SliceStable(arr, func(i1, i2 int) bool {
		return selector(arr[i1]) < selector(arr[i2])
	})
}