internal static async Task <bool> ProcessUpdatedArtifacts(
            TenantInformation tenant,
            ArtifactsPublishedMessage message,
            IArtifactsPublishedRepository repository,
            IServiceLogRepository serviceLogRepository,
            IActionsParser actionsParser,
            IWorkflowMessagingProcessor messageProcessor)
        {
            var allUpdatedArtifacts = message?.Artifacts?.Where(p => !p.IsFirstTimePublished).ToList();

            if (allUpdatedArtifacts == null || allUpdatedArtifacts.Count <= 0)
            {
                Logger.Log("No updated artifacts found", message, tenant);
                return(false);
            }
            Logger.Log($"{allUpdatedArtifacts.Count} updated artifacts found", message, tenant);

            var updatedArtifacts = allUpdatedArtifacts.Where(a => a.ModifiedProperties?.Count > 0).ToList();

            if (updatedArtifacts.Count == 0)
            {
                Logger.Log("No modified properties found for updated artifacts", message, tenant);
                return(false);
            }

            // Get artifacts which have modified properties list populated
            var allArtifactsModifiedProperties = updatedArtifacts.ToDictionary(k => k.Id,
                                                                               v => v.ModifiedProperties ?? new List <PublishedPropertyInformation>());

            Logger.Log(
                $"{allArtifactsModifiedProperties.Count} artifacts found: {string.Join(", ", allArtifactsModifiedProperties.Select(k => k.Key))}",
                message, tenant, LogLevel.Debug);

            if (allArtifactsModifiedProperties.Count == 0)
            {
                return(false);
            }

            // Get property transitions for published artifact ids.
            var publishedArtifactIds   = updatedArtifacts.Select(a => a.Id).ToHashSet();
            var artifactPropertyEvents =
                await
                repository.GetWorkflowPropertyTransitionsForArtifactsAsync(message.UserId,
                                                                           message.RevisionId,
                                                                           (int)TransitionType.Property, publishedArtifactIds);

            // If no property transitions found, then call does not need to proceed
            Logger.Log($"{artifactPropertyEvents?.Count ?? 0} workflow property events found", message, tenant, LogLevel.Debug);
            if (artifactPropertyEvents == null || artifactPropertyEvents.Count == 0)
            {
                Logger.Log("No property change triggers found", message, tenant);
                return(false);
            }

            // Convert all property transitions to a dictionary with artifact id as key
            var activePropertyTransitions = new Dictionary <int, IList <SqlWorkflowEvent> >();
            var publishedArtifactEvents   = artifactPropertyEvents.Where(ape => publishedArtifactIds.Contains(ape.VersionItemId));

            // key = artifact id, value = all events
            foreach (var artifactPropertyEvent in publishedArtifactEvents)
            {
                if (activePropertyTransitions.ContainsKey(artifactPropertyEvent.VersionItemId))
                {
                    activePropertyTransitions[artifactPropertyEvent.VersionItemId].Add(artifactPropertyEvent);
                }
                else
                {
                    activePropertyTransitions.Add(artifactPropertyEvent.VersionItemId,
                                                  new List <SqlWorkflowEvent> {
                        artifactPropertyEvent
                    });
                }
            }

            var sqlWorkflowStates =
                await
                repository.GetWorkflowStatesForArtifactsAsync(message.UserId, activePropertyTransitions.Keys,
                                                              message.RevisionId);

            var workflowStates = sqlWorkflowStates.Where(w => w.WorkflowStateId > 0).ToDictionary(k => k.ArtifactId);

            Logger.Log(
                $"{workflowStates.Count} workflow states found for artifacts: {string.Join(", ", workflowStates.Select(k => k.Key))}",
                message, tenant, LogLevel.Debug);
            if (workflowStates.Count == 0)
            {
                return(false);
            }

            // Get project names
            var projectIds = updatedArtifacts.Select(a => a.ProjectId).ToList();
            var projects   = await repository.GetProjectNameByIdsAsync(projectIds);

            Logger.Log($"{projects.Count} project names found for project IDs: {string.Join(", ", projectIds)}", message, tenant,
                       LogLevel.Debug);

            var notificationMessages = new Dictionary <int, List <IWorkflowMessage> >();

            // For artifacts in active property transitions
            foreach (var artifactId in activePropertyTransitions.Keys)
            {
                Logger.Log($"Processing artifact with ID: {artifactId}", message, tenant, LogLevel.Debug);

                var artifactTransitionInfo = activePropertyTransitions[artifactId];
                var notifications          = actionsParser.GetNotificationActions(artifactTransitionInfo).ToList();
                Logger.Log($"{notifications.Count} Notification actions found", message, tenant, LogLevel.Debug);
                if (notifications.Count == 0)
                {
                    continue;
                }

                List <PublishedPropertyInformation> artifactModifiedProperties;
                if (!allArtifactsModifiedProperties.TryGetValue(artifactId, out artifactModifiedProperties))
                {
                    Logger.Log($"modified properties not found for {artifactId}", message, tenant, LogLevel.Debug);
                    continue;
                }

                Logger.Log($"{artifactModifiedProperties?.Count ?? 0} modified properties found", message, tenant,
                           LogLevel.Debug);
                if (artifactModifiedProperties == null || !artifactModifiedProperties.Any())
                {
                    continue;
                }

                SqlWorkFlowStateInformation currentStateInfo;
                if (!workflowStates.TryGetValue(artifactId, out currentStateInfo))
                {
                    continue;
                }

                var modifiedSystemPropertiesSet = artifactModifiedProperties.Where(a => a.PredefinedType == (int)PropertyTypePredefined.Name ||
                                                                                   a.PredefinedType == (int)PropertyTypePredefined.Description)
                                                  .Select(a => (PropertyTypePredefined)a.PredefinedType)
                                                  .ToHashSet();

                await ProcessSystemPropertyChange(tenant, message, repository, notifications, modifiedSystemPropertiesSet, currentStateInfo, updatedArtifacts, artifactId, workflowStates, projects, notificationMessages);

                var modifiedCustomPropertiesSet = artifactModifiedProperties.Where(a => a.PredefinedType == (int)PropertyTypePredefined.CustomGroup)
                                                  .Select(a => a.TypeId)
                                                  .ToHashSet();

                // Process custom properties
                Logger.Log(
                    $"{modifiedCustomPropertiesSet.Count} instance property type IDs being located: {string.Join(", ", modifiedCustomPropertiesSet)}",
                    message, tenant, LogLevel.Debug);

                await ProcessCustomPropertyChange(tenant, message, repository, notifications, modifiedCustomPropertiesSet, currentStateInfo, updatedArtifacts, artifactId, workflowStates, projects, notificationMessages);
            }

            if (notificationMessages.Count == 0)
            {
                Logger.Log("None of the modified properties have property change notification triggers", message, tenant);
                return(false);
            }
            Logger.Log($"Sending property change notifications for artifacts: {string.Join(", ", notificationMessages.Select(kvp => kvp.Key))}", message, tenant);

            foreach (var notificationMessage in notificationMessages)
            {
                await WorkflowEventsMessagesHelper.ProcessMessages(LogSource,
                                                                   tenant,
                                                                   serviceLogRepository,
                                                                   notificationMessage.Value,
                                                                   $"Error on new artifact creation with Id: {notificationMessage.Key}",
                                                                   messageProcessor);
            }

            return(true);
        }
 public ArtifactsPublishedActionHelper(IActionsParser actionsParser = null)
 {
     _actionsParser = actionsParser ?? new ActionsParser();
 }