package util

import "sync"

type SafeArray[T any] struct {
	mu   sync.Mutex
	list []T
}

// Push 一个元素
func (sa *SafeArray[T]) Push(v T) {
	sa.mu.Lock()
	defer sa.mu.Unlock()
	sa.list = append(sa.list, v)
}

// PushMany 多个元素
func (sa *SafeArray[T]) PushMany(vs []T) {
	sa.mu.Lock()
	defer sa.mu.Unlock()
	sa.list = append(sa.list, vs...)
}

// Pop 最后一个元素
func (sa *SafeArray[T]) Pop() (zero T, ok bool) {
	sa.mu.Lock()
	defer sa.mu.Unlock()
	if len(sa.list) == 0 {
		return zero, false
	}
	last := sa.list[len(sa.list)-1]
	sa.list = sa.list[:len(sa.list)-1]
	return last, true
}

// Flush 清空并返回所有元素
func (sa *SafeArray[T]) Flush() []T {
	sa.mu.Lock()
	defer sa.mu.Unlock()
	res := sa.list
	sa.list = make([]T, 0)
	return res
}

func (sa *SafeArray[T]) View() []T {
	sa.mu.Lock()
	defer sa.mu.Unlock()

	listCopy := make([]T, len(sa.list))
	copy(listCopy, sa.list)
	return listCopy
}

func (sa *SafeArray[T]) Iterate(fn func(T)) {
	sa.mu.Lock()
	defer sa.mu.Unlock()

	for _, item := range sa.list {
		fn(item)
	}
}

func (sa *SafeArray[T]) ForEach(fn func(T)) {
	sa.mu.Lock()
	listCopy := make([]T, len(sa.list))
	copy(listCopy, sa.list)
	sa.mu.Unlock()

	for _, item := range listCopy {
		fn(item)
	}
}
