package infrastructure

import (
	"context"

	"code.justin.tv/eventbus/controlplane/infrastructure/notification"
	"code.justin.tv/eventbus/controlplane/infrastructure/validation"
	"go.uber.org/multierr"
)

//nolint:golint
func Validate(ctx context.Context, gracefulStopCtx context.Context, items []validation.Item, channels []notification.Channel) error {

	// This for+select checks if a graceful shutdown has been invoked. If so, the current
	// item finishes validating, then the entire for-loop is exited. This function will then
	// immediately continue to submitting the so-far-collected reports to the notification channels
	// as part of the graceful shutdown procedure.

validations:
	for _, item := range items {
		select {
		case <-gracefulStopCtx.Done():
			break validations
		default:
			report, err := item.Validate(ctx)
			if err != nil {
				report = validation.ValidationError(item, err.Error())
			}
			for _, channel := range channels {
				channel.Add(report)
			}
		}

	}

	var notificationErrors error
	for _, channel := range channels {
		notificationErrors = multierr.Append(notificationErrors, channel.Submit(ctx))
	}
	return notificationErrors
}
