package carapace

import 

type (
	batch        []Action
	invokedBatch []InvokedAction
)

// Batch creates a batch of Actions that can be invoked in parallel.
func ( ...Action) batch {
	return batch()
}

// Invoke invokes contained Actions of the batch using goroutines.
func ( batch) ( Context) invokedBatch {
	 := make([]InvokedAction, len())
	 := make([]func(), len())

	for ,  := range  {
		 := 
		 := 
		[] = func() {
			[] = .Invoke()
		}
	}
	parallelize(...)
	return 
}

// ToA converts the batch to an implicitly merged action which is a shortcut for:
//
//	ActionCallback(func(c Context) Action {
//		return batch.Invoke(c).Merge().ToA()
//	})
func ( batch) () Action {
	return ActionCallback(func( Context) Action {
		return .Invoke().Merge().ToA()
	})
}

// Merge merges Actions of a batch.
func ( invokedBatch) () InvokedAction {
	switch len() {
	case 0:
		return ActionValues().Invoke(Context{})
	case 1:
		return [0]
	default:
		return [0].Merge([1:]...)
	}
}

// Parallelize parallelizes the function calls (https://stackoverflow.com/a/44402936)
func parallelize( ...func()) {
	var  sync.WaitGroup
	.Add(len())

	defer .Wait()

	for ,  := range  {
		go func( func()) {
			defer .Done()
			()
		}()
	}
}