/// <summary>
        /// Sends triggers to the Azure send function.
        /// It uses Fan-out / Fan-in pattern to send batch triggers in parallel to the Azure send function.
        /// </summary>
        /// <param name="context">Orchestration context.</param>
        /// <param name="notificationDataEntityId">Notification data entity ID.</param>
        /// <param name="recipientDataListInformation">The information about the recipient data list.</param>
        /// <param name="log">The logging service.</param>
        /// <returns>A <see cref="Task"/> representing the asynchronous operation.</returns>
        private async Task SendTriggersToSendFunctionAsync(
            IDurableOrchestrationContext context,
            string notificationDataEntityId,
            RecipientDataListInformation recipientDataListInformation,
            ILogger log)
        {
            var numberOfRecipientDataBatches = recipientDataListInformation.NumberOfRecipientDataBatches;

            var tasks = new List <Task>();

            for (var batchIndex = 1; batchIndex <= numberOfRecipientDataBatches; batchIndex++)
            {
                if (!context.IsReplaying)
                {
                    log.LogInformation($"Processing batch {batchIndex} / {numberOfRecipientDataBatches}");
                }

                var task = this.sendTriggersToSendFunctionActivity.RunAsync(
                    context,
                    notificationDataEntityId,
                    batchIndex);

                tasks.Add(task);
            }

            await Task.WhenAll(tasks);
        }
        /// <summary>
        /// It uses the incoming request to determine which type of recipient list to fetch
        /// and initialize.
        /// It triggers the correct functions in order to fetch the recipient
        /// list and fill the corresponding sent notification data table/partition with
        /// unknown/initial statuses.
        /// It then breaks all those recipients down into batches and loads them into
        /// the send batches data table to be added to the send queue.
        /// </summary>
        /// <param name="context">Orchestration context.</param>
        /// <param name="notificationDataEntity">A notification data entity.</param>
        /// <param name="log">The logging service.</param>
        /// <returns>A <see cref="Task"/> representing the asynchronous operation.</returns>
        private async Task <RecipientDataListInformation> GetRecipientDataBatchesAsync(
            IDurableOrchestrationContext context,
            NotificationDataEntity notificationDataEntity,
            ILogger log)
        {
            var recipientTypeForLogging      = string.Empty;
            var recipientDataListInformation = new RecipientDataListInformation();

            if (notificationDataEntity.AllUsers)
            {
                recipientTypeForLogging = "All users";
                var userDataEntities = await this.getAllUsersDataEntitiesActivity.RunAsync(context, notificationDataEntity.Id);

                recipientDataListInformation = await this.getRecipientDataListForAllUsersActivity.RunAsync(context, userDataEntities, notificationDataEntity);
            }
            else if (notificationDataEntity.Rosters.Any())
            {
                recipientTypeForLogging = "Rosters";
                await this.GetRecipientDataListForRostersAsync(context, notificationDataEntity, log);

                recipientDataListInformation = await this.processRecipientDataListActivity.RunAsync(context, notificationDataEntity.Id);
            }
            else if (notificationDataEntity.Groups.Count() != 0)
            {
                recipientTypeForLogging = "Groups";
                await this.GetRecipientDataListForGroupsAsync(context, notificationDataEntity, log);

                recipientDataListInformation = await this.processRecipientDataListActivity.RunAsync(context, notificationDataEntity.Id);
            }
            else if (notificationDataEntity.Teams.Any())
            {
                recipientTypeForLogging = "General channels";
                var teamDataEntities = await this.getTeamDataEntitiesByIdsActivity.RunAsync(context, notificationDataEntity.Id, notificationDataEntity.Teams);

                recipientDataListInformation = await this.getRecipientDataListForTeamsActivity.RunAsync(context, teamDataEntities, notificationDataEntity);
            }
            else
            {
                recipientTypeForLogging = "No recipient type was defined";
                this.Log(context, log, notificationDataEntity.Id, recipientTypeForLogging, recipientDataListInformation);

                throw new ArgumentException($"No valid audience selected for the notification, Id: {notificationDataEntity.Id}");
            }

            this.Log(context, log, notificationDataEntity.Id, recipientTypeForLogging, recipientDataListInformation);

            return(recipientDataListInformation);
        }
        /// <summary>
        /// Log information if the context is not replaying.
        /// </summary>
        /// <param name="context">Orchestration context.</param>
        /// <param name="log">The logging service.</param>
        /// <param name="notificationDataEntityId">A notification data entity's ID.</param>
        /// <param name="recipientType">The recipient type.</param>
        /// <param name="recipientDataListInformation">The information for the recipient data list.</param>
        private void Log(
            IDurableOrchestrationContext context,
            ILogger log,
            string notificationDataEntityId,
            string recipientType,
            RecipientDataListInformation recipientDataListInformation)
        {
            if (context.IsReplaying)
            {
                return;
            }

            var numberOfRecipients       = recipientDataListInformation.TotalNumberOfRecipients;
            var numberOfRecipientBatches = recipientDataListInformation.NumberOfRecipientDataBatches;

            var message = $"Notification id:{notificationDataEntityId}. Recipient option: {recipientType}. Number of recipients: {numberOfRecipients}. Number of recipient data batches: {numberOfRecipientBatches}.";

            log.LogInformation(message);
        }