package supervisor

import (
	
	

	
)

// Group manages a collection of [process.Runner] instances that run
// concurrently in the background and can be stopped together.
//
// Use Go method to add runners, Interrupt to signal them to shutdown gracefully,
// and Wait to wait for them to complete.
type Group struct {
	mu   sync.Mutex
	ctx  context.Context
	done chan struct{}
	wg   sync.WaitGroup
}

// NewGroup returns a new [Group] instance that runs processes in the background
// under the given context.
func ( context.Context) *Group {
	return &Group{ctx: }
}

// GroupBuilder is a [BuilderFunc] function for the [Group] type.
func ( context.Context) (*Group, error) {
	return NewGroup(), nil
}

// Run implements the [process.Runner] interface. It runs the callback, then
// interrupts all runners in the group and waits for them to complete.
func ( *Group) ( context.Context,  process.Callback) error {
	defer .Wait()
	defer .Interrupt()
	return ()
}

// Interrupt signals all runners started before the next [Group.Wait] call to
// stop.
func ( *Group) () {
	.mu.Lock()
	defer .mu.Unlock()

	select {
	case <-.done:
		return
	default:
	}

	if .done == nil {
		.done = make(chan struct{})
	}
	close(.done)
}

// Wait blocks until all currently running processes exit.
func ( *Group) () {
	.wg.Wait()
	.mu.Lock()
	.done = nil
	.mu.Unlock()
}

// Go starts a runner in the background, calling atExit when it finishes.
func ( *Group) ( process.Runner,  func(error)) {
	.mu.Lock()
	if .done == nil {
		.done = make(chan struct{})
	}
	 := .done
	.mu.Unlock()

	 := .ctx
	if  == nil {
		 = context.Background()
	}

	if  == nil {
		 = func( error) {}
	}

	.wg.Go(func() {
		(.Run(, func( context.Context) error {
			select {
			case <-.Done():
			case <-:
			}
			return nil
		}))
	})
}