// package wgname -- ожидатель группы по имени для завершения
package wgname

import (
	"fmt"
	"sync"

	"wartank/pkg/components/safebool"
)

// WgName -- ожидатель группы завершения
type WgName struct {
	dictName map[string]bool    // Словарь имён потоков
	chEnd    chan int           // Канал сигнала закрытия ожидания
	isWork   *safebool.SafeBool // Признак работы ожидания
	block    sync.RWMutex
}

// NewWgName -- возвращает новый ожидатель группы
func NewWgName() *WgName {
	sf := &WgName{
		dictName: make(map[string]bool),
		chEnd:    make(chan int, 1),
		isWork:   safebool.NewSafeBool(),
	}
	sf.isWork.Set()
	return sf
}

// Add -- добавляет имя в группу ожидания
func (sf *WgName) Add(name string) error {
	sf.block.Lock()
	defer sf.block.Unlock()
	_, isOk := sf.dictName[name]
	if isOk {
		return fmt.Errorf("WgName.Add(): name %q already exists", name)
	}
	sf.dictName[name] = true
	return nil
}

// Done -- отмечает словарь ожидания готовности потока
func (sf *WgName) Done(name string) error {
	sf.block.Lock()
	defer sf.block.Unlock()
	_, isOk := sf.dictName[name]
	if !isOk {
		return fmt.Errorf("WgName.Done(): name %q not exists", name)
	}
	delete(sf.dictName, name)
	if !sf.isWork.Get() {
		return nil
	}
	if len(sf.dictName) == 0 {
		sf.isWork.Reset()
		close(sf.chEnd)
	}
	return nil
}

// Wait -- ожидание закрытия группы
func (sf *WgName) Wait() {
	<-sf.chEnd
}
