<commit_before>﻿// ==========================================================================
//  Squidex Headless CMS
// ==========================================================================
//  Copyright (c) Squidex UG (haftungsbeschraenkt)
//  All rights reserved. Licensed under the MIT license.
// ==========================================================================

using System;
using System.Collections.Concurrent;
using System.Threading.Tasks;
using Algolia.Search;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using Squidex.Domain.Apps.Core.Rules;
using Squidex.Domain.Apps.Core.Rules.Actions;
using Squidex.Domain.Apps.Events;
using Squidex.Domain.Apps.Events.Contents;
using Squidex.Infrastructure;
using Squidex.Infrastructure.EventSourcing;

namespace Squidex.Domain.Apps.Core.HandleRules.Actions
{
    public sealed class AlgoliaActionHandler : RuleActionHandler<AlgoliaAction>
    {
        private readonly ConcurrentDictionary<(string AppId, string ApiKey, string IndexName), Index> clients = new ConcurrentDictionary<(string AppId, string ApiKey, string IndexName), Index>();
        private readonly JsonSerializer serializer;

        public AlgoliaActionHandler(JsonSerializer serializer)
        {
            Guard.NotNull(serializer, nameof(serializer));

            this.serializer = serializer;
        }

        protected override (string Description, RuleJobData Data) CreateJob(Envelope<AppEvent> @event, string eventName, AlgoliaAction action)
        {
            var ruleDescription = string.Empty;
            var ruleData = new RuleJobData
            {
                ["AppId"] = action.AppId,
                ["ApiKey"] = action.ApiKey,
                ["IndexName"] = action.IndexName
            };

            if (@event.Payload is ContentEvent contentEvent)
            {
                ruleData["ContentId"] = contentEvent.ContentId.ToString();
                ruleData["Operation"] = "Upsert";

                switch (@event.Payload)
                {
                    case ContentCreated created:
                    {
                        ruleDescription = $"Add entry to Algolia index: {action.IndexName}";
                        ruleData["Content"] = new JObject(
                            new JProperty("data", JObject.FromObject(created.Data, serializer)));
                        break;
                    }

                    case ContentUpdated updated:
                    {
                        ruleDescription = $"Update entry in Algolia index: {action.IndexName}";
                        ruleData["Content"] = new JObject(
                            new JProperty("data", JObject.FromObject(updated.Data, serializer)));
                        break;
                    }

                    case ContentStatusChanged statusChanged:
                    {
                        ruleDescription = $"Update entry in Algolia index: {action.IndexName}";
                        ruleData["Content"] = new JObject(
                            new JProperty("status", statusChanged.Status.ToString()));
                        break;
                    }

                    case ContentDeleted deleted:
                    {
                        ruleDescription = $"Delete entry from Index: {action.IndexName}";
                        ruleData["Content"] = new JObject();
                        break;
                    }
                }
            }

            return (ruleDescription, ruleData);
        }

        public override async Task<(string Dump, Exception Exception)> ExecuteJobAsync(RuleJobData job)
        {
            var appId = job["AppId"].Value<string>();<commit_msg>Ensure that we have all properties.<commit_after>﻿// ==========================================================================
//  Squidex Headless CMS
// ==========================================================================
//  Copyright (c) Squidex UG (haftungsbeschraenkt)
//  All rights reserved. Licensed under the MIT license.
// ==========================================================================

using System;
using System.Collections.Concurrent;
using System.Threading.Tasks;
using Algolia.Search;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using Squidex.Domain.Apps.Core.Rules;
using Squidex.Domain.Apps.Core.Rules.Actions;
using Squidex.Domain.Apps.Events;
using Squidex.Domain.Apps.Events.Contents;
using Squidex.Infrastructure;
using Squidex.Infrastructure.EventSourcing;

namespace Squidex.Domain.Apps.Core.HandleRules.Actions
{
    public sealed class AlgoliaActionHandler : RuleActionHandler<AlgoliaAction>
    {
        private readonly ConcurrentDictionary<(string AppId, string ApiKey, string IndexName), Index> clients = new ConcurrentDictionary<(string AppId, string ApiKey, string IndexName), Index>();
        private readonly JsonSerializer serializer;

        public AlgoliaActionHandler(JsonSerializer serializer)
        {
            Guard.NotNull(serializer, nameof(serializer));

            this.serializer = serializer;
        }

        protected override (string Description, RuleJobData Data) CreateJob(Envelope<AppEvent> @event, string eventName, AlgoliaAction action)
        {
            var ruleDescription = string.Empty;
            var ruleData = new RuleJobData
            {
                ["AppId"] = action.AppId,
                ["ApiKey"] = action.ApiKey,
                ["IndexName"] = action.IndexName
            };

            if (@event.Payload is ContentEvent contentEvent)
            {
                ruleData["ContentId"] = contentEvent.ContentId.ToString();
                ruleData["Operation"] = "Upsert";

                var timestamp = @event.Headers.Timestamp().ToString();

                switch (@event.Payload)
                {
                    case ContentCreated created:
                    {
                        ruleDescription = $"Add entry to Algolia index: {action.IndexName}";
                        ruleData["Content"] = new JObject(
                            new JProperty("id", contentEvent.ContentId),
                            new JProperty("created", timestamp),
                            new JProperty("createdBy", created.Actor.ToString()),
                            new JProperty("lastModified", timestamp),
                            new JProperty("lastModifiedBy", created.Actor.ToString()),
                            new JProperty("data", JObject.FromObject(created.Data, serializer)));
                        break;
                    }

                    case ContentUpdated updated:
                    {
                        ruleDescription = $"Update entry in Algolia index: {action.IndexName}";
                        ruleData["Content"] = new JObject(
                            new JProperty("lastModified", timestamp),
                            new JProperty("lastModifiedBy", updated.Actor.ToString()),
                            new JProperty("data", JObject.FromObject(updated.Data, serializer)));
                        break;
                    }

                    case ContentStatusChanged statusChanged:
                    {
                        ruleDescription = $"Update entry in Algolia index: {action.IndexName}";
                        ruleData["Content"] = new JObject(
                            new JProperty("status", statusChanged.Status.ToString()));
                        break;
                    }

                    case ContentDeleted deleted:
                    {
                        ruleDescription = $"Delete entry from Index: {action.IndexName}";
                        ruleData["Content"] = new JObject();
                        break;
                    }
                }
            }

            return (ruleDescription, ruleData);
        }

        public override async Task<(string Dump, Exception Exception)> ExecuteJobAsync(RuleJobData job)
        {
            var appId = job["AppId"].Value<string>();
{'fraction_non_alphanumeric': 0.14057826520438685, 'fraction_numerical': 0.0, 'mean_word_length': 1.8447359092520383, 'pattern_counts': {'":': 0, '<': 15, '<?xml version=': 0, '>': 15, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '143619', 'n_tokens_mistral': 1887, 'n_tokens_neox': 1761, 'n_words': 416}