package sborepo

import "sync"

// PkgName is the package-name type used by repository and graph iterators.
type PkgName = string

// PkgFunc represents a function acting directly on a *Package.
type PkgFunc func(*Package)

// PkgIter iterates over *Package values and applies a PkgFunc to each of them.
type PkgIter func(PkgFunc)

// Parallel wraps `iter` so that it iterates concurrently.
func Parallel(iter PkgIter) PkgIter {
	return func(f PkgFunc) {
		var wg sync.WaitGroup
		iter(func(pkg *Package) {
			wg.Add(1)
			go func() { defer wg.Done(); f(pkg) }()
		})
		wg.Wait()
	}
}

// Names collects all names of the packages that iter iterates over into a slice.
func Names(iter PkgIter) (names []PkgName) {
	iter(func(pkg *Package) { names = append(names, pkg.Name) })
	return
}

func onPackage(iter func(func(*pkgNode))) PkgIter {
	return func(f PkgFunc) { iter(func(pkg *pkgNode) { f(pkg.Package) }) }
}
