package util

import "sync"

type Concurrency struct {
	concurrentCt int
	ch           chan struct{}
	wg           sync.WaitGroup
}

func NewConcurency(ct int) *Concurrency {
	curr := Concurrency{concurrentCt: ct, ch: make(chan struct{}, ct)}

	for i := 0; i < curr.concurrentCt; i++ {
		curr.ch <- struct{}{}
	}

	return &curr
}

func (curr *Concurrency) Run(fn func()) {
	<-curr.ch
	curr.wg.Add(1)
	go func() {
		defer func() {
			curr.wg.Done()
			curr.ch <- struct{}{}
		}()

		fn()
	}()
}

func (curr *Concurrency) Wait() {
	curr.wg.Wait()
}
