package yu_sync

import "sync"

type Map[K comparable, V any] struct {
	lock sync.Mutex
	hash map[K]V
}

func (t *Map[K, V]) Set(key K, val V) {
	t.lock.Lock()
	defer t.lock.Unlock()
	if t.hash == nil {
		t.hash = make(map[K]V)
	}
	t.hash[key] = val
}

func (t *Map[K, V]) Get(key K) (val V, ok bool) {
	t.lock.Lock()
	defer t.lock.Unlock()
	if t.hash == nil {
		return
	}
	val, ok = t.hash[key]
	return
}

func (t *Map[K, V]) GetDelete(key K) (val V, ok bool) {
	t.lock.Lock()
	defer t.lock.Unlock()
	if t.hash == nil {
		return
	}
	if val, ok = t.hash[key]; ok {
		delete(t.hash, key)
	}
	return
}

func (t *Map[K, V]) For(on func(K, V)) {
	if on == nil {
		return
	}
	t.lock.Lock()
	defer t.lock.Unlock()
	for j_k, j_v := range t.hash {
		on(j_k, j_v)
	}
	return
}

func (t *Map[K, V]) ForDelete(on func(K, V)) {
	if on == nil {
		return
	}
	t.lock.Lock()
	defer t.lock.Unlock()
	for j_k, j_v := range t.hash {
		on(j_k, j_v)
		delete(t.hash, j_k)
	}
	return
}

func (t *Map[K, V]) Delete(key K) (ok bool) {
	t.lock.Lock()
	defer t.lock.Unlock()
	if t.hash == nil {
		return
	}
	_, ok = t.hash[key]
	delete(t.hash, key)
	return
}

func (t *Map[K, V]) Clear() {
	t.lock.Lock()
	defer t.lock.Unlock()
	t.hash = make(map[K]V)
	return
}
