package signal

import (
	"context"
)

func executeAndFulfill(f func() error, done chan<- error) {
	err := f()
	if err != nil {
		done <- err
	}
	close(done)
}

// ExecuteAsync executes a function asynchronously and return its result.
func ExecuteAsync(f func() error) <-chan error {
	done := make(chan error, 1)
	go executeAndFulfill(f, done)
	return done
}

func ErrorOrFinish1(ctx context.Context, c <-chan error) error {
	select {
	case <-ctx.Done():
		return ctx.Err()
	case err := <-c:
		return err
	}
}

func ErrorOrFinish2(ctx context.Context, c1, c2 <-chan error) error {
	select {
	case <-ctx.Done():
		return ctx.Err()
	case err := <-c1:
		if err != nil {
			return err
		}
		return ErrorOrFinish1(ctx, c2)
	case err := <-c2:
		if err != nil {
			return err
		}
		return ErrorOrFinish1(ctx, c1)
	}
}